1- import { existsSync , readFileSync , statSync } from 'fs' ;
1+ import { execSync } from 'child_process' ;
2+ import { existsSync , readFileSync } from 'fs' ;
23import { join } from 'path' ;
34import { describe , expect , it } from 'vitest' ;
45
56const DIST_DIR = join ( process . cwd ( ) , 'dist' ) ;
6- const TYPES_DIR = join ( DIST_DIR , 'types' ) ;
7- const LIB_DIR = join ( DIST_DIR , 'lib' ) ;
87
98describe ( 'Build Artifacts' , ( ) => {
109 describe ( 'TypeScript Declarations' , ( ) => {
1110 it ( 'should generate main index.d.ts file' , ( ) => {
12- const indexDtsPath = join ( TYPES_DIR , 'index.d.ts' ) ;
11+ const indexDtsPath = join ( DIST_DIR , 'index.d.ts' ) ;
1312 expect ( existsSync ( indexDtsPath ) , `Expected ${ indexDtsPath } to exist` ) . toBe ( true ) ;
1413
1514 const content = readFileSync ( indexDtsPath , 'utf-8' ) ;
16- expect ( content ) . toContain ( 'export declare function search' ) ;
17- expect ( content ) . toContain ( 'export declare function compile' ) ;
18- expect ( content ) . toContain ( 'export declare const registerFunction' ) ;
15+ expect ( content ) . toContain ( 'declare function search' ) ;
16+ expect ( content ) . toContain ( 'declare function compile' ) ;
17+ expect ( content ) . toContain ( 'declare const registerFunction' ) ;
1918 } ) ;
2019
21- it ( 'should generate all required type declaration files' , ( ) => {
22- const requiredFiles = [
23- 'AST.type.d.ts' ,
24- 'JSON.type.d.ts' ,
25- 'Lexer.d.ts' ,
26- 'Lexer.type.d.ts' ,
27- 'Parser.d.ts' ,
28- 'Parser.type.d.ts' ,
29- 'Runtime.d.ts' ,
30- 'Scope.d.ts' ,
31- 'TreeInterpreter.d.ts' ,
32- 'utils/index.d.ts' ,
33- 'utils/strings.d.ts' ,
34- 'utils/text.d.ts' ,
35- ] ;
36-
37- for ( const file of requiredFiles ) {
38- const filePath = join ( TYPES_DIR , file ) ;
39- expect ( existsSync ( filePath ) , `Expected ${ filePath } to exist` ) . toBe ( true ) ;
40- }
20+ it ( 'should generate CLI type declarations' , ( ) => {
21+ const cliDtsPath = join ( DIST_DIR , 'cli.d.ts' ) ;
22+ expect ( existsSync ( cliDtsPath ) , `Expected ${ cliDtsPath } to exist` ) . toBe ( true ) ;
4123 } ) ;
4224
4325 it ( 'should export all main types and functions' , ( ) => {
44- const indexDtsPath = join ( TYPES_DIR , 'index.d.ts' ) ;
26+ const indexDtsPath = join ( DIST_DIR , 'index.d.ts' ) ;
4527 const content = readFileSync ( indexDtsPath , 'utf-8' ) ;
4628
4729 // Check for main function exports
48- expect ( content ) . toContain ( 'export declare function search' ) ;
49- expect ( content ) . toContain ( 'export declare function compile' ) ;
50- expect ( content ) . toContain ( 'export declare function tokenize' ) ;
30+ expect ( content ) . toContain ( 'declare function search' ) ;
31+ expect ( content ) . toContain ( 'declare function compile' ) ;
32+ expect ( content ) . toContain ( 'declare function tokenize' ) ;
5133
5234 // Check for type exports
53- expect ( content ) . toContain ( 'export type { JSONArray, JSONObject, JSONPrimitive, JSONValue }' ) ;
54- expect ( content ) . toContain ( 'export type { Options }' ) ;
55- expect ( content ) . toContain ( 'export type { BuiltInFunctionNames' ) ;
35+ expect ( content ) . toContain ( 'type JSONArray' ) ;
36+ expect ( content ) . toContain ( 'type JSONObject' ) ;
37+ expect ( content ) . toContain ( 'type JSONPrimitive' ) ;
38+ expect ( content ) . toContain ( 'type JSONValue' ) ;
5639
5740 // Check for constant exports
58- expect ( content ) . toContain ( 'export declare const TYPE_ANY' ) ;
59- expect ( content ) . toContain ( 'export declare const TYPE_STRING' ) ;
60- expect ( content ) . toContain ( 'export declare const TYPE_NUMBER' ) ;
41+ expect ( content ) . toContain ( 'declare const TYPE_ANY' ) ;
42+ expect ( content ) . toContain ( 'declare const TYPE_STRING' ) ;
43+ expect ( content ) . toContain ( 'declare const TYPE_NUMBER' ) ;
6144 } ) ;
6245 } ) ;
6346
64- describe ( 'UMD and ESM Bundles' , ( ) => {
65- it ( 'should generate UMD bundle' , ( ) => {
66- const umdPath = join ( DIST_DIR , 'jmespath.umd.js ' ) ;
67- expect ( existsSync ( umdPath ) , `Expected ${ umdPath } to exist` ) . toBe ( true ) ;
47+ describe ( 'Modern Dual Format Bundles' , ( ) => {
48+ it ( 'should generate CommonJS bundle' , ( ) => {
49+ const cjsPath = join ( DIST_DIR , 'index.cjs ' ) ;
50+ expect ( existsSync ( cjsPath ) , `Expected ${ cjsPath } to exist` ) . toBe ( true ) ;
6851
69- const content = readFileSync ( umdPath , 'utf-8' ) ;
70- expect ( content ) . toContain ( '(function (global, factory)' ) ;
71- } ) ;
72-
73- it ( 'should generate minified UMD bundle' , ( ) => {
74- const umdMinPath = join ( DIST_DIR , 'jmespath.umd.min.js' ) ;
75- expect ( existsSync ( umdMinPath ) , `Expected ${ umdMinPath } to exist` ) . toBe ( true ) ;
76-
77- const stat = statSync ( umdMinPath ) ;
78- expect ( stat . size ) . toBeGreaterThan ( 0 ) ;
52+ const content = readFileSync ( cjsPath , 'utf-8' ) ;
53+ expect ( content ) . toContain ( 'exports' ) ;
7954 } ) ;
8055
8156 it ( 'should generate ESM bundle' , ( ) => {
82- const esmPath = join ( DIST_DIR , 'jmespath.esm.js ' ) ;
57+ const esmPath = join ( DIST_DIR , 'index.mjs ' ) ;
8358 expect ( existsSync ( esmPath ) , `Expected ${ esmPath } to exist` ) . toBe ( true ) ;
8459
8560 const content = readFileSync ( esmPath , 'utf-8' ) ;
86- expect ( content ) . toContain ( 'export { ' ) ;
61+ expect ( content ) . toContain ( 'export' ) ;
8762 } ) ;
8863
89- it ( 'should generate minified ESM bundle ' , ( ) => {
90- const esmMinPath = join ( DIST_DIR , 'jmespath.esm.min.js ' ) ;
91- expect ( existsSync ( esmMinPath ) , `Expected ${ esmMinPath } to exist` ) . toBe ( true ) ;
64+ it ( 'should generate source maps ' , ( ) => {
65+ const cjsMapPath = join ( DIST_DIR , 'index.cjs.map ' ) ;
66+ const esmMapPath = join ( DIST_DIR , 'index.mjs.map' ) ;
9267
93- const stat = statSync ( esmMinPath ) ;
94- expect ( stat . size ) . toBeGreaterThan ( 0 ) ;
68+ expect ( existsSync ( cjsMapPath ) , `Expected ${ cjsMapPath } to exist` ) . toBe ( true ) ;
69+ expect ( existsSync ( esmMapPath ) , `Expected ${ esmMapPath } to exist` ) . toBe ( true ) ;
9570 } ) ;
9671 } ) ;
9772
9873 describe ( 'CLI Binary' , ( ) => {
99- it ( 'should generate CLI binary' , ( ) => {
100- const binPath = join ( LIB_DIR , 'bin' , 'jp.js ') ;
74+ it ( 'should generate CLI binary (ESM only) ' , ( ) => {
75+ const binPath = join ( DIST_DIR , 'cli.mjs ' ) ;
10176 expect ( existsSync ( binPath ) , `Expected ${ binPath } to exist` ) . toBe ( true ) ;
10277
10378 const content = readFileSync ( binPath , 'utf-8' ) ;
104- expect ( content ) . toContain ( '#! /usr/bin/env node' ) ;
79+ expect ( content ) . toContain ( '#!/usr/bin/env node' ) ;
10580 } ) ;
10681
10782 it ( 'should generate source maps for CLI binary' , ( ) => {
108- const mapPath = join ( LIB_DIR , 'bin' , 'jp.js.map' ) ;
109- expect ( existsSync ( mapPath ) , `Expected ${ mapPath } to exist` ) . toBe ( true ) ;
83+ const mjsMapPath = join ( DIST_DIR , 'cli.mjs.map' ) ;
84+ expect ( existsSync ( mjsMapPath ) , `Expected ${ mjsMapPath } to exist` ) . toBe ( true ) ;
85+ } ) ;
86+
87+ it ( 'should have functional CLI that can execute JMESPath queries' , ( ) => {
88+ const binPath = join ( DIST_DIR , 'cli.mjs' ) ;
89+ const testData = '{"foo": {"bar": "baz"}}' ;
90+ const query = 'foo.bar' ;
91+
92+ // Test basic functionality
93+ const result = execSync ( `echo '${ testData } ' | node ${ binPath } '${ query } '` , {
94+ encoding : 'utf-8' ,
95+ cwd : process . cwd ( ) ,
96+ } ) ;
97+
98+ expect ( result . trim ( ) ) . toBe ( '"baz"' ) ;
99+ } ) ;
100+
101+ it ( 'should show help when --help flag is used' , ( ) => {
102+ const binPath = join ( DIST_DIR , 'cli.mjs' ) ;
103+
104+ const result = execSync ( `node ${ binPath } --help` , {
105+ encoding : 'utf-8' ,
106+ cwd : process . cwd ( ) ,
107+ } ) ;
108+
109+ expect ( result ) . toContain ( 'NAME:' ) ;
110+ expect ( result ) . toContain ( 'jp - jp [<options>] <expression>' ) ;
111+ expect ( result ) . toContain ( 'OPTIONS:' ) ;
110112 } ) ;
111113 } ) ;
112114
@@ -115,17 +117,17 @@ describe('Build Artifacts', () => {
115117 const pkgPath = join ( process . cwd ( ) , 'package.json' ) ;
116118 const pkg = JSON . parse ( readFileSync ( pkgPath , 'utf-8' ) ) ;
117119
118- expect ( pkg . main ) . toBe ( 'dist/jmespath.umd.js ' ) ;
119- expect ( pkg . module ) . toBe ( 'dist/jmespath.esm.js ' ) ;
120- expect ( pkg . types ) . toBe ( 'dist/types /index.d.ts' ) ;
121- expect ( pkg . typings ) . toBe ( 'dist/types/index.d.ts ' ) ;
120+ expect ( pkg . main ) . toBe ( './ dist/index.cjs ' ) ;
121+ expect ( pkg . module ) . toBe ( './ dist/index.mjs ' ) ;
122+ expect ( pkg . types ) . toBe ( './dist /index.d.ts' ) ;
123+ expect ( pkg . type ) . toBe ( 'module ' ) ;
122124 } ) ;
123125
124126 it ( 'should have correct bin configuration' , ( ) => {
125127 const pkgPath = join ( process . cwd ( ) , 'package.json' ) ;
126128 const pkg = JSON . parse ( readFileSync ( pkgPath , 'utf-8' ) ) ;
127129
128- expect ( pkg . bin ) . toEqual ( { jp : 'dist/lib/bin/jp.js ' } ) ;
130+ expect ( pkg . bin ) . toEqual ( { jp : './ dist/cli.mjs ' } ) ;
129131 } ) ;
130132
131133 it ( 'should include dist directory in files' , ( ) => {
@@ -141,9 +143,15 @@ describe('Build Artifacts', () => {
141143
142144 expect ( pkg . exports ) . toBeDefined ( ) ;
143145 expect ( pkg . exports [ '.' ] ) . toBeDefined ( ) ;
144- expect ( pkg . exports [ '.' ] . types ) . toBe ( './dist/types/index.d.ts' ) ;
145- expect ( pkg . exports [ '.' ] . import ) . toBe ( './dist/jmespath.esm.js' ) ;
146- expect ( pkg . exports [ '.' ] . require ) . toBe ( './dist/jmespath.umd.js' ) ;
146+ expect ( pkg . exports [ '.' ] . types ) . toBe ( './dist/index.d.ts' ) ;
147+ expect ( pkg . exports [ '.' ] . import ) . toBe ( './dist/index.mjs' ) ;
148+ expect ( pkg . exports [ '.' ] . require ) . toBe ( './dist/index.cjs' ) ;
149+
150+ // Check CLI export
151+ expect ( pkg . exports [ './cli' ] ) . toBeDefined ( ) ;
152+ expect ( pkg . exports [ './cli' ] . types ) . toBe ( './dist/cli.d.ts' ) ;
153+ expect ( pkg . exports [ './cli' ] . import ) . toBe ( './dist/cli.mjs' ) ;
154+ expect ( pkg . exports [ './cli' ] . require ) . toBe ( './dist/cli.cjs' ) ;
147155 } ) ;
148156 } ) ;
149157} ) ;
0 commit comments