@weborigami/language 0.2.3 → 0.2.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/language",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Web Origami expression language compiler and runtime",
5
5
  "type": "module",
6
6
  "main": "./main.js",
@@ -12,8 +12,8 @@
12
12
  "yaml": "2.6.1"
13
13
  },
14
14
  "dependencies": {
15
- "@weborigami/async-tree": "0.2.3",
16
- "@weborigami/types": "0.2.3",
15
+ "@weborigami/async-tree": "0.2.4",
16
+ "@weborigami/types": "0.2.4",
17
17
  "watcher": "2.3.1"
18
18
  },
19
19
  "scripts": {
@@ -31,12 +31,12 @@ import {
31
31
 
32
32
  // A block of optional whitespace
33
33
  __
34
- = (inlineSpace / newLine / comment)* {
34
+ = whitespace* {
35
35
  return null;
36
36
  }
37
37
 
38
38
  additiveExpression
39
- = head:multiplicativeExpression tail:(__ @additiveOperator __ @multiplicativeExpression)* {
39
+ = head:multiplicativeExpression tail:(whitespace @additiveOperator whitespace @multiplicativeExpression)* {
40
40
  return annotate(tail.reduce(makeBinaryOperation, head), location());
41
41
  }
42
42
 
@@ -148,8 +148,8 @@ comment "comment"
148
148
 
149
149
  conditionalExpression
150
150
  = condition:logicalOrExpression tail:(__
151
- "?" __ @pipelineExpression __
152
- ":" __ @pipelineExpression)?
151
+ "?" __ @shorthandFunction __
152
+ ":" __ @shorthandFunction)?
153
153
  {
154
154
  if (!tail) {
155
155
  return condition;
@@ -310,7 +310,7 @@ multiLineComment
310
310
  = "/*" (!"*/" .)* "*/" { return null; }
311
311
 
312
312
  multiplicativeExpression
313
- = head:exponentiationExpression tail:(__ @multiplicativeOperator __ @exponentiationExpression)* {
313
+ = head:exponentiationExpression tail:(whitespace @multiplicativeOperator whitespace @exponentiationExpression)* {
314
314
  return annotate(tail.reduce(makeBinaryOperation, head), location());
315
315
  }
316
316
 
@@ -625,5 +625,10 @@ unaryOperator
625
625
  / "-"
626
626
  / "~"
627
627
 
628
+ whitespace
629
+ = inlineSpace
630
+ / newLine
631
+ / comment
632
+
628
633
  whitespaceWithNewLine
629
634
  = inlineSpace* comment? newLine __
@@ -202,7 +202,7 @@ function peg$parse(input, options) {
202
202
  var peg$FAILED = {};
203
203
  var peg$source = options.grammarSource;
204
204
 
205
- var peg$startRuleFunctions = { __: peg$parse__, additiveExpression: peg$parseadditiveExpression, additiveOperator: peg$parseadditiveOperator, arguments: peg$parsearguments, arrayLiteral: peg$parsearrayLiteral, arrayEntries: peg$parsearrayEntries, arrayEntry: peg$parsearrayEntry, arrowFunction: peg$parsearrowFunction, bitwiseAndExpression: peg$parsebitwiseAndExpression, bitwiseAndOperator: peg$parsebitwiseAndOperator, bitwiseOrExpression: peg$parsebitwiseOrExpression, bitwiseOrOperator: peg$parsebitwiseOrOperator, bitwiseXorExpression: peg$parsebitwiseXorExpression, bitwiseXorOperator: peg$parsebitwiseXorOperator, callExpression: peg$parsecallExpression, closingBrace: peg$parseclosingBrace, closingBracket: peg$parseclosingBracket, closingParenthesis: peg$parseclosingParenthesis, commaExpression: peg$parsecommaExpression, comment: peg$parsecomment, conditionalExpression: peg$parseconditionalExpression, digits: peg$parsedigits, doubleArrow: peg$parsedoubleArrow, doubleQuoteString: peg$parsedoubleQuoteString, doubleQuoteStringChar: peg$parsedoubleQuoteStringChar, ellipsis: peg$parseellipsis, equalityExpression: peg$parseequalityExpression, equalityOperator: peg$parseequalityOperator, escapedChar: peg$parseescapedChar, exponentiationExpression: peg$parseexponentiationExpression, expression: peg$parseexpression, floatLiteral: peg$parsefloatLiteral, group: peg$parsegroup, guillemetString: peg$parseguillemetString, guillemetStringChar: peg$parseguillemetStringChar, homeDirectory: peg$parsehomeDirectory, host: peg$parsehost, identifier: peg$parseidentifier, identifierChar: peg$parseidentifierChar, identifierList: peg$parseidentifierList, implicitParenthesesCallExpression: peg$parseimplicitParenthesesCallExpression, implicitParensthesesArguments: peg$parseimplicitParensthesesArguments, inlineSpace: peg$parseinlineSpace, integerLiteral: peg$parseintegerLiteral, list: peg$parselist, literal: peg$parseliteral, logicalAndExpression: peg$parselogicalAndExpression, logicalOrExpression: peg$parselogicalOrExpression, multiLineComment: peg$parsemultiLineComment, multiplicativeExpression: peg$parsemultiplicativeExpression, multiplicativeOperator: peg$parsemultiplicativeOperator, namespace: peg$parsenamespace, newLine: peg$parsenewLine, numericLiteral: peg$parsenumericLiteral, nullishCoalescingExpression: peg$parsenullishCoalescingExpression, objectLiteral: peg$parseobjectLiteral, objectEntries: peg$parseobjectEntries, objectEntry: peg$parseobjectEntry, objectGetter: peg$parseobjectGetter, objectHiddenKey: peg$parseobjectHiddenKey, objectKey: peg$parseobjectKey, objectProperty: peg$parseobjectProperty, objectShorthandProperty: peg$parseobjectShorthandProperty, objectPublicKey: peg$parseobjectPublicKey, parenthesesArguments: peg$parseparenthesesArguments, path: peg$parsepath, pathArguments: peg$parsepathArguments, pathKey: peg$parsepathKey, pathSegment: peg$parsepathSegment, pathSegmentChar: peg$parsepathSegmentChar, pipelineExpression: peg$parsepipelineExpression, primary: peg$parseprimary, program: peg$parseprogram, protocolExpression: peg$parseprotocolExpression, qualifiedReference: peg$parsequalifiedReference, reference: peg$parsereference, relationalExpression: peg$parserelationalExpression, relationalOperator: peg$parserelationalOperator, rootDirectory: peg$parserootDirectory, scopeReference: peg$parsescopeReference, separator: peg$parseseparator, slashFollows: peg$parseslashFollows, shebang: peg$parseshebang, shiftExpression: peg$parseshiftExpression, shiftOperator: peg$parseshiftOperator, shorthandFunction: peg$parseshorthandFunction, singleArrow: peg$parsesingleArrow, singleLineComment: peg$parsesingleLineComment, singleQuoteString: peg$parsesingleQuoteString, singleQuoteStringChar: peg$parsesingleQuoteStringChar, spreadElement: peg$parsespreadElement, stringLiteral: peg$parsestringLiteral, templateDocument: peg$parsetemplateDocument, templateDocumentChar: peg$parsetemplateDocumentChar, templateDocumentText: peg$parsetemplateDocumentText, templateLiteral: peg$parsetemplateLiteral, templateLiteralChar: peg$parsetemplateLiteralChar, templateLiteralText: peg$parsetemplateLiteralText, templateSubstitution: peg$parsetemplateSubstitution, textChar: peg$parsetextChar, unaryExpression: peg$parseunaryExpression, unaryOperator: peg$parseunaryOperator, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
205
+ var peg$startRuleFunctions = { __: peg$parse__, additiveExpression: peg$parseadditiveExpression, additiveOperator: peg$parseadditiveOperator, arguments: peg$parsearguments, arrayLiteral: peg$parsearrayLiteral, arrayEntries: peg$parsearrayEntries, arrayEntry: peg$parsearrayEntry, arrowFunction: peg$parsearrowFunction, bitwiseAndExpression: peg$parsebitwiseAndExpression, bitwiseAndOperator: peg$parsebitwiseAndOperator, bitwiseOrExpression: peg$parsebitwiseOrExpression, bitwiseOrOperator: peg$parsebitwiseOrOperator, bitwiseXorExpression: peg$parsebitwiseXorExpression, bitwiseXorOperator: peg$parsebitwiseXorOperator, callExpression: peg$parsecallExpression, closingBrace: peg$parseclosingBrace, closingBracket: peg$parseclosingBracket, closingParenthesis: peg$parseclosingParenthesis, commaExpression: peg$parsecommaExpression, comment: peg$parsecomment, conditionalExpression: peg$parseconditionalExpression, digits: peg$parsedigits, doubleArrow: peg$parsedoubleArrow, doubleQuoteString: peg$parsedoubleQuoteString, doubleQuoteStringChar: peg$parsedoubleQuoteStringChar, ellipsis: peg$parseellipsis, equalityExpression: peg$parseequalityExpression, equalityOperator: peg$parseequalityOperator, escapedChar: peg$parseescapedChar, exponentiationExpression: peg$parseexponentiationExpression, expression: peg$parseexpression, floatLiteral: peg$parsefloatLiteral, group: peg$parsegroup, guillemetString: peg$parseguillemetString, guillemetStringChar: peg$parseguillemetStringChar, homeDirectory: peg$parsehomeDirectory, host: peg$parsehost, identifier: peg$parseidentifier, identifierChar: peg$parseidentifierChar, identifierList: peg$parseidentifierList, implicitParenthesesCallExpression: peg$parseimplicitParenthesesCallExpression, implicitParensthesesArguments: peg$parseimplicitParensthesesArguments, inlineSpace: peg$parseinlineSpace, integerLiteral: peg$parseintegerLiteral, list: peg$parselist, literal: peg$parseliteral, logicalAndExpression: peg$parselogicalAndExpression, logicalOrExpression: peg$parselogicalOrExpression, multiLineComment: peg$parsemultiLineComment, multiplicativeExpression: peg$parsemultiplicativeExpression, multiplicativeOperator: peg$parsemultiplicativeOperator, namespace: peg$parsenamespace, newLine: peg$parsenewLine, numericLiteral: peg$parsenumericLiteral, nullishCoalescingExpression: peg$parsenullishCoalescingExpression, objectLiteral: peg$parseobjectLiteral, objectEntries: peg$parseobjectEntries, objectEntry: peg$parseobjectEntry, objectGetter: peg$parseobjectGetter, objectHiddenKey: peg$parseobjectHiddenKey, objectKey: peg$parseobjectKey, objectProperty: peg$parseobjectProperty, objectShorthandProperty: peg$parseobjectShorthandProperty, objectPublicKey: peg$parseobjectPublicKey, parenthesesArguments: peg$parseparenthesesArguments, path: peg$parsepath, pathArguments: peg$parsepathArguments, pathKey: peg$parsepathKey, pathSegment: peg$parsepathSegment, pathSegmentChar: peg$parsepathSegmentChar, pipelineExpression: peg$parsepipelineExpression, primary: peg$parseprimary, program: peg$parseprogram, protocolExpression: peg$parseprotocolExpression, qualifiedReference: peg$parsequalifiedReference, reference: peg$parsereference, relationalExpression: peg$parserelationalExpression, relationalOperator: peg$parserelationalOperator, rootDirectory: peg$parserootDirectory, scopeReference: peg$parsescopeReference, separator: peg$parseseparator, slashFollows: peg$parseslashFollows, shebang: peg$parseshebang, shiftExpression: peg$parseshiftExpression, shiftOperator: peg$parseshiftOperator, shorthandFunction: peg$parseshorthandFunction, singleArrow: peg$parsesingleArrow, singleLineComment: peg$parsesingleLineComment, singleQuoteString: peg$parsesingleQuoteString, singleQuoteStringChar: peg$parsesingleQuoteStringChar, spreadElement: peg$parsespreadElement, stringLiteral: peg$parsestringLiteral, templateDocument: peg$parsetemplateDocument, templateDocumentChar: peg$parsetemplateDocumentChar, templateDocumentText: peg$parsetemplateDocumentText, templateLiteral: peg$parsetemplateLiteral, templateLiteralChar: peg$parsetemplateLiteralChar, templateLiteralText: peg$parsetemplateLiteralText, templateSubstitution: peg$parsetemplateSubstitution, textChar: peg$parsetextChar, unaryExpression: peg$parseunaryExpression, unaryOperator: peg$parseunaryOperator, whitespace: peg$parsewhitespace, whitespaceWithNewLine: peg$parsewhitespaceWithNewLine };
206
206
  var peg$startRuleFunction = peg$parse__;
207
207
 
208
208
  var peg$c0 = "[";
@@ -791,22 +791,10 @@ function peg$parse(input, options) {
791
791
 
792
792
  s0 = peg$currPos;
793
793
  s1 = [];
794
- s2 = peg$parseinlineSpace();
795
- if (s2 === peg$FAILED) {
796
- s2 = peg$parsenewLine();
797
- if (s2 === peg$FAILED) {
798
- s2 = peg$parsecomment();
799
- }
800
- }
794
+ s2 = peg$parsewhitespace();
801
795
  while (s2 !== peg$FAILED) {
802
796
  s1.push(s2);
803
- s2 = peg$parseinlineSpace();
804
- if (s2 === peg$FAILED) {
805
- s2 = peg$parsenewLine();
806
- if (s2 === peg$FAILED) {
807
- s2 = peg$parsecomment();
808
- }
809
- }
797
+ s2 = peg$parsewhitespace();
810
798
  }
811
799
  peg$savedPos = s0;
812
800
  s1 = peg$f0();
@@ -823,13 +811,23 @@ function peg$parse(input, options) {
823
811
  if (s1 !== peg$FAILED) {
824
812
  s2 = [];
825
813
  s3 = peg$currPos;
826
- s4 = peg$parse__();
827
- s5 = peg$parseadditiveOperator();
828
- if (s5 !== peg$FAILED) {
829
- s6 = peg$parse__();
830
- s7 = peg$parsemultiplicativeExpression();
831
- if (s7 !== peg$FAILED) {
832
- s3 = [ s5, s7 ];
814
+ s4 = peg$parsewhitespace();
815
+ if (s4 !== peg$FAILED) {
816
+ s5 = peg$parseadditiveOperator();
817
+ if (s5 !== peg$FAILED) {
818
+ s6 = peg$parsewhitespace();
819
+ if (s6 !== peg$FAILED) {
820
+ s7 = peg$parsemultiplicativeExpression();
821
+ if (s7 !== peg$FAILED) {
822
+ s3 = [ s5, s7 ];
823
+ } else {
824
+ peg$currPos = s3;
825
+ s3 = peg$FAILED;
826
+ }
827
+ } else {
828
+ peg$currPos = s3;
829
+ s3 = peg$FAILED;
830
+ }
833
831
  } else {
834
832
  peg$currPos = s3;
835
833
  s3 = peg$FAILED;
@@ -841,13 +839,23 @@ function peg$parse(input, options) {
841
839
  while (s3 !== peg$FAILED) {
842
840
  s2.push(s3);
843
841
  s3 = peg$currPos;
844
- s4 = peg$parse__();
845
- s5 = peg$parseadditiveOperator();
846
- if (s5 !== peg$FAILED) {
847
- s6 = peg$parse__();
848
- s7 = peg$parsemultiplicativeExpression();
849
- if (s7 !== peg$FAILED) {
850
- s3 = [ s5, s7 ];
842
+ s4 = peg$parsewhitespace();
843
+ if (s4 !== peg$FAILED) {
844
+ s5 = peg$parseadditiveOperator();
845
+ if (s5 !== peg$FAILED) {
846
+ s6 = peg$parsewhitespace();
847
+ if (s6 !== peg$FAILED) {
848
+ s7 = peg$parsemultiplicativeExpression();
849
+ if (s7 !== peg$FAILED) {
850
+ s3 = [ s5, s7 ];
851
+ } else {
852
+ peg$currPos = s3;
853
+ s3 = peg$FAILED;
854
+ }
855
+ } else {
856
+ peg$currPos = s3;
857
+ s3 = peg$FAILED;
858
+ }
851
859
  } else {
852
860
  peg$currPos = s3;
853
861
  s3 = peg$FAILED;
@@ -1565,7 +1573,7 @@ function peg$parse(input, options) {
1565
1573
  }
1566
1574
  if (s4 !== peg$FAILED) {
1567
1575
  s5 = peg$parse__();
1568
- s6 = peg$parsepipelineExpression();
1576
+ s6 = peg$parseshorthandFunction();
1569
1577
  if (s6 !== peg$FAILED) {
1570
1578
  s7 = peg$parse__();
1571
1579
  if (input.charCodeAt(peg$currPos) === 58) {
@@ -1577,7 +1585,7 @@ function peg$parse(input, options) {
1577
1585
  }
1578
1586
  if (s8 !== peg$FAILED) {
1579
1587
  s9 = peg$parse__();
1580
- s10 = peg$parsepipelineExpression();
1588
+ s10 = peg$parseshorthandFunction();
1581
1589
  if (s10 !== peg$FAILED) {
1582
1590
  s2 = [ s6, s10 ];
1583
1591
  } else {
@@ -2863,13 +2871,23 @@ function peg$parse(input, options) {
2863
2871
  if (s1 !== peg$FAILED) {
2864
2872
  s2 = [];
2865
2873
  s3 = peg$currPos;
2866
- s4 = peg$parse__();
2867
- s5 = peg$parsemultiplicativeOperator();
2868
- if (s5 !== peg$FAILED) {
2869
- s6 = peg$parse__();
2870
- s7 = peg$parseexponentiationExpression();
2871
- if (s7 !== peg$FAILED) {
2872
- s3 = [ s5, s7 ];
2874
+ s4 = peg$parsewhitespace();
2875
+ if (s4 !== peg$FAILED) {
2876
+ s5 = peg$parsemultiplicativeOperator();
2877
+ if (s5 !== peg$FAILED) {
2878
+ s6 = peg$parsewhitespace();
2879
+ if (s6 !== peg$FAILED) {
2880
+ s7 = peg$parseexponentiationExpression();
2881
+ if (s7 !== peg$FAILED) {
2882
+ s3 = [ s5, s7 ];
2883
+ } else {
2884
+ peg$currPos = s3;
2885
+ s3 = peg$FAILED;
2886
+ }
2887
+ } else {
2888
+ peg$currPos = s3;
2889
+ s3 = peg$FAILED;
2890
+ }
2873
2891
  } else {
2874
2892
  peg$currPos = s3;
2875
2893
  s3 = peg$FAILED;
@@ -2881,13 +2899,23 @@ function peg$parse(input, options) {
2881
2899
  while (s3 !== peg$FAILED) {
2882
2900
  s2.push(s3);
2883
2901
  s3 = peg$currPos;
2884
- s4 = peg$parse__();
2885
- s5 = peg$parsemultiplicativeOperator();
2886
- if (s5 !== peg$FAILED) {
2887
- s6 = peg$parse__();
2888
- s7 = peg$parseexponentiationExpression();
2889
- if (s7 !== peg$FAILED) {
2890
- s3 = [ s5, s7 ];
2902
+ s4 = peg$parsewhitespace();
2903
+ if (s4 !== peg$FAILED) {
2904
+ s5 = peg$parsemultiplicativeOperator();
2905
+ if (s5 !== peg$FAILED) {
2906
+ s6 = peg$parsewhitespace();
2907
+ if (s6 !== peg$FAILED) {
2908
+ s7 = peg$parseexponentiationExpression();
2909
+ if (s7 !== peg$FAILED) {
2910
+ s3 = [ s5, s7 ];
2911
+ } else {
2912
+ peg$currPos = s3;
2913
+ s3 = peg$FAILED;
2914
+ }
2915
+ } else {
2916
+ peg$currPos = s3;
2917
+ s3 = peg$FAILED;
2918
+ }
2891
2919
  } else {
2892
2920
  peg$currPos = s3;
2893
2921
  s3 = peg$FAILED;
@@ -4683,6 +4711,20 @@ function peg$parse(input, options) {
4683
4711
  return s0;
4684
4712
  }
4685
4713
 
4714
+ function peg$parsewhitespace() {
4715
+ var s0;
4716
+
4717
+ s0 = peg$parseinlineSpace();
4718
+ if (s0 === peg$FAILED) {
4719
+ s0 = peg$parsenewLine();
4720
+ if (s0 === peg$FAILED) {
4721
+ s0 = peg$parsecomment();
4722
+ }
4723
+ }
4724
+
4725
+ return s0;
4726
+ }
4727
+
4686
4728
  function peg$parsewhitespaceWithNewLine() {
4687
4729
  var s0, s1, s2, s3, s4;
4688
4730
 
@@ -4841,6 +4883,7 @@ const peg$allowedStartRules = [
4841
4883
  "textChar",
4842
4884
  "unaryExpression",
4843
4885
  "unaryOperator",
4886
+ "whitespace",
4844
4887
  "whitespaceWithNewLine"
4845
4888
  ];
4846
4889
 
@@ -1,4 +1,9 @@
1
- import { isPlainObject, isUnpackable, merge } from "@weborigami/async-tree";
1
+ import {
2
+ isPlainObject,
3
+ isUnpackable,
4
+ merge,
5
+ Tree,
6
+ } from "@weborigami/async-tree";
2
7
 
3
8
  /**
4
9
  * Create a tree that's the result of merging the given trees.
@@ -28,8 +33,23 @@ export default async function mergeTrees(...trees) {
28
33
  );
29
34
 
30
35
  // If all trees are plain objects, return a plain object.
31
- if (unpacked.every((tree) => isPlainObject(tree))) {
32
- return Object.assign({}, ...unpacked);
36
+ if (
37
+ unpacked.every((tree) => isPlainObject(tree) && !Tree.isAsyncTree(tree))
38
+ ) {
39
+ // If we do an Object.assign, we'd evaluate getters.
40
+ // To avoid that, we'll merge property descriptors.
41
+ const result = {};
42
+ for (const obj of unpacked) {
43
+ const descriptors = Object.getOwnPropertyDescriptors(obj);
44
+ for (const [key, descriptor] of Object.entries(descriptors)) {
45
+ if (descriptor.value !== undefined) {
46
+ result[key] = descriptor.value;
47
+ } else {
48
+ Object.defineProperty(result, key, descriptor);
49
+ }
50
+ }
51
+ }
52
+ return result;
33
53
  }
34
54
 
35
55
  // If all trees are arrays, return an array.
@@ -433,6 +433,18 @@ describe("Origami parser", () => {
433
433
  [ops.scope, "slug"],
434
434
  ],
435
435
  ]);
436
+ assertParse("expression", "keys ~", [
437
+ [ops.builtin, "keys"],
438
+ [ops.homeDirectory],
439
+ ]);
440
+ assertParse("expression", "keys /Users/alice", [
441
+ [ops.builtin, "keys"],
442
+ [
443
+ ops.traverse,
444
+ [ops.rootDirectory, [ops.literal, "Users/"]],
445
+ [ops.literal, "alice"],
446
+ ],
447
+ ]);
436
448
 
437
449
  // Verify parser treatment of identifiers containing operators
438
450
  assertParse("expression", "a + b", [
@@ -1,50 +1,68 @@
1
- import { Tree } from "@weborigami/async-tree";
1
+ import { ObjectTree, Tree } from "@weborigami/async-tree";
2
2
  import assert from "node:assert";
3
3
  import { describe, test } from "node:test";
4
4
  import mergeTrees from "../../src/runtime/mergeTrees.js";
5
5
 
6
6
  describe("mergeTrees", () => {
7
- test("merges trees", async () => {
8
- const tree = await mergeTrees.call(
7
+ test("if all arguments are plain objects, result is a plain object", async () => {
8
+ let calledFoo = false;
9
+ let calledBar = false;
10
+ const result = await mergeTrees.call(
9
11
  null,
10
12
  {
11
13
  a: 1,
12
14
  b: 2,
15
+ get foo() {
16
+ calledFoo = true;
17
+ return true;
18
+ },
13
19
  },
14
20
  {
15
21
  b: 3,
16
22
  c: 4,
23
+ get bar() {
24
+ calledBar = true;
25
+ return true;
26
+ },
17
27
  }
18
28
  );
19
- // @ts-ignore
20
- assert.deepEqual(await Tree.plain(tree), {
29
+
30
+ // Shouldn't call functions when just getting keys
31
+ assert.deepEqual(Object.keys(result), ["a", "b", "foo", "c", "bar"]);
32
+ assert(!calledFoo);
33
+ assert(!calledBar);
34
+
35
+ assert.deepEqual(result, {
21
36
  a: 1,
22
37
  b: 3,
38
+ foo: true,
23
39
  c: 4,
40
+ bar: true,
24
41
  });
25
42
  });
26
43
 
27
- test("if all arguments are plain objects, result is a plain object", async () => {
28
- const result = await mergeTrees.call(
44
+ test("if all arguments are arrays, result is an array", async () => {
45
+ const result = await mergeTrees.call(null, [1, 2], [3, 4]);
46
+ assert.deepEqual(result, [1, 2, 3, 4]);
47
+ });
48
+
49
+ test("merges heterogenous arguments as trees", async () => {
50
+ const tree = await mergeTrees.call(
29
51
  null,
30
- {
52
+ new ObjectTree({
31
53
  a: 1,
32
54
  b: 2,
33
- },
55
+ }),
34
56
  {
35
57
  b: 3,
36
58
  c: 4,
37
59
  }
38
60
  );
39
- assert.deepEqual(result, {
61
+ // @ts-ignore
62
+ assert.deepEqual(await Tree.plain(tree), {
40
63
  a: 1,
41
64
  b: 3,
42
65
  c: 4,
43
66
  });
44
67
  });
45
-
46
- test("if all arguments are arrays, result is an array", async () => {
47
- const result = await mergeTrees.call(null, [1, 2], [3, 4]);
48
- assert.deepEqual(result, [1, 2, 3, 4]);
49
- });
50
68
  });