@@ -58,6 +58,110 @@ describe('Multi-Expression Support', () => {
5858 } )
5959 } )
6060
61+ describe ( 'Semicolon after property access' , ( ) => {
62+ it ( 'handles semicolon after dot-accessed identifier' , ( ) => {
63+ const ctx = { obj : { val : 'hello' } }
64+ expect ( jexl . eval ( 's = obj.val; s' , ctx ) ) . toBe ( 'hello' )
65+ } )
66+
67+ it ( 'handles semicolon after function call result property' , ( ) => {
68+ const j = new Jexl ( )
69+ j . addFunction ( 'getObj' , ( ) => ( { CLNSIG : 'Benign' } ) )
70+ const lookup = { Benign : 'blue' , Pathogenic : 'red' }
71+ expect ( j . eval ( 's = getObj().CLNSIG; lookup[s]' , { lookup } ) ) . toBe ( 'blue' )
72+ } )
73+
74+ it ( 'handles semicolon after bracket access on identifier' , ( ) => {
75+ const ctx = { arr : [ 10 , 20 , 30 ] }
76+ expect ( jexl . eval ( 'v = arr[1]; v + 5' , ctx ) ) . toBe ( 25 )
77+ } )
78+ } )
79+
80+ describe ( 'Real-world expressions' , ( ) => {
81+ it ( 'handles full CLNSIG-style lookup with semicolon' , ( ) => {
82+ const j = new Jexl ( )
83+ j . addFunction ( 'get' , ( obj , key ) => obj [ key ] )
84+ const expr =
85+ "s = get(feature,'INFO').CLNSIG; ({'Benign':'blue','Likely_benign':'deepskyblue','Uncertain_significance':'gray','Pathogenic':'red','Likely_pathogenic':'orange','Conflicting_interpretations_of_pathogenicity':'brown'})[s] || 'purple'"
86+ expect (
87+ j . eval ( expr , { feature : { INFO : { CLNSIG : 'Benign' } } } )
88+ ) . toBe ( 'blue' )
89+ expect (
90+ j . eval ( expr , { feature : { INFO : { CLNSIG : 'Pathogenic' } } } )
91+ ) . toBe ( 'red' )
92+ expect (
93+ j . eval ( expr , { feature : { INFO : { CLNSIG : 'Likely_benign' } } } )
94+ ) . toBe ( 'deepskyblue' )
95+ expect (
96+ j . eval ( expr , {
97+ feature : {
98+ INFO : {
99+ CLNSIG : 'Conflicting_interpretations_of_pathogenicity'
100+ }
101+ }
102+ } )
103+ ) . toBe ( 'brown' )
104+ expect (
105+ j . eval ( expr , { feature : { INFO : { CLNSIG : 'SomethingElse' } } } )
106+ ) . toBe ( 'purple' )
107+ } )
108+
109+ it ( 'handles CLNSIG-style lookup returning default' , ( ) => {
110+ const j = new Jexl ( )
111+ j . addFunction ( 'get' , ( obj , key ) => obj [ key ] )
112+ const feature = {
113+ INFO : { CLNSIG : 'Unknown' }
114+ }
115+ const result = j . eval (
116+ "s = get(feature,'INFO').CLNSIG; ({'Benign':'blue','Pathogenic':'red'})[s] || 'purple'" ,
117+ { feature }
118+ )
119+ expect ( result ) . toBe ( 'purple' )
120+ } )
121+
122+ it ( 'semicolon after function call with no property access' , ( ) => {
123+ const j = new Jexl ( )
124+ j . addFunction ( 'add' , ( a , b ) => a + b )
125+ expect ( j . eval ( 'x = add(3, 4); x * 2' ) ) . toBe ( 14 )
126+ } )
127+
128+ it ( 'semicolon after bracket access on result of parens' , ( ) => {
129+ expect ( jexl . eval ( "s = 'a'; ({'a': 1, 'b': 2})[s]" ) ) . toBe ( 1 )
130+ } )
131+ } )
132+
133+ describe ( 'Edge cases' , ( ) => {
134+ it ( 'handles negative numbers after semicolons' , ( ) => {
135+ expect ( jexl . eval ( '5; -3' ) ) . toBe ( - 3 )
136+ } )
137+
138+ it ( 'handles trailing semicolons' , ( ) => {
139+ expect ( jexl . eval ( '5;' ) ) . toBe ( 5 )
140+ } )
141+
142+ it ( 'handles negative numbers after commas in function args' , ( ) => {
143+ const j = new Jexl ( )
144+ j . addFunction ( 'add' , ( a , b ) => a + b )
145+ expect ( j . eval ( 'add(1, -2)' ) ) . toBe ( - 1 )
146+ } )
147+
148+ it ( 'handles semicolon after ternary expression' , ( ) => {
149+ expect ( jexl . eval ( 'true ? 1 : 2; 99' ) ) . toBe ( 99 )
150+ } )
151+
152+ it ( 'handles ternary with object literal still works' , ( ) => {
153+ expect ( jexl . eval ( 'true ? {a:1} : {b:2}' ) ) . toEqual ( { a : 1 } )
154+ } )
155+
156+ it ( 'handles ternary inside array' , ( ) => {
157+ expect ( jexl . eval ( '[true ? 1 : 2]' ) ) . toEqual ( [ 1 ] )
158+ } )
159+
160+ it ( 'handles ternary in parens with continuation' , ( ) => {
161+ expect ( jexl . eval ( '(true ? 1 : 2) + 3' ) ) . toBe ( 4 )
162+ } )
163+ } )
164+
61165 describe ( 'Error Handling' , ( ) => {
62166 it ( 'assignment to non-identifier throws error' , ( ) => {
63167 expect ( ( ) => jexl . eval ( '5 = 10' ) ) . toThrow (
0 commit comments