@fincity/kirun-js 3.1.4 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/engine/dsl/GraphDebugTest.ts +316 -0
- package/__tests__/engine/runtime/expression/ExpressionParsingTest.ts +402 -14
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/module.js +15 -1
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +416 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/engine/dsl/DSLCompiler.ts +104 -0
- package/src/engine/dsl/index.ts +30 -0
- package/src/engine/dsl/lexer/DSLLexer.ts +518 -0
- package/src/engine/dsl/lexer/DSLToken.ts +74 -0
- package/src/engine/dsl/lexer/Keywords.ts +80 -0
- package/src/engine/dsl/lexer/LexerError.ts +37 -0
- package/src/engine/dsl/monaco/DSLFunctionProvider.ts +187 -0
- package/src/engine/dsl/parser/DSLParser.ts +1075 -0
- package/src/engine/dsl/parser/DSLParserError.ts +29 -0
- package/src/engine/dsl/parser/ast/ASTNode.ts +23 -0
- package/src/engine/dsl/parser/ast/ArgumentNode.ts +43 -0
- package/src/engine/dsl/parser/ast/ComplexValueNode.ts +22 -0
- package/src/engine/dsl/parser/ast/EventDeclNode.ts +27 -0
- package/src/engine/dsl/parser/ast/ExpressionNode.ts +33 -0
- package/src/engine/dsl/parser/ast/FunctionCallNode.ts +29 -0
- package/src/engine/dsl/parser/ast/FunctionDefNode.ts +37 -0
- package/src/engine/dsl/parser/ast/ParameterDeclNode.ts +25 -0
- package/src/engine/dsl/parser/ast/SchemaLiteralNode.ts +26 -0
- package/src/engine/dsl/parser/ast/SchemaNode.ts +23 -0
- package/src/engine/dsl/parser/ast/StatementNode.ts +41 -0
- package/src/engine/dsl/parser/ast/index.ts +14 -0
- package/src/engine/dsl/transformer/ASTToJSON.ts +378 -0
- package/src/engine/dsl/transformer/ExpressionHandler.ts +48 -0
- package/src/engine/dsl/transformer/JSONToText.ts +694 -0
- package/src/engine/dsl/transformer/SchemaTransformer.ts +110 -0
- package/src/engine/model/FunctionDefinition.ts +23 -0
- package/src/engine/runtime/expression/Expression.ts +5 -1
- package/src/engine/runtime/expression/ExpressionEvaluator.ts +152 -139
- package/src/engine/runtime/expression/ExpressionParser.ts +80 -27
- package/src/engine/util/duplicate.ts +3 -1
- package/src/index.ts +1 -0
|
@@ -387,18 +387,6 @@ describe('Original Expression Parsing Tests', () => {
|
|
|
387
387
|
expect(expr.toString()).toContain('??');
|
|
388
388
|
});
|
|
389
389
|
|
|
390
|
-
test('Expression 3: Parent.perCount[Parent.Parent.__index].value. Percentage + \'%\'', () => {
|
|
391
|
-
// This expression has:
|
|
392
|
-
// 1. Dynamic array index with path expression
|
|
393
|
-
// 2. Space before "Percentage" (after the dot)
|
|
394
|
-
// 3. String concatenation with '%'
|
|
395
|
-
const expression = "Parent.perCount[Parent.Parent.__index].value. Percentage + '%'";
|
|
396
|
-
|
|
397
|
-
// Verify parsing succeeds (space before property name is handled)
|
|
398
|
-
const expr = new Expression(expression);
|
|
399
|
-
expect(expr).toBeDefined();
|
|
400
|
-
});
|
|
401
|
-
|
|
402
390
|
test('Expression 4: Page.dealData.size < Page.dealData.totalElements', () => {
|
|
403
391
|
// This expression has extra space in the less-than comparison
|
|
404
392
|
const expression = 'Page.dealData.size < Page.dealData.totalElements';
|
|
@@ -415,8 +403,8 @@ describe('Original Expression Parsing Tests', () => {
|
|
|
415
403
|
const expressions = [
|
|
416
404
|
'Steps.floorWeekOne.output.value * {{Page.secondsInDay}}',
|
|
417
405
|
"Parent.projectInfo.projectType?? '-'",
|
|
418
|
-
"Parent.perCount[Parent.Parent.__index].value. Percentage + '%'",
|
|
419
406
|
'Page.dealData.size < Page.dealData.totalElements',
|
|
407
|
+
'Store.pageDefinition.{{Store.urlDetails.pageName}}.properties.title.name.value ?? {{Store.pageDefinition.{{Store.urlDetails.pageName}}.properties.title.name.location.expression}}',
|
|
420
408
|
];
|
|
421
409
|
|
|
422
410
|
for (const expression of expressions) {
|
|
@@ -557,7 +545,7 @@ describe('Original Expression Parsing Tests', () => {
|
|
|
557
545
|
|
|
558
546
|
test('Expression 7: Nested dynamic bracket index', () => {
|
|
559
547
|
const parentExtractor = new TestTokenValueExtractor('Parent.', { index: 1 });
|
|
560
|
-
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
548
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
561
549
|
matrix: [
|
|
562
550
|
['a', 'b', 'c'],
|
|
563
551
|
['d', 'e', 'f'],
|
|
@@ -575,4 +563,404 @@ describe('Original Expression Parsing Tests', () => {
|
|
|
575
563
|
|
|
576
564
|
expect(result).toBe('e');
|
|
577
565
|
});
|
|
566
|
+
|
|
567
|
+
test('Expression 8: Store.pageDefinition.{{Store.urlDetails.pageName}}.properties.title.name.value ?? {{Store.pageDefinition.{{Store.urlDetails.pageName}}.properties.title.name.location.expression}}', () => {
|
|
568
|
+
// Expression: dynamic page key from urlDetails.pageName, nullish coalesce value with location.expression
|
|
569
|
+
const expression =
|
|
570
|
+
'Store.pageDefinition.{{Store.urlDetails.pageName}}.properties.title.name.value ?? {{Store.pageDefinition.{{Store.urlDetails.pageName}}.properties.title.name.location.expression}}';
|
|
571
|
+
|
|
572
|
+
// Verify parsing succeeds
|
|
573
|
+
const expr = new Expression(expression);
|
|
574
|
+
expect(expr).toBeDefined();
|
|
575
|
+
expect(expr.getOperations().isEmpty()).toBe(false);
|
|
576
|
+
|
|
577
|
+
// Store with urlDetails.pageName = "home" and pageDefinition.home.properties.title.name.value present
|
|
578
|
+
const storeWithValue = new TestTokenValueExtractor('Store.', {
|
|
579
|
+
application: {
|
|
580
|
+
properties: {
|
|
581
|
+
title: 'My Application Title',
|
|
582
|
+
},
|
|
583
|
+
},
|
|
584
|
+
urlDetails: { pageName: 'home' },
|
|
585
|
+
pageDefinition: {
|
|
586
|
+
home: {
|
|
587
|
+
properties: {
|
|
588
|
+
title: {
|
|
589
|
+
name: {
|
|
590
|
+
location: { expression: "'Application : ' + Store.application.properties.title" },
|
|
591
|
+
},
|
|
592
|
+
},
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
},
|
|
596
|
+
});
|
|
597
|
+
const valuesMapWithValue: Map<string, TokenValueExtractor> = new Map([
|
|
598
|
+
[storeWithValue.getPrefix(), storeWithValue],
|
|
599
|
+
]);
|
|
600
|
+
|
|
601
|
+
const ev = new ExpressionEvaluator(expression);
|
|
602
|
+
expect(ev.evaluate(valuesMapWithValue)).toBe('Application : My Application Title');
|
|
603
|
+
|
|
604
|
+
// Store with value null - should return location.expression
|
|
605
|
+
|
|
606
|
+
const storeValueNull = new TestTokenValueExtractor('Store.', {
|
|
607
|
+
urlDetails: { pageName: 'home' },
|
|
608
|
+
pageDefinition: {
|
|
609
|
+
home: {
|
|
610
|
+
properties: {
|
|
611
|
+
title: {
|
|
612
|
+
name: {
|
|
613
|
+
value: null,
|
|
614
|
+
location: { expression: 'Expression Fallback Title' },
|
|
615
|
+
},
|
|
616
|
+
},
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
},
|
|
620
|
+
});
|
|
621
|
+
const valuesMapValueNull: Map<string, TokenValueExtractor> = new Map([
|
|
622
|
+
[storeValueNull.getPrefix(), storeValueNull],
|
|
623
|
+
]);
|
|
624
|
+
expect(ev.evaluate(valuesMapValueNull)).toBe('Expression Fallback Title');
|
|
625
|
+
|
|
626
|
+
// Store with value missing (no .value key) - should return location.expression
|
|
627
|
+
// Use a fresh evaluator to avoid any cached expansion from previous evaluations
|
|
628
|
+
const storeValueMissing = new TestTokenValueExtractor('Store.', {
|
|
629
|
+
urlDetails: { pageName: 'home' },
|
|
630
|
+
pageDefinition: {
|
|
631
|
+
home: {
|
|
632
|
+
properties: {
|
|
633
|
+
title: {
|
|
634
|
+
name: {
|
|
635
|
+
location: { expression: 'Expression Fallback Title' },
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
},
|
|
639
|
+
},
|
|
640
|
+
},
|
|
641
|
+
});
|
|
642
|
+
const valuesMapValueMissing: Map<string, TokenValueExtractor> = new Map([
|
|
643
|
+
[storeValueMissing.getPrefix(), storeValueMissing],
|
|
644
|
+
]);
|
|
645
|
+
const evFresh = new ExpressionEvaluator(expression);
|
|
646
|
+
expect(evFresh.evaluate(valuesMapValueMissing)).toBe('Expression Fallback Title');
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
test('Expression 9a: Simplified nested ternary to isolate issue', () => {
|
|
650
|
+
// Simplified version to isolate the issue
|
|
651
|
+
const expression = `Page.a != undefined ? 'A' : Page.b != undefined ? 'B' : Page.c != undefined ? 'C' : '-'`;
|
|
652
|
+
|
|
653
|
+
// Test with matching condition
|
|
654
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
655
|
+
a: 'test'
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
const valuesMap = new Map([
|
|
659
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
660
|
+
]);
|
|
661
|
+
|
|
662
|
+
const ev = new ExpressionEvaluator(expression);
|
|
663
|
+
expect(ev.evaluate(valuesMap)).toBe('A');
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
test('Expression 9b: Nested ternary with dynamic keys', () => {
|
|
667
|
+
// Test with dynamic keys using {{}}
|
|
668
|
+
const expression = `Page.kycs.{{Parent.id}}.a != undefined ? 'A' : Page.kycs.{{Parent.id}}.b != undefined ? 'B' : '-'`;
|
|
669
|
+
|
|
670
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
671
|
+
kycs: {
|
|
672
|
+
'123': {
|
|
673
|
+
a: 'test'
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
const parentExtractor = new TestTokenValueExtractor('Parent.', {
|
|
679
|
+
id: '123'
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
const valuesMap = new Map([
|
|
683
|
+
[pageExtractor.getPrefix(), pageExtractor],
|
|
684
|
+
[parentExtractor.getPrefix(), parentExtractor]
|
|
685
|
+
]);
|
|
686
|
+
|
|
687
|
+
const ev = new ExpressionEvaluator(expression);
|
|
688
|
+
expect(ev.evaluate(valuesMap)).toBe('A');
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
test('Expression 9c1: Debug - Simplest failing case', () => {
|
|
692
|
+
// Simplest case that reproduces the issue
|
|
693
|
+
const expression = `true ? 'a' +' '+ 'b' : false ? 'c' +' '+ 'd' : '-'`;
|
|
694
|
+
|
|
695
|
+
const valuesMap = new Map();
|
|
696
|
+
|
|
697
|
+
const ev = new ExpressionEvaluator(expression);
|
|
698
|
+
const result = ev.evaluate(valuesMap);
|
|
699
|
+
expect(result).toBe('a b');
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
test('Expression 9c2: Debug - With property access', () => {
|
|
703
|
+
// Test with property access in ternary
|
|
704
|
+
const expression = `true ? Page.a +' '+ Page.b : false ? Page.c +' '+ Page.d : '-'`;
|
|
705
|
+
|
|
706
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
707
|
+
a: 'Hello',
|
|
708
|
+
b: 'World'
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
const valuesMap = new Map([
|
|
712
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
713
|
+
]);
|
|
714
|
+
|
|
715
|
+
const ev = new ExpressionEvaluator(expression);
|
|
716
|
+
const result = ev.evaluate(valuesMap);
|
|
717
|
+
expect(result).toBe('Hello World');
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
test('Expression 9c3: Debug - With deeper property paths like original', () => {
|
|
721
|
+
// Test with deeper property paths like the original failing expression
|
|
722
|
+
const expression = `true ? Page.x.a.first +' '+ Page.x.a.last : '-'`;
|
|
723
|
+
|
|
724
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
725
|
+
x: {
|
|
726
|
+
a: {
|
|
727
|
+
first: 'John',
|
|
728
|
+
last: 'Doe'
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
const valuesMap = new Map([
|
|
734
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
735
|
+
]);
|
|
736
|
+
|
|
737
|
+
const ev = new ExpressionEvaluator(expression);
|
|
738
|
+
const result = ev.evaluate(valuesMap);
|
|
739
|
+
expect(result).toBe('John Doe');
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
test('Expression 9c4: Debug - Nested ternary with deep paths', () => {
|
|
743
|
+
// Test nested ternary with deep property paths
|
|
744
|
+
const expression = `true ? Page.x.a.first +' '+ Page.x.a.last : false ? Page.x.b.first +' '+ Page.x.b.last : '-'`;
|
|
745
|
+
|
|
746
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
747
|
+
x: {
|
|
748
|
+
a: {
|
|
749
|
+
first: 'John',
|
|
750
|
+
last: 'Doe'
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
const valuesMap = new Map([
|
|
756
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
757
|
+
]);
|
|
758
|
+
|
|
759
|
+
const ev = new ExpressionEvaluator(expression);
|
|
760
|
+
const result = ev.evaluate(valuesMap);
|
|
761
|
+
expect(result).toBe('John Doe');
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
test('Expression 9c5: Debug - With NUMERIC property path segment', () => {
|
|
765
|
+
// Test numeric segment in property path - should now work with the fix
|
|
766
|
+
const expression = `true ? Page.x.123.a.first +' '+ Page.x.123.a.last : '-'`;
|
|
767
|
+
|
|
768
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
769
|
+
x: {
|
|
770
|
+
'123': {
|
|
771
|
+
a: {
|
|
772
|
+
first: 'John',
|
|
773
|
+
last: 'Doe'
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
const valuesMap = new Map([
|
|
780
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
781
|
+
]);
|
|
782
|
+
|
|
783
|
+
const ev = new ExpressionEvaluator(expression);
|
|
784
|
+
const result = ev.evaluate(valuesMap);
|
|
785
|
+
expect(result).toBe('John Doe');
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
test('Expression 9c6: Debug - With ObjectId-like property path segment', () => {
|
|
789
|
+
// Test with alphanumeric ObjectId-like value (e.g., MongoDB ObjectId)
|
|
790
|
+
const expression = `true ? Page.x.507f1f77bcf86cd799439011.a.first +' '+ Page.x.507f1f77bcf86cd799439011.a.last : '-'`;
|
|
791
|
+
|
|
792
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
793
|
+
x: {
|
|
794
|
+
'507f1f77bcf86cd799439011': {
|
|
795
|
+
a: {
|
|
796
|
+
first: 'Jane',
|
|
797
|
+
last: 'Smith'
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
const valuesMap = new Map([
|
|
804
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
805
|
+
]);
|
|
806
|
+
|
|
807
|
+
const ev = new ExpressionEvaluator(expression);
|
|
808
|
+
const result = ev.evaluate(valuesMap);
|
|
809
|
+
expect(result).toBe('Jane Smith');
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
test('Expression 9c7: Debug - With underscore in property path segment', () => {
|
|
813
|
+
// Test with property names containing underscores and numbers
|
|
814
|
+
const expression = `true ? Page.x.123_abc.a.first +' '+ Page.x.123_abc.a.last : '-'`;
|
|
815
|
+
|
|
816
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
817
|
+
x: {
|
|
818
|
+
'123_abc': {
|
|
819
|
+
a: {
|
|
820
|
+
first: 'Bob',
|
|
821
|
+
last: 'Johnson'
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
const valuesMap = new Map([
|
|
828
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
829
|
+
]);
|
|
830
|
+
|
|
831
|
+
const ev = new ExpressionEvaluator(expression);
|
|
832
|
+
const result = ev.evaluate(valuesMap);
|
|
833
|
+
expect(result).toBe('Bob Johnson');
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
test('Expression 9c: Debug - Parse expanded expression without {{}}', () => {
|
|
837
|
+
// Test the expanded expression directly (without {{}}) to see if parsing is the issue
|
|
838
|
+
const expandedExpression = `Page.kycs.123.a != undefined ? Page.kycs.123.a.first +' '+ Page.kycs.123.a.last : Page.kycs.123.b != undefined ? Page.kycs.123.b.first +' '+ Page.kycs.123.b.last : '-'`;
|
|
839
|
+
|
|
840
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
841
|
+
kycs: {
|
|
842
|
+
'123': {
|
|
843
|
+
a: {
|
|
844
|
+
first: 'John',
|
|
845
|
+
last: 'Doe'
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
|
|
851
|
+
const valuesMap = new Map([
|
|
852
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
853
|
+
]);
|
|
854
|
+
|
|
855
|
+
const ev = new ExpressionEvaluator(expandedExpression);
|
|
856
|
+
const result = ev.evaluate(valuesMap);
|
|
857
|
+
expect(result).toBe('John Doe');
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
test('Expression 9c: Nested ternary with string concatenation', () => {
|
|
861
|
+
// Test with string concatenation in ternary branches
|
|
862
|
+
const expression = `Page.kycs.{{Parent.id}}.a != undefined ? Page.kycs.{{Parent.id}}.a.first +' '+ Page.kycs.{{Parent.id}}.a.last : Page.kycs.{{Parent.id}}.b != undefined ? Page.kycs.{{Parent.id}}.b.first +' '+ Page.kycs.{{Parent.id}}.b.last : '-'`;
|
|
863
|
+
|
|
864
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
865
|
+
kycs: {
|
|
866
|
+
'123': {
|
|
867
|
+
a: {
|
|
868
|
+
first: 'John',
|
|
869
|
+
last: 'Doe'
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
const parentExtractor = new TestTokenValueExtractor('Parent.', {
|
|
876
|
+
id: '123'
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
const valuesMap = new Map([
|
|
880
|
+
[pageExtractor.getPrefix(), pageExtractor],
|
|
881
|
+
[parentExtractor.getPrefix(), parentExtractor]
|
|
882
|
+
]);
|
|
883
|
+
|
|
884
|
+
const ev = new ExpressionEvaluator(expression);
|
|
885
|
+
expect(ev.evaluate(valuesMap)).toBe('John Doe');
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
test('Expression 9: Complex nested ternary with dynamic keys and string concatenation', () => {
|
|
889
|
+
// This is a complex multi-level ternary with dynamic object keys and string concatenation
|
|
890
|
+
const expression = `Page.kycs.{{Parent.kycAccountId}}.individual != undefined ? Page.kycs.{{Parent.kycAccountId}}.individual.basic.personalInformation.firstName +' '+ Page.kycs.{{Parent.kycAccountId}}.individual.basic.personalInformation.lastName : Page.kycs.{{Parent.kycAccountId}}.joint != undefined ? Page.kycs.{{Parent.kycAccountId}}.joint.mainApplicant.individual.basic.personalInformation.firstName +' '+ Page.kycs.{{Parent.kycAccountId}}.joint.mainApplicant.individual.basic.personalInformation.lastName : Page.kycs.{{Parent.kycAccountId}}.llp != undefined ? Page.kycs.{{Parent.kycAccountId}}.llp.authorizePerson.personalInformation.firstName +' '+ Page.kycs.{{Parent.kycAccountId}}.llp.authorizePerson.personalInformation.lastName : Page.kycs.{{Parent.kycAccountId}}.partnership != undefined ? Page.kycs.{{Parent.kycAccountId}}.partnership.authorizePerson.personalInformation.firstName +' '+ Page.kycs.{{Parent.kycAccountId}}.partnership.authorizePerson.personalInformation.lastName : Page.kycs.{{Parent.kycAccountId}}.private != undefined ? Page.kycs.{{Parent.kycAccountId}}.private.authorizePerson.personalInformation.firstName +' '+ Page.kycs.{{Parent.kycAccountId}}.private.authorizePerson.personalInformation.lastName : Page.kycs.{{Parent.kycAccountId}}.trust != undefined ? Page.kycs.{{Parent.kycAccountId}}.trust.authorizePerson.personalInformation.firstName +' '+ Page.kycs.{{Parent.kycAccountId}}.trust.authorizePerson.personalInformation.lastName : Page.kycs.{{Parent.kycAccountId}}.huf != undefined ? Page.kycs.{{Parent.kycAccountId}}.huf.kartaInformation.personalInformation.firstName +' '+ Page.kycs.{{Parent.kycAccountId}}.huf.kartaInformation.personalInformation.lastName : '-'`;
|
|
891
|
+
|
|
892
|
+
// Test with individual account type
|
|
893
|
+
const pageExtractorIndividual = new TestTokenValueExtractor('Page.', {
|
|
894
|
+
kycs: {
|
|
895
|
+
'123': {
|
|
896
|
+
individual: {
|
|
897
|
+
basic: {
|
|
898
|
+
personalInformation: {
|
|
899
|
+
firstName: 'John',
|
|
900
|
+
lastName: 'Doe'
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
const parentExtractorIndividual = new TestTokenValueExtractor('Parent.', {
|
|
909
|
+
kycAccountId: '123'
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
const valuesMapIndividual = new Map([
|
|
913
|
+
[pageExtractorIndividual.getPrefix(), pageExtractorIndividual],
|
|
914
|
+
[parentExtractorIndividual.getPrefix(), parentExtractorIndividual]
|
|
915
|
+
]);
|
|
916
|
+
|
|
917
|
+
const ev = new ExpressionEvaluator(expression);
|
|
918
|
+
expect(ev.evaluate(valuesMapIndividual)).toBe('John Doe');
|
|
919
|
+
|
|
920
|
+
// Test with fallback (no matching account type)
|
|
921
|
+
const pageExtractorFallback = new TestTokenValueExtractor('Page.', {
|
|
922
|
+
kycs: {
|
|
923
|
+
'456': {}
|
|
924
|
+
}
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
const parentExtractorFallback = new TestTokenValueExtractor('Parent.', {
|
|
928
|
+
kycAccountId: '456'
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
const valuesMapFallback = new Map([
|
|
932
|
+
[pageExtractorFallback.getPrefix(), pageExtractorFallback],
|
|
933
|
+
[parentExtractorFallback.getPrefix(), parentExtractorFallback]
|
|
934
|
+
]);
|
|
935
|
+
|
|
936
|
+
const evFallback = new ExpressionEvaluator(expression);
|
|
937
|
+
expect(evFallback.evaluate(valuesMapFallback)).toBe('-');
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
test('Expression trimming: Leading and trailing whitespace should be trimmed', () => {
|
|
941
|
+
// Test that expressions with leading/trailing whitespace are properly trimmed
|
|
942
|
+
const expr1 = new Expression(' Page.value ');
|
|
943
|
+
expect(expr1.getExpression()).toBe('Page.value');
|
|
944
|
+
|
|
945
|
+
const expr2 = new Expression(' true ? "yes" : "no" ');
|
|
946
|
+
expect(expr2.getExpression()).toBe('true ? "yes" : "no"');
|
|
947
|
+
|
|
948
|
+
const expr3 = new Expression('\t\nPage.x + 5\n\t');
|
|
949
|
+
expect(expr3.getExpression()).toBe('Page.x + 5');
|
|
950
|
+
|
|
951
|
+
// Test with actual evaluation to ensure trimming doesn't break functionality
|
|
952
|
+
const pageExtractor = new TestTokenValueExtractor('Page.', {
|
|
953
|
+
value: 'test',
|
|
954
|
+
x: 10
|
|
955
|
+
});
|
|
956
|
+
const valuesMap = new Map([
|
|
957
|
+
[pageExtractor.getPrefix(), pageExtractor]
|
|
958
|
+
]);
|
|
959
|
+
|
|
960
|
+
const ev1 = new ExpressionEvaluator(' Page.value ');
|
|
961
|
+
expect(ev1.evaluate(valuesMap)).toBe('test');
|
|
962
|
+
|
|
963
|
+
const ev2 = new ExpressionEvaluator(' Page.x + 5 ');
|
|
964
|
+
expect(ev2.evaluate(valuesMap)).toBe(15);
|
|
965
|
+
});
|
|
578
966
|
});
|