@saltcorn/data 1.5.4 → 1.5.5

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.
Files changed (149) hide show
  1. package/package.json +8 -8
  2. package/dist/migrations/202603101553.d.ts +0 -4
  3. package/dist/migrations/202603101553.d.ts.map +0 -1
  4. package/dist/migrations/202603101553.js +0 -22
  5. package/dist/migrations/202603101553.js.map +0 -1
  6. package/dist/mobile-mocks/node/assert.d.ts +0 -1
  7. package/dist/mobile-mocks/node/assert.d.ts.map +0 -1
  8. package/dist/mobile-mocks/node/assert.js +0 -2
  9. package/dist/mobile-mocks/node/assert.js.map +0 -1
  10. package/dist/mobile-mocks/npm/apns2.d.ts +0 -1
  11. package/dist/mobile-mocks/npm/apns2.d.ts.map +0 -1
  12. package/dist/mobile-mocks/npm/apns2.js +0 -2
  13. package/dist/mobile-mocks/npm/apns2.js.map +0 -1
  14. package/dist/mobile-mocks/npm/vm2.d.ts +0 -1
  15. package/dist/mobile-mocks/npm/vm2.d.ts.map +0 -1
  16. package/dist/mobile-mocks/npm/vm2.js +0 -2
  17. package/dist/mobile-mocks/npm/vm2.js.map +0 -1
  18. package/dist/mobile-mocks/npm/xml2js.d.ts +0 -1
  19. package/dist/mobile-mocks/npm/xml2js.d.ts.map +0 -1
  20. package/dist/mobile-mocks/npm/xml2js.js +0 -2
  21. package/dist/mobile-mocks/npm/xml2js.js.map +0 -1
  22. package/dist/tests/actions.test.d.ts +0 -2
  23. package/dist/tests/actions.test.d.ts.map +0 -1
  24. package/dist/tests/actions.test.js +0 -936
  25. package/dist/tests/actions.test.js.map +0 -1
  26. package/dist/tests/auth.test.d.ts +0 -2
  27. package/dist/tests/auth.test.d.ts.map +0 -1
  28. package/dist/tests/auth.test.js +0 -824
  29. package/dist/tests/auth.test.js.map +0 -1
  30. package/dist/tests/auxtest.test.d.ts +0 -2
  31. package/dist/tests/auxtest.test.d.ts.map +0 -1
  32. package/dist/tests/auxtest.test.js +0 -562
  33. package/dist/tests/auxtest.test.js.map +0 -1
  34. package/dist/tests/base.test.d.ts +0 -2
  35. package/dist/tests/base.test.d.ts.map +0 -1
  36. package/dist/tests/base.test.js +0 -30
  37. package/dist/tests/base.test.js.map +0 -1
  38. package/dist/tests/calc.test.d.ts +0 -2
  39. package/dist/tests/calc.test.d.ts.map +0 -1
  40. package/dist/tests/calc.test.js +0 -1081
  41. package/dist/tests/calc.test.js.map +0 -1
  42. package/dist/tests/composite_pk.test.d.ts +0 -2
  43. package/dist/tests/composite_pk.test.d.ts.map +0 -1
  44. package/dist/tests/composite_pk.test.js +0 -98
  45. package/dist/tests/composite_pk.test.js.map +0 -1
  46. package/dist/tests/config.test.d.ts +0 -2
  47. package/dist/tests/config.test.d.ts.map +0 -1
  48. package/dist/tests/config.test.js +0 -86
  49. package/dist/tests/config.test.js.map +0 -1
  50. package/dist/tests/db.test.d.ts +0 -2
  51. package/dist/tests/db.test.d.ts.map +0 -1
  52. package/dist/tests/db.test.js +0 -178
  53. package/dist/tests/db.test.js.map +0 -1
  54. package/dist/tests/discover.test.d.ts +0 -2
  55. package/dist/tests/discover.test.d.ts.map +0 -1
  56. package/dist/tests/discover.test.js +0 -245
  57. package/dist/tests/discover.test.js.map +0 -1
  58. package/dist/tests/edit.test.d.ts +0 -2
  59. package/dist/tests/edit.test.d.ts.map +0 -1
  60. package/dist/tests/edit.test.js +0 -1161
  61. package/dist/tests/edit.test.js.map +0 -1
  62. package/dist/tests/email.test.d.ts +0 -2
  63. package/dist/tests/email.test.d.ts.map +0 -1
  64. package/dist/tests/email.test.js +0 -255
  65. package/dist/tests/email.test.js.map +0 -1
  66. package/dist/tests/exact_views.test.d.ts +0 -2
  67. package/dist/tests/exact_views.test.d.ts.map +0 -1
  68. package/dist/tests/exact_views.test.js +0 -1363
  69. package/dist/tests/exact_views.test.js.map +0 -1
  70. package/dist/tests/field.test.d.ts +0 -2
  71. package/dist/tests/field.test.d.ts.map +0 -1
  72. package/dist/tests/field.test.js +0 -588
  73. package/dist/tests/field.test.js.map +0 -1
  74. package/dist/tests/fieldviews.test.d.ts +0 -2
  75. package/dist/tests/fieldviews.test.d.ts.map +0 -1
  76. package/dist/tests/fieldviews.test.js +0 -74
  77. package/dist/tests/fieldviews.test.js.map +0 -1
  78. package/dist/tests/file.test.d.ts +0 -2
  79. package/dist/tests/file.test.d.ts.map +0 -1
  80. package/dist/tests/file.test.js +0 -148
  81. package/dist/tests/file.test.js.map +0 -1
  82. package/dist/tests/filter.test.d.ts +0 -2
  83. package/dist/tests/filter.test.d.ts.map +0 -1
  84. package/dist/tests/filter.test.js +0 -496
  85. package/dist/tests/filter.test.js.map +0 -1
  86. package/dist/tests/form.test.d.ts +0 -2
  87. package/dist/tests/form.test.d.ts.map +0 -1
  88. package/dist/tests/form.test.js +0 -264
  89. package/dist/tests/form.test.js.map +0 -1
  90. package/dist/tests/list.test.d.ts +0 -2
  91. package/dist/tests/list.test.d.ts.map +0 -1
  92. package/dist/tests/list.test.js +0 -1037
  93. package/dist/tests/list.test.js.map +0 -1
  94. package/dist/tests/models.test.d.ts +0 -2
  95. package/dist/tests/models.test.d.ts.map +0 -1
  96. package/dist/tests/models.test.js +0 -417
  97. package/dist/tests/models.test.js.map +0 -1
  98. package/dist/tests/page.test.d.ts +0 -2
  99. package/dist/tests/page.test.d.ts.map +0 -1
  100. package/dist/tests/page.test.js +0 -26
  101. package/dist/tests/page.test.js.map +0 -1
  102. package/dist/tests/page_group.test.d.ts +0 -2
  103. package/dist/tests/page_group.test.d.ts.map +0 -1
  104. package/dist/tests/page_group.test.js +0 -51
  105. package/dist/tests/page_group.test.js.map +0 -1
  106. package/dist/tests/plugin.test.d.ts +0 -2
  107. package/dist/tests/plugin.test.d.ts.map +0 -1
  108. package/dist/tests/plugin.test.js +0 -60
  109. package/dist/tests/plugin.test.js.map +0 -1
  110. package/dist/tests/show.test.d.ts +0 -2
  111. package/dist/tests/show.test.d.ts.map +0 -1
  112. package/dist/tests/show.test.js +0 -561
  113. package/dist/tests/show.test.js.map +0 -1
  114. package/dist/tests/state.test.d.ts +0 -2
  115. package/dist/tests/state.test.d.ts.map +0 -1
  116. package/dist/tests/state.test.js +0 -82
  117. package/dist/tests/state.test.js.map +0 -1
  118. package/dist/tests/table.test.d.ts +0 -2
  119. package/dist/tests/table.test.d.ts.map +0 -1
  120. package/dist/tests/table.test.js +0 -2717
  121. package/dist/tests/table.test.js.map +0 -1
  122. package/dist/tests/table_history.test.d.ts +0 -2
  123. package/dist/tests/table_history.test.d.ts.map +0 -1
  124. package/dist/tests/table_history.test.js +0 -413
  125. package/dist/tests/table_history.test.js.map +0 -1
  126. package/dist/tests/tag.test.d.ts +0 -2
  127. package/dist/tests/tag.test.d.ts.map +0 -1
  128. package/dist/tests/tag.test.js +0 -97
  129. package/dist/tests/tag.test.js.map +0 -1
  130. package/dist/tests/user.test.d.ts +0 -2
  131. package/dist/tests/user.test.d.ts.map +0 -1
  132. package/dist/tests/user.test.js +0 -441
  133. package/dist/tests/user.test.js.map +0 -1
  134. package/dist/tests/view.test.d.ts +0 -2
  135. package/dist/tests/view.test.d.ts.map +0 -1
  136. package/dist/tests/view.test.js +0 -699
  137. package/dist/tests/view.test.js.map +0 -1
  138. package/dist/tests/workflow.test.d.ts +0 -2
  139. package/dist/tests/workflow.test.d.ts.map +0 -1
  140. package/dist/tests/workflow.test.js +0 -303
  141. package/dist/tests/workflow.test.js.map +0 -1
  142. package/dist/tests/workflow_run.test.d.ts +0 -2
  143. package/dist/tests/workflow_run.test.d.ts.map +0 -1
  144. package/dist/tests/workflow_run.test.js +0 -922
  145. package/dist/tests/workflow_run.test.js.map +0 -1
  146. package/dist/viewable_fields.d.ts +0 -227
  147. package/dist/viewable_fields.d.ts.map +0 -1
  148. package/dist/viewable_fields.js +0 -1928
  149. package/dist/viewable_fields.js.map +0 -1
@@ -1,1081 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const table_1 = __importDefault(require("../models/table"));
7
- const field_1 = __importDefault(require("../models/field"));
8
- const trigger_1 = __importDefault(require("../models/trigger"));
9
- const db_1 = __importDefault(require("../db"));
10
- const { getState } = require("../db/state");
11
- const mocks_1 = __importDefault(require("./mocks"));
12
- const { plugin_with_routes, sleep } = mocks_1.default;
13
- const expression_1 = __importDefault(require("../models/expression"));
14
- const { eval_expression, get_expression_function, transform_for_async, expressionValidator, jsexprToWhere, jsexprToSQL, freeVariables, freeVariablesInInterpolation, recalculate_for_stored, } = expression_1.default;
15
- const internal_1 = require("@saltcorn/db-common/internal");
16
- const assertions_1 = require("./assertions");
17
- const globals_1 = require("@jest/globals");
18
- const utils_1 = __importDefault(require("../utils"));
19
- const { interpolate, mergeIntoWhere } = utils_1.default;
20
- getState().registerPlugin("base", require("../base-plugin"));
21
- (0, globals_1.afterAll)(db_1.default.close);
22
- jest.setTimeout(30000);
23
- (0, globals_1.beforeAll)(async () => {
24
- await require("../db/reset_schema")();
25
- await require("../db/fixtures")();
26
- });
27
- (0, globals_1.describe)("eval_expression", () => {
28
- (0, globals_1.it)("simply evaluates", () => {
29
- (0, globals_1.expect)(eval_expression("x+2", { x: 5 })).toBe(7);
30
- });
31
- (0, globals_1.it)("uses code pages", async () => {
32
- await getState().setConfig("function_code_pages", {
33
- mypage: `function add58(x){return x+58}`,
34
- });
35
- await getState().refresh_codepages();
36
- (0, globals_1.expect)(eval_expression("add58(x)", { x: 5 })).toBe(63);
37
- });
38
- (0, globals_1.it)("evaluates with null row", () => {
39
- (0, globals_1.expect)(eval_expression("5+2", undefined)).toBe(7);
40
- (0, globals_1.expect)(eval_expression("5+2", null)).toBe(7);
41
- (0, globals_1.expect)(eval_expression("5+2")).toBe(7);
42
- });
43
- });
44
- (0, globals_1.describe)("calculated", () => {
45
- (0, globals_1.it)("how to use functions", () => {
46
- const f = new Function("{x,y}", "return x+y");
47
- (0, globals_1.expect)(f({ x: 1, y: 2 })).toBe(3);
48
- });
49
- (0, globals_1.it)("build table", async () => {
50
- const table = await table_1.default.create("withcalcs");
51
- await field_1.default.create({
52
- table,
53
- label: "x",
54
- type: "Integer",
55
- });
56
- await field_1.default.create({
57
- table,
58
- label: "y",
59
- type: "Integer",
60
- });
61
- const fz = await field_1.default.create({
62
- table,
63
- label: "z",
64
- type: "Integer",
65
- calculated: true,
66
- expression: "x+y",
67
- });
68
- const fzid = await field_1.default.create({
69
- table,
70
- label: "zid",
71
- type: "Integer",
72
- calculated: true,
73
- expression: "x+y+id",
74
- });
75
- const fw = await field_1.default.create({
76
- table,
77
- label: "w",
78
- type: "Integer",
79
- calculated: true,
80
- expression: "y-x",
81
- stored: true,
82
- });
83
- const fields = table.getFields();
84
- const fzf = get_expression_function(fz.expression, fields);
85
- (0, globals_1.expect)(fzf({ x: 4, y: 2 })).toBe(6);
86
- await table.insertRow({ x: 5, y: 8 });
87
- const [row] = await table.getRows();
88
- (0, globals_1.expect)(row.z).toBe(13);
89
- (0, globals_1.expect)(row.zid).toBe(14);
90
- (0, globals_1.expect)(row.w).toBe(3);
91
- const [row1] = await table.getJoinedRows();
92
- (0, globals_1.expect)(row1.z).toBe(13);
93
- (0, globals_1.expect)(row1.w).toBe(3);
94
- const row0 = await table.getRow({});
95
- (0, assertions_1.assertIsSet)(row0);
96
- (0, globals_1.expect)(row0.z).toBe(13);
97
- (0, globals_1.expect)(row0.w).toBe(3);
98
- await table.updateRow({ y: 9 }, row.id);
99
- const row2 = await table.getRow({});
100
- (0, assertions_1.assertIsSet)(row2);
101
- (0, globals_1.expect)(row2.z).toBe(14);
102
- (0, globals_1.expect)(row2.w).toBe(4);
103
- await table.update({ versioned: true });
104
- const newid = await table.insertRow({ x: 2, y: 4 });
105
- const row3 = await table.getRow({ id: newid });
106
- (0, assertions_1.assertIsSet)(row3);
107
- (0, globals_1.expect)(row3.z).toBe(6);
108
- (0, globals_1.expect)(row3.w).toBe(2);
109
- await fz.delete();
110
- await fw.delete();
111
- });
112
- (0, globals_1.it)("cannot exit", async () => {
113
- const table = await table_1.default.create("withcalcs2");
114
- await field_1.default.create({
115
- table,
116
- label: "x",
117
- type: "Integer",
118
- });
119
- const fz = await field_1.default.create({
120
- table,
121
- label: "z",
122
- type: "Integer",
123
- calculated: true,
124
- expression: "process.exit(0)",
125
- });
126
- const fields = table.getFields();
127
- (0, assertions_1.assertIsSet)(fz.expression);
128
- const fzf = get_expression_function(fz.expression, fields);
129
- let error;
130
- try {
131
- fzf({ x: 4 });
132
- }
133
- catch (e) {
134
- error = e;
135
- }
136
- (0, globals_1.expect)(error.constructor.name).toContain("Error");
137
- });
138
- (0, globals_1.it)("stored existing", async () => {
139
- const table = await table_1.default.create("withcalcs3");
140
- await field_1.default.create({
141
- table,
142
- label: "x",
143
- type: "Integer",
144
- });
145
- await field_1.default.create({
146
- table,
147
- label: "y",
148
- type: "Integer",
149
- });
150
- const id1 = await table.insertRow({ x: 6, y: 9 });
151
- for (let index = 0; index < 25; index++) {
152
- await table.insertRow({ x: 1, y: 1 });
153
- }
154
- const id201 = await table.insertRow({ x: 7, y: 2 });
155
- const fz = await field_1.default.create({
156
- table,
157
- label: "z",
158
- type: "Integer",
159
- calculated: true,
160
- expression: "x+y",
161
- stored: true,
162
- });
163
- const row0 = await table.getRow({ id: id1 });
164
- (0, assertions_1.assertIsSet)(row0);
165
- (0, globals_1.expect)(row0.x).toBe(6);
166
- (0, globals_1.expect)([null, 15]).toContain(row0.z);
167
- const row201 = await table.getRow({ id: id201 });
168
- (0, assertions_1.assertIsSet)(row201);
169
- (0, globals_1.expect)(row201.x).toBe(7);
170
- (0, globals_1.expect)([null, 9]).toContain(row201.z);
171
- await sleep(3000);
172
- const row1 = await table.getRow({ id: id1 });
173
- (0, assertions_1.assertIsSet)(row1);
174
- (0, globals_1.expect)(row1.x).toBe(6);
175
- (0, globals_1.expect)(row1.z).toBe(15);
176
- const rowlast = await table.getRow({ id: id201 });
177
- (0, assertions_1.assertIsSet)(rowlast);
178
- (0, globals_1.expect)(rowlast.z).toBe(9);
179
- (0, globals_1.expect)(rowlast.x).toBe(7);
180
- });
181
- (0, globals_1.it)("use supplied function", async () => {
182
- const table = await table_1.default.create("withcalcs5");
183
- await field_1.default.create({
184
- table,
185
- label: "x",
186
- type: "Integer",
187
- });
188
- getState().registerPlugin("mock_plugin", plugin_with_routes());
189
- await field_1.default.create({
190
- table,
191
- label: "z",
192
- type: "Integer",
193
- calculated: true,
194
- expression: "add3(x)",
195
- });
196
- await field_1.default.create({
197
- table,
198
- label: "w",
199
- type: "Integer",
200
- calculated: true,
201
- expression: "add5(x)",
202
- });
203
- await table.insertRow({ x: 13 });
204
- const row0 = await table.getRow({});
205
- (0, assertions_1.assertIsSet)(row0);
206
- (0, globals_1.expect)(row0.z).toBe(16);
207
- (0, globals_1.expect)(row0.w).toBe(18);
208
- });
209
- (0, globals_1.it)("use supplied function", async () => {
210
- const table = await table_1.default.create("withcalcs7");
211
- await field_1.default.create({
212
- table,
213
- label: "x",
214
- type: "Integer",
215
- });
216
- getState().registerPlugin("mock_plugin", plugin_with_routes());
217
- const xres = transform_for_async("add5(1)+ add3(4)+asyncAdd2(x)", getState().functions);
218
- (0, globals_1.expect)(xres).toEqual({
219
- expr_string: "add5(1) + add3(4) + await asyncAdd2(x)",
220
- isAsync: true,
221
- });
222
- await field_1.default.create({
223
- table,
224
- label: "z",
225
- type: "Integer",
226
- calculated: true,
227
- expression: "1+asyncAdd2(x)",
228
- stored: true,
229
- });
230
- await field_1.default.create({
231
- table,
232
- label: "td",
233
- type: "Date",
234
- calculated: true,
235
- expression: "today(-5)",
236
- stored: true,
237
- });
238
- const id = await table.insertRow({ x: 14 });
239
- const row0 = await table.getRow({});
240
- (0, assertions_1.assertIsSet)(row0);
241
- (0, globals_1.expect)(row0.z).toBe(17);
242
- await table.updateRow({ x: 15 }, id);
243
- const rows = await table.getRows({});
244
- (0, globals_1.expect)(rows[0].z).toBe(18);
245
- if (!db_1.default.isSQLite)
246
- (0, globals_1.expect)(rows[0].td instanceof Date).toBe(true);
247
- });
248
- });
249
- (0, globals_1.describe)("single joinfields in stored calculated fields", () => {
250
- (0, globals_1.it)("creates", async () => {
251
- const patients = table_1.default.findOne({ name: "patients" });
252
- (0, assertions_1.assertIsSet)(patients);
253
- const f = await field_1.default.create({
254
- table: patients,
255
- label: "favpages",
256
- type: "Integer",
257
- calculated: true,
258
- expression: "favbook?.pages",
259
- stored: true,
260
- });
261
- (0, globals_1.expect)(f.attributes.calc_joinfields.length).toBe(1);
262
- (0, globals_1.expect)(f.attributes.calc_joinfields[0].targetTable).toBe("books");
263
- (0, globals_1.expect)(f.attributes.calc_joinfields[0].field).toBe("favbook");
264
- });
265
- (0, globals_1.it)("updates", async () => {
266
- const patients = table_1.default.findOne({ name: "patients" });
267
- (0, assertions_1.assertIsSet)(patients);
268
- const bookRows = await patients.getRows({});
269
- for (const row of bookRows) {
270
- await patients.updateRow({}, row.id);
271
- }
272
- });
273
- (0, globals_1.it)("check", async () => {
274
- const patients = table_1.default.findOne({ name: "patients" });
275
- (0, assertions_1.assertIsSet)(patients);
276
- const bookrow = await patients.getRow({ id: 1 });
277
- (0, globals_1.expect)(bookrow?.favpages).toBe(967);
278
- });
279
- (0, globals_1.it)("changes", async () => {
280
- const patients = table_1.default.findOne({ name: "patients" });
281
- (0, assertions_1.assertIsSet)(patients);
282
- await patients.updateRow({ favbook: 2 }, 1);
283
- const bookrow = await patients.getRow({ id: 1 });
284
- (0, globals_1.expect)(bookrow?.favpages).toBe(728);
285
- });
286
- (0, globals_1.it)("insert", async () => {
287
- const patients = table_1.default.findOne({ name: "patients" });
288
- (0, assertions_1.assertIsSet)(patients);
289
- const hid = await patients.insertRow({ name: "Herman Smith", favbook: 1 });
290
- const hrow = await patients.getRow({ id: hid });
291
- (0, globals_1.expect)(hrow?.favpages).toBe(967);
292
- //expect(bookrow?.favpages).toBe(967);
293
- });
294
- (0, globals_1.it)("recalculates", async () => {
295
- const patients = table_1.default.findOne({ name: "patients" });
296
- (0, assertions_1.assertIsSet)(patients);
297
- const patient = await patients.getRow({ id: 1 });
298
- (0, assertions_1.assertIsSet)(patient);
299
- (0, globals_1.expect)(patient.favbook).toBe(2);
300
- (0, globals_1.expect)(patient.favpages).toBe(728);
301
- const books = table_1.default.findOne({ name: "books" });
302
- (0, assertions_1.assertIsSet)(books);
303
- const book = await books.getRow({ id: patient.favbook });
304
- (0, assertions_1.assertIsSet)(book);
305
- (0, globals_1.expect)(book.pages).toBe(728);
306
- await books.updateRow({ pages: 729 }, book.id);
307
- //await recalculate_for_stored(patients, { id: 1 });
308
- const patient1 = await patients.getRow({ id: 1 });
309
- (0, assertions_1.assertIsSet)(patient1);
310
- (0, globals_1.expect)(patient1.favpages).toBe(729);
311
- await books.updateRow({ pages: 728 }, book.id);
312
- });
313
- (0, globals_1.it)("add reciprocal field for looped updates ", async () => {
314
- const books = table_1.default.findOne({ name: "books" });
315
- (0, assertions_1.assertIsSet)(books);
316
- await field_1.default.create({
317
- table: books,
318
- label: "Number of fans",
319
- type: "Integer",
320
- calculated: true,
321
- expression: "__aggregation",
322
- attributes: {
323
- aggregate: "Count",
324
- aggwhere: "",
325
- agg_field: "id@Integer",
326
- agg_relation: "patients.favbook",
327
- table: "patients",
328
- ref: "favbook",
329
- },
330
- stored: true,
331
- });
332
- await field_1.default.create({
333
- table: books,
334
- label: "idp1",
335
- type: "Integer",
336
- calculated: true,
337
- expression: "id+1",
338
- stored: false,
339
- });
340
- await field_1.default.create({
341
- table: books,
342
- label: "storedsum",
343
- type: "Integer",
344
- calculated: true,
345
- expression: "number_of_fans+idp1",
346
- stored: true,
347
- });
348
- });
349
- (0, globals_1.it)("change value without triggering infinite loop", async () => {
350
- const patients = table_1.default.findOne({ name: "patients" });
351
- (0, assertions_1.assertIsSet)(patients);
352
- const patient = await patients.getRow({ id: 1 });
353
- (0, assertions_1.assertIsSet)(patient);
354
- const books = table_1.default.findOne({ name: "books" });
355
- (0, assertions_1.assertIsSet)(books);
356
- const book = await books.getRow({ id: patient.favbook });
357
- (0, assertions_1.assertIsSet)(book);
358
- (0, globals_1.expect)(book.pages).toBe(728);
359
- await books.updateRow({ pages: 729 }, book.id);
360
- await books.updateRow({ pages: 728 }, book.id);
361
- const bid = await books.insertRow({ author: "Terry Eagleton", pages: 456 });
362
- const book1 = await books.getRow({ id: bid });
363
- (0, assertions_1.assertIsSet)(book1);
364
- (0, globals_1.expect)(book1.storedsum).toBe(4);
365
- await books.getField("number_of_fans").delete();
366
- await books.getField("idp1").delete();
367
- await books.getField("storedsum").delete();
368
- await books.deleteRows({ id: bid });
369
- });
370
- });
371
- (0, globals_1.describe)("bool arrays in stored calculated JSON fields", () => {
372
- (0, globals_1.it)("creates", async () => {
373
- getState().registerPlugin("mock_plugin", plugin_with_routes());
374
- const patients = table_1.default.findOne({ name: "patients" });
375
- (0, assertions_1.assertIsSet)(patients);
376
- await field_1.default.create({
377
- name: "normalised_readings",
378
- label: "normalised_readings",
379
- calculated: true,
380
- stored: true,
381
- expression: "__aggregation",
382
- type: "JSON",
383
- attributes: {
384
- ref: "patient_id",
385
- table: "readings",
386
- aggwhere: "",
387
- agg_field: "normalised@Bool",
388
- aggregate: "Array_Agg",
389
- agg_order_by: "",
390
- agg_relation: "readings.patient_id",
391
- unique_error_msg: null,
392
- },
393
- required: false,
394
- table: patients,
395
- });
396
- // need this to avoid race condition with next test
397
- await recalculate_for_stored(patients);
398
- });
399
- (0, globals_1.it)("has array content", async () => {
400
- const patients = table_1.default.findOne({ name: "patients" });
401
- (0, assertions_1.assertIsSet)(patients);
402
- const pat = await patients.getRow({ id: 1 });
403
- (0, assertions_1.assertIsSet)(pat);
404
- (0, globals_1.expect)(Array.isArray(pat.normalised_readings)).toBe(true);
405
- if (!db_1.default.isSQLite)
406
- (0, globals_1.expect)(typeof pat.normalised_readings[0]).toBe("boolean");
407
- });
408
- (0, globals_1.it)("updates on changes", async () => {
409
- const patients = table_1.default.findOne({ name: "patients" });
410
- (0, assertions_1.assertIsSet)(patients);
411
- const readings = table_1.default.findOne({ name: "readings" });
412
- (0, assertions_1.assertIsSet)(readings);
413
- const pat = await patients.getRow({ id: 1 });
414
- (0, assertions_1.assertIsSet)(pat);
415
- if (!db_1.default.isSQLite)
416
- (0, globals_1.expect)(typeof pat.normalised_readings[0]).toBe("boolean");
417
- const reads = await readings.getRows({ patient_id: 1 });
418
- for (const read of reads)
419
- await readings.updateRow({ normalised: false }, read.id);
420
- const pat1 = await patients.getRow({ id: 1 });
421
- (0, assertions_1.assertIsSet)(pat1);
422
- (0, globals_1.expect)(Array.isArray(pat1.normalised_readings)).toBe(true);
423
- if (!db_1.default.isSQLite)
424
- (0, globals_1.expect)(typeof pat1.normalised_readings[0]).toBe("boolean");
425
- if (db_1.default.isSQLite)
426
- (0, globals_1.expect)(!!pat1.normalised_readings[0]).toBe(false);
427
- else
428
- (0, globals_1.expect)(pat1.normalised_readings[0]).toBe(false);
429
- });
430
- (0, globals_1.it)("updates on insert", async () => {
431
- const patients = table_1.default.findOne({ name: "patients" });
432
- (0, assertions_1.assertIsSet)(patients);
433
- const readings = table_1.default.findOne({ name: "readings" });
434
- (0, assertions_1.assertIsSet)(readings);
435
- const pat0 = await patients.getRow({ id: 1 });
436
- (0, assertions_1.assertIsSet)(pat0);
437
- (0, globals_1.expect)(Array.isArray(pat0.normalised_readings)).toBe(true);
438
- (0, globals_1.expect)(pat0.normalised_readings.length).toBe(2);
439
- await readings.insertRow({
440
- normalised: true,
441
- patient_id: 1,
442
- temperature: 39,
443
- });
444
- const pat1 = await patients.getRow({ id: 1 });
445
- (0, assertions_1.assertIsSet)(pat1);
446
- (0, globals_1.expect)(Array.isArray(pat1.normalised_readings)).toBe(true);
447
- if (!db_1.default.isSQLite)
448
- (0, globals_1.expect)(typeof pat1.normalised_readings[0]).toBe("boolean");
449
- (0, globals_1.expect)(pat1.normalised_readings.length).toBe(3);
450
- });
451
- });
452
- (0, globals_1.describe)("double joinfields in stored calculated fields", () => {
453
- (0, globals_1.it)("creates", async () => {
454
- const readings = table_1.default.findOne({ name: "readings" });
455
- (0, assertions_1.assertIsSet)(readings);
456
- const f = await field_1.default.create({
457
- table: readings,
458
- label: "favpages",
459
- type: "Integer",
460
- calculated: true,
461
- expression: "patient_id?.favbook?.pages",
462
- stored: true,
463
- });
464
- //console.log(f.attributes.calc_joinfields)
465
- });
466
- (0, globals_1.it)("recalculates if final value changes", async () => {
467
- const readings = table_1.default.findOne({ name: "readings" });
468
- (0, assertions_1.assertIsSet)(readings);
469
- const patients = table_1.default.findOne({ name: "patients" });
470
- (0, assertions_1.assertIsSet)(patients);
471
- const patid = await patients.insertRow({ name: "Stephen Few", favbook: 2 });
472
- const readid = await readings.insertRow({
473
- patient_id: patid,
474
- temperature: 37,
475
- });
476
- const reading = await readings.getRow({ id: readid });
477
- (0, globals_1.expect)(reading?.favpages).toBe(728);
478
- const patient = await patients.getRow({ id: patid });
479
- (0, assertions_1.assertIsSet)(patient);
480
- const books = table_1.default.findOne({ name: "books" });
481
- (0, assertions_1.assertIsSet)(books);
482
- const book = await books.getRow({ id: patient.favbook });
483
- (0, globals_1.expect)(book?.pages).toBe(728);
484
- await books.updateRow({ pages: 729 }, book?.id);
485
- //await recalculate_for_stored(patients, { id: 1 });
486
- const reading1 = await readings.getRow({ id: readid });
487
- (0, globals_1.expect)(reading1?.favpages).toBe(729);
488
- await books.updateRow({ pages: 728 }, book?.id);
489
- });
490
- (0, globals_1.it)("recalculates if intermediate value changes", async () => {
491
- const readings = table_1.default.findOne({ name: "readings" });
492
- (0, assertions_1.assertIsSet)(readings);
493
- const patients = table_1.default.findOne({ name: "patients" });
494
- (0, assertions_1.assertIsSet)(patients);
495
- const patid = await patients.insertRow({
496
- name: "Stephen Many",
497
- favbook: 2,
498
- });
499
- const readid = await readings.insertRow({
500
- patient_id: patid,
501
- temperature: 37,
502
- });
503
- const reading = await readings.getRow({ id: readid });
504
- (0, globals_1.expect)(reading?.favpages).toBe(728);
505
- await patients.updateRow({ favbook: 1 }, patid);
506
- //await recalculate_for_stored(readings, { id: readid });
507
- const reading1 = await readings.getRow({ id: readid });
508
- (0, globals_1.expect)(reading1?.favpages).toBe(967);
509
- });
510
- });
511
- (0, globals_1.describe)("Simple aggregations in stored calculated fields", () => {
512
- (0, globals_1.it)("creates", async () => {
513
- const publisher = table_1.default.findOne({ name: "publisher" });
514
- (0, assertions_1.assertIsSet)(publisher);
515
- await field_1.default.create({
516
- table: publisher,
517
- label: "Number of books",
518
- type: "Integer",
519
- calculated: true,
520
- expression: "__aggregation",
521
- attributes: {
522
- aggregate: "Count",
523
- aggwhere: "",
524
- agg_field: "id@Integer",
525
- agg_relation: "books.publisher",
526
- table: "books",
527
- ref: "publisher",
528
- },
529
- stored: true,
530
- });
531
- });
532
- (0, globals_1.it)("updates", async () => {
533
- const publisher = table_1.default.findOne({ name: "publisher" });
534
- (0, assertions_1.assertIsSet)(publisher);
535
- const bookRows = await publisher.getRows({});
536
- for (const row of bookRows) {
537
- await publisher.updateRow({}, row.id);
538
- }
539
- });
540
- (0, globals_1.it)("check", async () => {
541
- const publisher = table_1.default.findOne({ name: "publisher" });
542
- (0, assertions_1.assertIsSet)(publisher);
543
- const bookrow = await publisher.getRow({ id: 1 });
544
- (0, globals_1.expect)(bookrow?.number_of_books).toBe(1);
545
- });
546
- (0, globals_1.it)("insert", async () => {
547
- const publisher = table_1.default.findOne({ name: "publisher" });
548
- (0, assertions_1.assertIsSet)(publisher);
549
- const hid = await publisher.insertRow({ name: "Collins" });
550
- const hrow = await publisher.getRow({ id: hid });
551
- (0, globals_1.expect)(hrow?.number_of_books).toBe(0);
552
- const books = table_1.default.findOne({ name: "books" });
553
- (0, assertions_1.assertIsSet)(books);
554
- await books.insertRow({
555
- author: "Murphy",
556
- pages: 456,
557
- publisher: hid,
558
- });
559
- //await recalculate_for_stored(publisher);
560
- const hrow1 = await publisher.getRow({ id: hid });
561
- (0, globals_1.expect)(hrow1?.number_of_books).toBe(1);
562
- await books.insertRow({
563
- author: "Tufte",
564
- pages: 210,
565
- publisher: hid,
566
- });
567
- //await recalculate_for_stored(publisher, { id: hid });
568
- const hrow2 = await publisher.getRow({ id: hid });
569
- (0, globals_1.expect)(hrow2?.number_of_books).toBe(2);
570
- const trigger = await trigger_1.default.create({
571
- action: "recalculate_stored_fields",
572
- table_id: books.id,
573
- when_trigger: "Insert",
574
- configuration: {
575
- table: "publisher",
576
- where: "{id: publisher}",
577
- },
578
- });
579
- const wid = await books.insertRow({
580
- author: "West",
581
- pages: 210,
582
- publisher: hid,
583
- });
584
- await sleep(200);
585
- const hrow3 = await publisher.getRow({ id: hid });
586
- (0, globals_1.expect)(hrow3?.number_of_books).toBe(3);
587
- await books.deleteRows({ id: wid });
588
- const hrow4 = await publisher.getRow({ id: hid });
589
- (0, globals_1.expect)(hrow4?.number_of_books).toBe(2);
590
- });
591
- (0, globals_1.it)("moves from one parent to another", async () => {
592
- const publisher = table_1.default.findOne({ name: "publisher" });
593
- (0, assertions_1.assertIsSet)(publisher);
594
- const books = table_1.default.findOne({ name: "books" });
595
- (0, assertions_1.assertIsSet)(books);
596
- const ps = await publisher.getRows({}, { orderBy: "id" });
597
- //console.log("ps", ps);
598
- (0, globals_1.expect)(ps[1].number_of_books).toBe(0);
599
- (0, globals_1.expect)(ps[2].number_of_books).toBe(2);
600
- const cbook = await books.getRow({ publisher: 3 });
601
- (0, assertions_1.assertIsSet)(cbook);
602
- //await getState().setConfig("log_level", 6);
603
- await books.updateRow({ publisher: 2 }, cbook.id);
604
- //await recalculate_for_stored(publisher, {});
605
- //await getState().setConfig("log_level", 1);
606
- const ps1 = await publisher.getRows({}, { orderBy: "id" });
607
- //onsole.log("ps1", ps1);
608
- (0, globals_1.expect)(ps1[1].number_of_books).toBe(1);
609
- (0, globals_1.expect)(ps1[2].number_of_books).toBe(1);
610
- });
611
- (0, globals_1.it)("creates and updates sum field", async () => {
612
- const publisher = table_1.default.findOne({ name: "publisher" });
613
- (0, assertions_1.assertIsSet)(publisher);
614
- await field_1.default.create({
615
- table: publisher,
616
- label: "Sum of pages",
617
- type: "Integer",
618
- calculated: true,
619
- expression: "__aggregation",
620
- attributes: {
621
- aggregate: "Sum",
622
- aggwhere: "",
623
- agg_field: "pages@Integer",
624
- agg_relation: "books.publisher",
625
- table: "books",
626
- ref: "publisher",
627
- },
628
- stored: true,
629
- });
630
- const bookRows = await publisher.getRows({});
631
- for (const row of bookRows) {
632
- await publisher.updateRow({}, row.id);
633
- }
634
- const hrow3 = await publisher.getRow({ id: 1 });
635
- (0, globals_1.expect)(hrow3?.sum_of_pages).toBe(728);
636
- const books = table_1.default.findOne({ name: "books" });
637
- (0, assertions_1.assertIsSet)(books);
638
- const book = await books.getRow({ publisher: 1 });
639
- (0, assertions_1.assertIsSet)(book);
640
- await books.updateRow({ pages: 729 }, book.id);
641
- const hrow4 = await publisher.getRow({ id: 1 });
642
- (0, globals_1.expect)(hrow4?.sum_of_pages).toBe(729);
643
- const bid = await books.insertRow({
644
- pages: 11,
645
- publisher: 1,
646
- author: "Fizz Buzz",
647
- });
648
- const hrow5 = await publisher.getRow({ id: 1 });
649
- (0, globals_1.expect)(hrow5?.sum_of_pages).toBe(740);
650
- await books.deleteRows({ id: bid });
651
- });
652
- });
653
- (0, globals_1.describe)("Sum-where aggregations in stored calculated fields", () => {
654
- (0, globals_1.it)("creates and updates sum field", async () => {
655
- const publisher = table_1.default.findOne({ name: "publisher" });
656
- (0, assertions_1.assertIsSet)(publisher);
657
- const books = table_1.default.findOne({ name: "books" });
658
- (0, assertions_1.assertIsSet)(books);
659
- await field_1.default.create({
660
- table: books,
661
- label: "Interesting",
662
- type: "Bool",
663
- });
664
- await field_1.default.create({
665
- table: publisher,
666
- label: "Sum of pages2",
667
- type: "Integer",
668
- calculated: true,
669
- expression: "__aggregation",
670
- attributes: {
671
- aggregate: "Sum",
672
- aggwhere: "interesting == true",
673
- agg_field: "pages@Integer",
674
- agg_relation: "books.publisher",
675
- table: "books",
676
- ref: "publisher",
677
- },
678
- stored: true,
679
- });
680
- const bookRows = await publisher.getRows({});
681
- for (const row of bookRows) {
682
- await publisher.updateRow({}, row.id);
683
- }
684
- const book = await books.getRow({ publisher: 1 });
685
- (0, assertions_1.assertIsSet)(book);
686
- const bookid = await books.insertRow({
687
- pages: 12,
688
- publisher: 1,
689
- author: "Fizz Buzz",
690
- interesting: true,
691
- });
692
- const hrow4 = await publisher.getRow({ id: 1 });
693
- (0, globals_1.expect)(hrow4?.sum_of_pages2).toBe(12);
694
- await books.updateRow({ pages: 14 }, bookid);
695
- const hrow6 = await publisher.getRow({ id: 1 });
696
- (0, globals_1.expect)(hrow6?.sum_of_pages2).toBe(14);
697
- const bid2 = await books.insertRow({
698
- pages: 11,
699
- publisher: 1,
700
- author: "Fizz Buzz",
701
- interesting: true,
702
- });
703
- const hrow5 = await publisher.getRow({ id: 1 });
704
- (0, globals_1.expect)(hrow5?.sum_of_pages2).toBe(25);
705
- await books.deleteRows({ id: bookid });
706
- await books.deleteRows({ id: bid2 });
707
- });
708
- });
709
- (0, globals_1.describe)("join-aggregations in stored calculated fields", () => {
710
- (0, globals_1.it)("creates", async () => {
711
- const books = table_1.default.findOne({ name: "books" });
712
- (0, assertions_1.assertIsSet)(books);
713
- await field_1.default.create({
714
- table: books,
715
- name: "books_same_pub",
716
- label: "books_same_pub",
717
- calculated: true,
718
- stored: true,
719
- expression: "__aggregation",
720
- type: "Integer",
721
- attributes: {
722
- ref: "publisher",
723
- table: "publisher->books",
724
- aggwhere: "",
725
- agg_field: "id@Integer",
726
- aggregate: "Count",
727
- agg_order_by: null,
728
- agg_relation: "publisher->books.publisher",
729
- unique_error_msg: null,
730
- },
731
- });
732
- await recalculate_for_stored(books);
733
- });
734
- (0, globals_1.it)("check", async () => {
735
- const books = table_1.default.findOne({ name: "books" });
736
- (0, assertions_1.assertIsSet)(books);
737
- const bookrow = await books.getRow({ id: 2 });
738
- (0, globals_1.expect)(bookrow?.books_same_pub).toBe(1);
739
- await books.insertRow({ author: "Boring bloke", pages: 54, publisher: 1 });
740
- const bookrow1 = await books.getRow({ id: 2 });
741
- (0, globals_1.expect)(bookrow1?.books_same_pub).toBe(2);
742
- });
743
- });
744
- (0, globals_1.describe)("join-aggregations in stored calculated fields again", () => {
745
- (0, globals_1.it)("creates", async () => {
746
- const sumtable = await table_1.default.create("DateSummary");
747
- const banktable = await table_1.default.create("Bank");
748
- const xacttable = await table_1.default.create("Transaction");
749
- await field_1.default.create({
750
- table: banktable,
751
- name: "name",
752
- label: "Name",
753
- type: "String",
754
- });
755
- await field_1.default.create({
756
- table: sumtable,
757
- name: "bankid",
758
- label: "BankID",
759
- type: "Key to Bank",
760
- });
761
- await field_1.default.create({
762
- table: xacttable,
763
- name: "tbankid",
764
- label: "TBankID",
765
- type: "Key to Bank",
766
- });
767
- await field_1.default.create({
768
- table: xacttable,
769
- name: "amount",
770
- label: "Amount",
771
- type: "Integer",
772
- });
773
- await field_1.default.create({
774
- table: sumtable,
775
- name: "sumamount",
776
- label: "SumAmount",
777
- type: "Integer",
778
- calculated: true,
779
- stored: true,
780
- expression: "__aggregation",
781
- attributes: {
782
- ref: "tbankid",
783
- table: "bankid->Transaction",
784
- aggwhere: "", //"transactiondate == summarydate",
785
- agg_field: "amount@Integer",
786
- aggregate: "Sum",
787
- agg_relation: "bankid->Transaction.tbankid",
788
- },
789
- });
790
- await banktable.insertRow({ name: "Lloyds" });
791
- await banktable.insertRow({ name: "Starling" });
792
- await banktable.insertRow({ name: "HSBC" });
793
- await sumtable.insertRow({ bankid: 2 });
794
- await sumtable.insertRow({ bankid: 1 });
795
- await sumtable.insertRow({ bankid: 3 });
796
- await xacttable.insertRow({ tbankid: 2, amount: 10 });
797
- //await recalculate_for_stored(sumtable);
798
- const sumrow = await sumtable.getRow({ id: 1 });
799
- (0, globals_1.expect)(sumrow?.sumamount).toBe(10);
800
- });
801
- });
802
- (0, globals_1.describe)("expressionValidator", () => {
803
- (0, globals_1.it)("validates correct", () => {
804
- (0, globals_1.expect)(expressionValidator("2+2")).toBe(true);
805
- });
806
- (0, globals_1.it)("validates record literal", () => {
807
- (0, globals_1.expect)(expressionValidator("{foo: 4}")).toBe(true);
808
- });
809
- (0, globals_1.it)("validates correct", () => {
810
- (0, globals_1.expect)(expressionValidator("name.toUpperCase()")).toBe(true);
811
- });
812
- (0, globals_1.it)("invalidates incorrect", () => {
813
- (0, globals_1.expect)(expressionValidator("2+")).toContain("Unexpected");
814
- });
815
- });
816
- (0, globals_1.describe)("free variables", () => {
817
- (0, globals_1.it)("empty", () => {
818
- (0, globals_1.expect)([...freeVariables("2+2")]).toEqual([]);
819
- });
820
- (0, globals_1.it)("simple", () => {
821
- (0, globals_1.expect)([...freeVariables("2+x")]).toEqual(["x"]);
822
- });
823
- (0, globals_1.it)("record access", () => {
824
- (0, globals_1.expect)([...freeVariables("2+x.k")]).toEqual(["x.k"]);
825
- });
826
- (0, globals_1.it)("record double access", () => {
827
- (0, globals_1.expect)([...freeVariables("x.k.y")]).toEqual(["x.k.y"]);
828
- });
829
- (0, globals_1.it)("record triple access", () => {
830
- (0, globals_1.expect)([...freeVariables("1+x.k.y.z")]).toEqual(["x.k.y.z"]);
831
- });
832
- (0, globals_1.it)("record single and double access", () => {
833
- (0, globals_1.expect)([...freeVariables("x.k.y+x.z")]).toEqual(["x.k.y", "x.z"]);
834
- });
835
- (0, globals_1.it)("record double access with function", () => {
836
- (0, globals_1.expect)([...freeVariables("Math.floor(x.k)")]).toEqual(["Math", "x.k"]);
837
- (0, globals_1.expect)([...freeVariables("Math.floor(x)")]).toEqual(["Math", "x"]);
838
- (0, globals_1.expect)([...freeVariables("Math.floor(x.k.y)")]).toEqual(["Math", "x.k.y"]);
839
- (0, globals_1.expect)([...freeVariables("Math.floor(x.k.y.w)")]).toEqual([
840
- "Math",
841
- "x.k.y.w",
842
- ]);
843
- });
844
- (0, globals_1.it)("does not include match function calls", () => {
845
- (0, globals_1.expect)([...freeVariables("x.k.match(/xx/)")]).toEqual(["x.k"]);
846
- (0, globals_1.expect)([...freeVariables("x.k.map(g).includes(y)")]).toContain("x.k");
847
- (0, globals_1.expect)([...freeVariables("myFun(k)")]).toEqual(["myFun", "k"]);
848
- (0, globals_1.expect)([...freeVariables("myFun(x.k)")]).toEqual(["myFun", "x.k"]);
849
- (0, globals_1.expect)([...freeVariables("Foo.myFun(x.k)")]).toEqual(["Foo", "x.k"]);
850
- (0, globals_1.expect)([...freeVariables("foo.match(/xx/)")]).toEqual(["foo"]);
851
- (0, globals_1.expect)([...freeVariables("foo[0]")]).toEqual(["foo"]);
852
- (0, globals_1.expect)([...freeVariables("x.k.map(g)")]).toEqual(["x.k", "g"]);
853
- });
854
- (0, globals_1.it)("does not include length", () => {
855
- (0, globals_1.expect)([...freeVariables("x.k.length")]).toEqual(["x.k"]);
856
- (0, globals_1.expect)([...freeVariables("x.length")]).toEqual(["x"]);
857
- });
858
- (0, globals_1.it)("chain record access", () => {
859
- (0, globals_1.expect)([...freeVariables("1+x?.k")]).toEqual(["x.k"]);
860
- });
861
- (0, globals_1.it)("user ownership with group", () => {
862
- (0, globals_1.expect)([
863
- ...freeVariables("user.books_by_editor.map(b=>b.id).includes(id)"),
864
- ]).toContain("user.books_by_editor");
865
- });
866
- (0, globals_1.it)("in interpolation", () => {
867
- (0, globals_1.expect)([...freeVariablesInInterpolation("hello {{2+x.k}}")]).toEqual([
868
- "x.k",
869
- ]);
870
- });
871
- (0, globals_1.it)("in unsafe interpolation", () => {
872
- (0, globals_1.expect)([...freeVariablesInInterpolation("hello {{! x.k}}")]).toEqual([
873
- "x.k",
874
- ]);
875
- });
876
- (0, globals_1.it)("in unsafe interpolation", () => {
877
- (0, globals_1.expect)([...freeVariablesInInterpolation("hello {{! foo}}")]).toEqual([
878
- "foo",
879
- ]);
880
- });
881
- (0, globals_1.it)("in interpolation", () => {
882
- (0, globals_1.expect)([
883
- ...freeVariablesInInterpolation("hello {{2+x.k}} there {{y.z}}"),
884
- ]).toEqual(["x.k", "y.z"]);
885
- });
886
- });
887
- (0, globals_1.describe)("interpolation", () => {
888
- (0, globals_1.it)("interpolates simple", () => {
889
- (0, globals_1.expect)(interpolate("hello {{ x }}", { x: 1 })).toBe("hello 1");
890
- (0, globals_1.expect)(interpolate("hello {{ x }}", { x: "<script>alert(1)</script>" })).toBe("hello &lt;script&gt;alert(1)&lt;/script&gt;");
891
- (0, globals_1.expect)(interpolate("hello {{! x }}", { x: "<script>alert(1)</script>" })).toBe("hello <script>alert(1)</script>");
892
- //expect(interpolate("hello {{x}}", { x: 1 })).toBe("hello 1"); TODO
893
- });
894
- });
895
- (0, globals_1.describe)("jsexprToSQL", () => {
896
- (0, globals_1.it)("translates equality", () => {
897
- (0, globals_1.expect)(jsexprToSQL("foo==4")).toEqual("(foo)=(4)");
898
- });
899
- (0, globals_1.it)("translates string equality", () => {
900
- (0, globals_1.expect)(jsexprToSQL('foo=="bar"')).toEqual("(foo)=('bar')");
901
- (0, globals_1.expect)(jsexprToSQL('foo!="bar"')).toEqual("(foo)!=('bar')");
902
- (0, globals_1.expect)(jsexprToSQL('!(foo=="bar")')).toEqual("not ((foo)=('bar'))");
903
- });
904
- (0, globals_1.it)("translates bools", () => {
905
- (0, globals_1.expect)(jsexprToSQL("foo==true")).toEqual("foo is true");
906
- (0, globals_1.expect)(jsexprToSQL("foo==false")).toEqual("foo is false");
907
- });
908
- (0, globals_1.it)("translates null cmps", () => {
909
- (0, globals_1.expect)(jsexprToSQL("foo===null")).toEqual("foo is null");
910
- (0, globals_1.expect)(jsexprToSQL("foo==null")).toEqual("foo is null");
911
- (0, globals_1.expect)(jsexprToSQL("foo!=null")).toEqual("foo is not null");
912
- (0, globals_1.expect)(jsexprToSQL("foo!==null")).toEqual("foo is not null");
913
- });
914
- (0, globals_1.it)("translates and", () => {
915
- (0, globals_1.expect)(jsexprToSQL("foo==true && x==2")).toEqual("(foo is true)and((x)=(2))");
916
- });
917
- (0, globals_1.it)("translates something mildly complex", () => {
918
- (0, globals_1.expect)(jsexprToSQL('!(name==="roderick" && phone==null)')).toEqual("not (((name)=('roderick'))and(phone is null))");
919
- });
920
- });
921
- (0, globals_1.describe)("mergeIntoWhere", () => {
922
- (0, globals_1.it)("merges", () => {
923
- (0, globals_1.expect)(mergeIntoWhere({ a: 1 }, { b: 2 })).toEqual({ a: 1, b: 2 });
924
- (0, globals_1.expect)(mergeIntoWhere({ a: 1 }, { a: 2 })).toEqual({ a: [1, 2] });
925
- (0, globals_1.expect)(mergeIntoWhere({ or: [{ a: 1 }, { a: 2 }] }, { or: [{ b: 3 }, { b: 4 }] })).toEqual({
926
- and: [{ or: [{ a: 1 }, { a: 2 }] }, { or: [{ b: 3 }, { b: 4 }] }],
927
- });
928
- });
929
- });
930
- let x = {
931
- and: [{ or: [{ a: 1 }, { a: 2 }] }, { or: [{ b: 3 }, { b: 4 }] }],
932
- or: [{ b: 3 }, { b: 4 }],
933
- };
934
- (0, globals_1.describe)("jsexprToWhere", () => {
935
- (0, globals_1.it)("translates equality", () => {
936
- (0, globals_1.expect)(jsexprToWhere("foo==4")).toEqual({ foo: 4 });
937
- });
938
- (0, globals_1.it)("translates equality reverse", () => {
939
- (0, globals_1.expect)(jsexprToWhere("4==foo")).toEqual({ foo: 4 });
940
- });
941
- (0, globals_1.it)("translates equal to col", () => {
942
- (0, globals_1.expect)(jsexprToWhere("foo==bar").foo.description).toBe("bar");
943
- });
944
- (0, globals_1.it)("translates context", () => {
945
- (0, globals_1.expect)(jsexprToWhere("foo==$bar", { bar: 5 })).toEqual({ foo: 5 });
946
- });
947
- (0, globals_1.it)("translates own context", () => {
948
- (0, globals_1.expect)(jsexprToWhere("foo==$foo", { foo: 5 }, [{ name: "foo" }])).toEqual({ foo: 5 });
949
- });
950
- (0, globals_1.it)("translates context", () => {
951
- const w = jsexprToWhere("$father !== null && married_to === $father", {
952
- father: "1",
953
- });
954
- (0, globals_1.expect)(w).toEqual({ married_to: "1", not: { eq: ["1", null] } });
955
- });
956
- (0, globals_1.it)("translates context", () => {
957
- const w = jsexprToWhere("$father !== null && married_to === $father", {});
958
- (0, globals_1.expect)(w).toEqual({ married_to: null, not: { eq: [null, null] } });
959
- });
960
- (0, globals_1.it)("is null in sql", () => {
961
- const w = jsexprToWhere("group !== null", {});
962
- (0, globals_1.expect)(w).toEqual({ not: { group: null } });
963
- const { where } = (0, internal_1.mkWhere)(w);
964
- (0, globals_1.expect)(where).toEqual('where not ("group" is null)');
965
- });
966
- /* TODO
967
-
968
- it("double exclamation", () => {
969
- const w = jsexprToWhere("!!group", {});
970
- console.log(w);
971
-
972
- expect(w).toEqual({ not: { group: null } });
973
-
974
- const { where } = mkWhere(w);
975
- expect(where).toEqual('where not ("group" is null)');
976
- }); */
977
- (0, globals_1.it)("translates greater than", () => {
978
- (0, globals_1.expect)(jsexprToWhere("foo>4")).toEqual({ foo: { gt: 4 } });
979
- });
980
- (0, globals_1.it)("translates lte", () => {
981
- (0, globals_1.expect)(jsexprToWhere("foo<=4")).toEqual({ foo: { lt: 4, equal: true } });
982
- });
983
- (0, globals_1.it)("translates join field", async () => {
984
- const books = table_1.default.findOne({ name: "books" });
985
- const fields = await books?.getFields();
986
- (0, globals_1.expect)(jsexprToWhere("publisher.name=='AK Press'", {}, fields)).toEqual({
987
- publisher: {
988
- inSelect: {
989
- field: "id",
990
- table: "publisher",
991
- tenant: "public",
992
- where: { name: "AK Press" },
993
- },
994
- },
995
- });
996
- });
997
- (0, globals_1.it)("access context subvars", () => {
998
- (0, globals_1.expect)(jsexprToWhere("foo==user.id", { user: { id: 5 } })).toEqual({
999
- foo: 5,
1000
- });
1001
- });
1002
- (0, globals_1.it)("access deep context subvars", () => {
1003
- (0, globals_1.expect)(jsexprToWhere("foo==user.address.id", { user: { address: { id: 5 } } })).toEqual({
1004
- foo: 5,
1005
- });
1006
- });
1007
- (0, globals_1.it)("access context subvars rev", () => {
1008
- (0, globals_1.expect)(jsexprToWhere("user.id===foo", { user: { id: 5 } })).toEqual({
1009
- foo: 5,
1010
- });
1011
- });
1012
- (0, globals_1.it)("still parses same var", () => {
1013
- //nexdot issue Where function not working well
1014
- (0, globals_1.expect)(jsexprToWhere("foo == $foo", { foo: "$foo" })).toEqual({
1015
- foo: "$foo",
1016
- });
1017
- });
1018
- (0, globals_1.it)("translates sums", () => {
1019
- (0, globals_1.expect)(jsexprToWhere("foo==4+3")).toEqual({ foo: 7 });
1020
- (0, globals_1.expect)(jsexprToWhere("foo==4+3+1")).toEqual({ foo: 8 });
1021
- });
1022
- (0, globals_1.it)("translates bools", () => {
1023
- (0, globals_1.expect)(jsexprToWhere("foo==true")).toEqual({ foo: true });
1024
- (0, globals_1.expect)(jsexprToWhere("foo==false")).toEqual({ foo: false });
1025
- (0, globals_1.expect)(jsexprToWhere("foo!==true")).toEqual({ not: { foo: true } });
1026
- (0, globals_1.expect)(jsexprToWhere("!(foo==true)")).toEqual({ not: { foo: true } });
1027
- (0, globals_1.expect)(jsexprToWhere('bar == "Zoo" && !(foo==true)')).toEqual({
1028
- bar: "Zoo",
1029
- not: { foo: true },
1030
- });
1031
- (0, globals_1.expect)(jsexprToWhere('(bar == "Zoo" || bar == "Baz" || bar == "Waz") && !(foo==true)')).toEqual({
1032
- or: [{ or: [{ bar: "Zoo" }, { bar: "Baz" }] }, { bar: "Waz" }],
1033
- not: { foo: true },
1034
- });
1035
- (0, globals_1.expect)(jsexprToWhere('(bar == "Zoo" || bar == "Baz") && (foo==false || foo==null)')).toEqual({
1036
- and: [
1037
- { or: [{ bar: "Zoo" }, { bar: "Baz" }] },
1038
- { or: [{ foo: false }, { foo: null }] },
1039
- ],
1040
- });
1041
- });
1042
- (0, globals_1.it)("jsexprToWhere equate constant", () => {
1043
- (0, globals_1.expect)(jsexprToWhere("user.clearance==5", { user: { clearance: 5 } })).toEqual({ eq: [5, 5] });
1044
- (0, globals_1.expect)(jsexprToWhere('user.clearance=="ALL"', { user: { clearance: "ALL" } })).toEqual({ eq: ["ALL", "ALL"] });
1045
- (0, globals_1.expect)(jsexprToWhere("user.clearance==5", { user: { clearance: 6 } })).toEqual({ eq: [6, 5] });
1046
- (0, globals_1.expect)(jsexprToWhere('user.clearance=="ALL"', { user: { clearance: "NONE" } })).toEqual({ eq: ["NONE", "ALL"] });
1047
- });
1048
- (0, globals_1.it)("translates date limits", () => {
1049
- (0, globals_1.expect)(jsexprToWhere("foo>=year+'-'+month+'-01'").foo.gt).toMatch(/^202/);
1050
- });
1051
- (0, globals_1.it)("translates today()", () => {
1052
- const todayW = jsexprToWhere("foo>=today()");
1053
- const today = todayW.foo.gt;
1054
- (0, globals_1.expect)(todayW.foo.equal).toEqual(true);
1055
- (0, globals_1.expect)(today).toMatch(/^202/);
1056
- (0, globals_1.expect)(jsexprToWhere("foo>=today(5)").foo.gt).toMatch(/^202/);
1057
- (0, globals_1.expect)(new Date(jsexprToWhere("foo>=today(5)").foo.gt) > new Date(today)).toEqual(true);
1058
- (0, globals_1.expect)(new Date(jsexprToWhere("foo>=today({startOf: 'week'})").foo.gt) <
1059
- new Date()).toEqual(true);
1060
- const eoweek = new Date(jsexprToWhere("foo>=today({endOf: 'week'})").foo.gt);
1061
- (0, globals_1.expect)(eoweek > new Date() || eoweek.toDateString() === new Date().toDateString()).toEqual(true);
1062
- (0, globals_1.expect)(jsexprToWhere("foo>=today(-5)").foo.gt).toMatch(/^202/);
1063
- (0, globals_1.expect)(new Date(jsexprToWhere("foo>=today(-5)").foo.gt) < new Date(today)).toEqual(true);
1064
- const pp1W = jsexprToWhere("foo >= today(-1) && foo < today()");
1065
- (0, globals_1.expect)(!!pp1W.foo[0].gt).toBe(true);
1066
- (0, globals_1.expect)(pp1W.foo[0].equal).toBe(true);
1067
- (0, globals_1.expect)(!!pp1W.foo[1].lt).toBe(true);
1068
- const ppW = jsexprToWhere("createdby == user.id && (foo >= today(-1) && foo < today())", { user: { id: 1 } });
1069
- (0, globals_1.expect)(ppW.createdby).toBe(1);
1070
- (0, globals_1.expect)(!!ppW.foo[0].gt).toBe(true);
1071
- (0, globals_1.expect)(!!ppW.foo[1].lt).toBe(true);
1072
- });
1073
- (0, globals_1.it)("translates new Date()", () => {
1074
- const todayW = jsexprToWhere("foo>=new Date()");
1075
- const today = todayW.foo.gt;
1076
- (0, globals_1.expect)(todayW.foo.equal).toEqual(true);
1077
- (0, globals_1.expect)(today instanceof Date).toBe(true);
1078
- (0, globals_1.expect)(today.toISOString()).toMatch(/^202/);
1079
- });
1080
- });
1081
- //# sourceMappingURL=calc.test.js.map