@@ -56,14 +56,26 @@ describe('Positional arguments passed as named options', () => {
5656 c . arguments ( z . object ( { pos1 : z . string ( ) , pos2 : z . string ( ) } ) , { positional : [ 'pos1' , 'pos2' ] } ) . action ( ( args ) => args ) ,
5757 ) ;
5858
59- it ( 'should not correctly resolve when first is named and second is positional' , ( ) => {
60- // `cmd val2 --pos1=val1` — val2 is assigned to pos1 positionally (overwriting --pos1=val1), pos2 is never set
59+ it ( 'should fail with ambiguity error when first is named and second is positional' , ( ) => {
60+ // `cmd val2 --pos1=val1` — pos1 is provided both positionally and as --pos1
6161 const result = program . eval ( 'cmd val2 --pos1=val1' ) ;
62- // The positional assignment overwrites the named value, so pos1 becomes val2
63- // and pos2 is missing, causing a validation error
6462 expect ( result . args ) . toBeUndefined ( ) ;
6563 expect ( result . argsResult ?. issues ) . toBeDefined ( ) ;
66- expect ( result . argsResult ?. issues ?. some ( ( i : any ) => i . path ?. includes ( 'pos2' ) ) ) . toBe ( true ) ;
64+ expect ( result . argsResult ?. issues ?. some ( ( i : any ) => i . message ?. includes ( 'Ambiguous' ) ) ) . toBe ( true ) ;
65+ } ) ;
66+ } ) ;
67+
68+ describe ( 'two positionals with optional — ambiguity still detected' , ( ) => {
69+ const program = createPadrone ( 'app' ) . command ( 'cmd' , ( c ) =>
70+ c . arguments ( z . object ( { pos1 : z . string ( ) , pos2 : z . string ( ) . optional ( ) } ) , { positional : [ 'pos1' , 'pos2' ] } ) . action ( ( args ) => args ) ,
71+ ) ;
72+
73+ it ( 'should fail even when the trailing positional is optional' , ( ) => {
74+ // `cmd val2 --pos1=val1` — pos1 is provided both positionally and as --pos1
75+ const result = program . eval ( 'cmd val2 --pos1=val1' ) ;
76+ expect ( result . args ) . toBeUndefined ( ) ;
77+ expect ( result . argsResult ?. issues ) . toBeDefined ( ) ;
78+ expect ( result . argsResult ?. issues ?. some ( ( i : any ) => i . message ?. includes ( 'Ambiguous' ) ) ) . toBe ( true ) ;
6779 } ) ;
6880 } ) ;
6981
@@ -88,19 +100,35 @@ describe('Positional arguments passed as named options', () => {
88100 } ) ;
89101
90102 it ( 'should fail when naming a middle positional but passing the last by position' , ( ) => {
91- // `cmd val1 val3 --b=val2` — val1→a, val3→b (overwrites --b=val2), c is missing
103+ // `cmd val1 val3 --b=val2` — b is provided both positionally and as --b
92104 const result = program . eval ( 'cmd val1 val3 --b=val2' ) ;
93105 expect ( result . args ) . toBeUndefined ( ) ;
94106 expect ( result . argsResult ?. issues ) . toBeDefined ( ) ;
95- expect ( result . argsResult ?. issues ?. some ( ( i : any ) => i . path ?. includes ( 'c ' ) ) ) . toBe ( true ) ;
107+ expect ( result . argsResult ?. issues ?. some ( ( i : any ) => i . message ?. includes ( 'Ambiguous ' ) ) ) . toBe ( true ) ;
96108 } ) ;
97109
98110 it ( 'should fail when naming the first positional but passing later ones by position' , ( ) => {
99- // `cmd val2 val3 --a=val1` — val2→a (overwrites), val3→b, c is missing
111+ // `cmd val2 val3 --a=val1` — a is provided both positionally and as --a
100112 const result = program . eval ( 'cmd val2 val3 --a=val1' ) ;
101113 expect ( result . args ) . toBeUndefined ( ) ;
102114 expect ( result . argsResult ?. issues ) . toBeDefined ( ) ;
103- expect ( result . argsResult ?. issues ?. some ( ( i : any ) => i . path ?. includes ( 'c' ) ) ) . toBe ( true ) ;
115+ expect ( result . argsResult ?. issues ?. some ( ( i : any ) => i . message ?. includes ( 'Ambiguous' ) ) ) . toBe ( true ) ;
116+ } ) ;
117+ } ) ;
118+
119+ describe ( 'three positionals with optional last — naming earlier still fails' , ( ) => {
120+ const program = createPadrone ( 'app' ) . command ( 'cmd' , ( c ) =>
121+ c
122+ . arguments ( z . object ( { a : z . string ( ) , b : z . string ( ) , c : z . string ( ) . optional ( ) } ) , { positional : [ 'a' , 'b' , 'c' ] } )
123+ . action ( ( args ) => args ) ,
124+ ) ;
125+
126+ it ( 'should fail when naming first positional with positional values present, even if last is optional' , ( ) => {
127+ // `cmd val1 val2 --a=val3` — a is provided both positionally and as --a
128+ const result = program . eval ( 'cmd val1 val2 --a=val3' ) ;
129+ expect ( result . args ) . toBeUndefined ( ) ;
130+ expect ( result . argsResult ?. issues ) . toBeDefined ( ) ;
131+ expect ( result . argsResult ?. issues ?. some ( ( i : any ) => i . message ?. includes ( 'Ambiguous' ) ) ) . toBe ( true ) ;
104132 } ) ;
105133 } ) ;
106134} ) ;
0 commit comments