Skip to content

Commit 77f905e

Browse files
authored
Bring SDK Expression types into alignment with CLI + unit tests for Expression (#1227)
1 parent a54cd0b commit 77f905e

File tree

6 files changed

+327
-44
lines changed

6 files changed

+327
-44
lines changed

spec/fixtures/sources/commonjs-params/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ const functionsv2 = require("../../../../src/v2/index");
33
const params = require("../../../../src/params");
44

55
params.defineString("BORING");
6-
params.defineString("FOO", { input: { text: { validationRegex: "w+" } } });
7-
params.defineString("BAR", { default: "{{ params.FOO }}", label: "asdf" });
6+
const foo = params.defineString("FOO", { input: { text: { validationRegex: "w+" } } });
7+
const bar = params.defineString("BAR", { default: foo , label: "asdf" });
88
params.defineString("BAZ", { input: { select: { options: [{ value: "a" }, { value: "b" }] } } });
99

10-
params.defineInt("AN_INT", { default: 22 });
10+
params.defineInt("AN_INT", { default: bar.equals("qux").then(0, 1) });
1111
params.defineInt("ANOTHER_INT", {
1212
input: {
1313
select: {

spec/params/params.spec.ts

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
import { expect } from "chai";
2+
import * as params from "../../src/params";
3+
4+
describe("Params spec extraction", () => {
5+
it("converts Expressions in the param default to strings", () => {
6+
const bar = params.defineInt("BAR");
7+
expect(
8+
params.defineString("FOO", { default: bar.notEquals(22).then("asdf", "jkl;") }).toSpec()
9+
.default
10+
).to.equal(`{{ params.BAR != 22 ? "asdf" : "jkl;" }}`);
11+
});
12+
});
13+
14+
describe("Params value extraction", () => {
15+
beforeEach(() => {
16+
process.env.A_STRING = "asdf";
17+
process.env.SAME_STRING = "asdf";
18+
process.env.DIFF_STRING = "jkl;";
19+
process.env.AN_INT = "-11";
20+
process.env.SAME_INT = "-11";
21+
process.env.DIFF_INT = "22";
22+
process.env.PI = "3.14159";
23+
process.env.TRUE = "true";
24+
process.env.FALSE = "false";
25+
});
26+
27+
afterEach(() => {
28+
params.clearParams();
29+
delete process.env.A_STRING;
30+
delete process.env.SAME_STRING;
31+
delete process.env.DIFF_STRING;
32+
delete process.env.AN_INT;
33+
delete process.env.SAME_INT;
34+
delete process.env.DIFF_INT;
35+
delete process.env.TRUE;
36+
delete process.env.PI;
37+
delete process.env.TRUE;
38+
delete process.env.FALSE;
39+
});
40+
41+
it("extracts identity params from the environment", () => {
42+
const strParam = params.defineString("A_STRING");
43+
expect(strParam.value()).to.equal("asdf");
44+
45+
const intParam = params.defineInt("AN_INT");
46+
expect(intParam.value()).to.equal(-11);
47+
48+
const boolParam = params.defineBoolean("TRUE");
49+
expect(boolParam.value()).to.be.true;
50+
51+
const floatParam = params.defineFloat("PI");
52+
expect(floatParam.value()).to.equal(3.14159);
53+
54+
const falseParam = params.defineBoolean("FALSE");
55+
expect(falseParam.value()).to.be.false;
56+
});
57+
58+
it("falls back on the javascript zero values in case of type mismatch", () => {
59+
const stringToInt = params.defineInt("A_STRING");
60+
expect(stringToInt.value()).to.equal(0);
61+
62+
const stringToBool = params.defineBoolean("A_STRING");
63+
expect(stringToBool.value()).to.equal(false);
64+
});
65+
66+
it("returns a boolean value for Comparison expressions", () => {
67+
const str = params.defineString("A_STRING");
68+
const sameStr = params.defineString("SAME_STRING");
69+
const diffStr = params.defineString("DIFF_STRING");
70+
expect(str.equals(sameStr).value()).to.be.true;
71+
expect(str.equals("asdf").value()).to.be.true;
72+
expect(str.equals(diffStr).value()).to.be.false;
73+
expect(str.equals("jkl;").value()).to.be.false;
74+
expect(str.notEquals(diffStr).value()).to.be.true;
75+
expect(str.notEquals("jkl;").value()).to.be.true;
76+
expect(str.lessThan(diffStr).value()).to.be.true;
77+
expect(str.lessThan("jkl;").value()).to.be.true;
78+
expect(str.lessThanorEqualTo(diffStr).value()).to.be.true;
79+
expect(str.lessThanorEqualTo("jkl;").value()).to.be.true;
80+
expect(str.greaterThan(diffStr).value()).to.be.false;
81+
expect(str.greaterThan("jkl;").value()).to.be.false;
82+
expect(str.greaterThanOrEqualTo(diffStr).value()).to.be.false;
83+
expect(str.greaterThanOrEqualTo("jkl;").value()).to.be.false;
84+
85+
const int = params.defineInt("AN_INT");
86+
const sameInt = params.defineInt("SAME_INT");
87+
const diffInt = params.defineInt("DIFF_INT");
88+
expect(int.equals(sameInt).value()).to.be.true;
89+
expect(int.equals(-11).value()).to.be.true;
90+
expect(int.equals(diffInt).value()).to.be.false;
91+
expect(int.equals(22).value()).to.be.false;
92+
93+
expect(int.notEquals(diffInt).value()).to.be.true;
94+
expect(int.notEquals(22).value()).to.be.true;
95+
expect(int.greaterThan(diffInt).value()).to.be.false;
96+
expect(int.greaterThan(22).value()).to.be.false;
97+
expect(int.greaterThanOrEqualTo(diffInt).value()).to.be.false;
98+
expect(int.greaterThanOrEqualTo(22).value()).to.be.false;
99+
expect(int.lessThan(diffInt).value()).to.be.true;
100+
expect(int.lessThan(22).value()).to.be.true;
101+
expect(int.lessThanorEqualTo(diffInt).value()).to.be.true;
102+
expect(int.lessThanorEqualTo(22).value()).to.be.true;
103+
});
104+
105+
it("can use all the comparison operators when explicitly requested", () => {
106+
const jkl = params.defineString("DIFF_STRING");
107+
expect(jkl.cmp(">", "asdf").value()).to.be.true;
108+
expect(jkl.cmp(">", "jkl;").value()).to.be.false;
109+
expect(jkl.cmp(">", "qwerty").value()).to.be.false;
110+
expect(jkl.cmp(">=", "asdf").value()).to.be.true;
111+
expect(jkl.cmp(">=", "jkl;").value()).to.be.true;
112+
expect(jkl.cmp(">=", "qwerty").value()).to.be.false;
113+
expect(jkl.cmp("<", "asdf").value()).to.be.false;
114+
expect(jkl.cmp("<", "jkl;").value()).to.be.false;
115+
expect(jkl.cmp("<", "qwerty").value()).to.be.true;
116+
expect(jkl.cmp("<=", "asdf").value()).to.be.false;
117+
expect(jkl.cmp("<=", "jkl;").value()).to.be.true;
118+
expect(jkl.cmp("<=", "qwerty").value()).to.be.true;
119+
120+
const twentytwo = params.defineInt("DIFF_INT");
121+
expect(twentytwo.cmp(">", 11).value()).to.be.true;
122+
expect(twentytwo.cmp(">", 22).value()).to.be.false;
123+
expect(twentytwo.cmp(">", 33).value()).to.be.false;
124+
expect(twentytwo.cmp(">=", 11).value()).to.be.true;
125+
expect(twentytwo.cmp(">=", 22).value()).to.be.true;
126+
expect(twentytwo.cmp(">=", 33).value()).to.be.false;
127+
expect(twentytwo.cmp("<", 11).value()).to.be.false;
128+
expect(twentytwo.cmp("<", 22).value()).to.be.false;
129+
expect(twentytwo.cmp("<", 33).value()).to.be.true;
130+
expect(twentytwo.cmp("<=", 11).value()).to.be.false;
131+
expect(twentytwo.cmp("<=", 22).value()).to.be.true;
132+
expect(twentytwo.cmp("<=", 33).value()).to.be.true;
133+
134+
const trueParam = params.defineBoolean("TRUE");
135+
expect(trueParam.cmp(">", true).value()).to.be.false;
136+
expect(trueParam.cmp(">", false).value()).to.be.true;
137+
expect(trueParam.cmp(">=", true).value()).to.be.true;
138+
expect(trueParam.cmp(">=", false).value()).to.be.true;
139+
expect(trueParam.cmp("<", true).value()).to.be.false;
140+
expect(trueParam.cmp("<", false).value()).to.be.false;
141+
expect(trueParam.cmp("<=", true).value()).to.be.true;
142+
expect(trueParam.cmp("<=", false).value()).to.be.false;
143+
});
144+
145+
it("can select the output of a ternary expression based on the comparison", () => {
146+
const trueExpr = params.defineString("A_STRING").equals(params.defineString("SAME_STRING"));
147+
expect(trueExpr.then(1, 0).value()).to.equal(1);
148+
const falseExpr = params.defineInt("AN_INT").equals(params.defineInt("DIFF_INT"));
149+
expect(falseExpr.then(1, 0).value()).to.equal(0);
150+
151+
const twentytwo = params.defineInt("DIFF_INT");
152+
expect(trueExpr.then(twentytwo, 0).value()).to.equal(22);
153+
expect(falseExpr.then(1, twentytwo).value()).to.equal(22);
154+
});
155+
});
156+
157+
describe("Params as CEL", () => {
158+
it("identity expressions", () => {
159+
expect(params.defineString("FOO").toCEL()).to.equal("{{ params.FOO }}");
160+
expect(params.defineInt("FOO").toCEL()).to.equal("{{ params.FOO }}");
161+
expect(params.defineBoolean("FOO").toCEL()).to.equal("{{ params.FOO }}");
162+
});
163+
164+
it("comparison expressions", () => {
165+
expect(params.defineString("FOO").equals(params.defineString("BAR")).toCEL()).to.equal(
166+
"{{ params.FOO == params.BAR }}"
167+
);
168+
expect(params.defineString("FOO").cmp("==", params.defineString("BAR")).toCEL()).to.equal(
169+
"{{ params.FOO == params.BAR }}"
170+
);
171+
expect(params.defineString("FOO").cmp("!=", params.defineString("BAR")).toCEL()).to.equal(
172+
"{{ params.FOO != params.BAR }}"
173+
);
174+
expect(params.defineString("FOO").cmp(">", params.defineString("BAR")).toCEL()).to.equal(
175+
"{{ params.FOO > params.BAR }}"
176+
);
177+
expect(params.defineString("FOO").cmp(">=", params.defineString("BAR")).toCEL()).to.equal(
178+
"{{ params.FOO >= params.BAR }}"
179+
);
180+
expect(params.defineString("FOO").cmp("<", params.defineString("BAR")).toCEL()).to.equal(
181+
"{{ params.FOO < params.BAR }}"
182+
);
183+
expect(params.defineString("FOO").cmp("<=", params.defineString("BAR")).toCEL()).to.equal(
184+
"{{ params.FOO <= params.BAR }}"
185+
);
186+
187+
expect(params.defineString("FOO").equals("BAR").toCEL()).to.equal('{{ params.FOO == "BAR" }}');
188+
expect(params.defineString("FOO").cmp("==", "BAR").toCEL()).to.equal(
189+
'{{ params.FOO == "BAR" }}'
190+
);
191+
expect(params.defineString("FOO").cmp("!=", "BAR").toCEL()).to.equal(
192+
'{{ params.FOO != "BAR" }}'
193+
);
194+
expect(params.defineString("FOO").cmp(">", "BAR").toCEL()).to.equal('{{ params.FOO > "BAR" }}');
195+
expect(params.defineString("FOO").cmp(">=", "BAR").toCEL()).to.equal(
196+
'{{ params.FOO >= "BAR" }}'
197+
);
198+
expect(params.defineString("FOO").cmp("<", "BAR").toCEL()).to.equal('{{ params.FOO < "BAR" }}');
199+
expect(params.defineString("FOO").cmp("<=", "BAR").toCEL()).to.equal(
200+
'{{ params.FOO <= "BAR" }}'
201+
);
202+
203+
expect(params.defineInt("FOO").equals(-11).toCEL()).to.equal("{{ params.FOO == -11 }}");
204+
expect(params.defineInt("FOO").cmp("==", -11).toCEL()).to.equal("{{ params.FOO == -11 }}");
205+
expect(params.defineInt("FOO").cmp("!=", -11).toCEL()).to.equal("{{ params.FOO != -11 }}");
206+
expect(params.defineInt("FOO").cmp(">", -11).toCEL()).to.equal("{{ params.FOO > -11 }}");
207+
expect(params.defineInt("FOO").cmp(">=", -11).toCEL()).to.equal("{{ params.FOO >= -11 }}");
208+
expect(params.defineInt("FOO").cmp("<", -11).toCEL()).to.equal("{{ params.FOO < -11 }}");
209+
expect(params.defineInt("FOO").cmp("<=", -11).toCEL()).to.equal("{{ params.FOO <= -11 }}");
210+
});
211+
212+
it("ternary expressions", () => {
213+
const booleanExpr = params.defineBoolean("BOOL");
214+
const cmpExpr = params.defineInt("A").cmp("!=", params.defineInt("B"));
215+
216+
expect(booleanExpr.then("asdf", "jkl;").toCEL()).to.equal(
217+
'{{ params.BOOL ? "asdf" : "jkl;" }}'
218+
);
219+
expect(booleanExpr.then(-11, 22).toCEL()).to.equal("{{ params.BOOL ? -11 : 22 }}");
220+
expect(booleanExpr.then(false, true).toCEL()).to.equal("{{ params.BOOL ? false : true }}");
221+
expect(
222+
booleanExpr.then(params.defineString("FOO"), params.defineString("BAR")).toCEL()
223+
).to.equal("{{ params.BOOL ? params.FOO : params.BAR }}");
224+
expect(cmpExpr.then("asdf", "jkl;").toCEL()).to.equal(
225+
'{{ params.A != params.B ? "asdf" : "jkl;" }}'
226+
);
227+
expect(cmpExpr.then(-11, 22).toCEL()).to.equal("{{ params.A != params.B ? -11 : 22 }}");
228+
expect(cmpExpr.then(false, true).toCEL()).to.equal("{{ params.A != params.B ? false : true }}");
229+
expect(cmpExpr.then(params.defineString("FOO"), params.defineString("BAR")).toCEL()).to.equal(
230+
"{{ params.A != params.B ? params.FOO : params.BAR }}"
231+
);
232+
});
233+
});

spec/runtime/loader.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ describe("loadStack", () => {
331331
select: { options: [{ value: "a" }, { value: "b" }] },
332332
},
333333
},
334-
{ name: "AN_INT", type: "int", default: 22 },
334+
{ name: "AN_INT", type: "int", default: `{{ params.BAR == "qux" ? 0 : 1 }}` },
335335
{
336336
name: "ANOTHER_INT",
337337
type: "int",

0 commit comments

Comments
 (0)