@malloydata/malloy-tests 0.0.68-dev230808000650 → 0.0.68

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 (81) hide show
  1. package/dist/databases/all/db_index.spec.d.ts +1 -0
  2. package/dist/databases/all/db_index.spec.js +36 -0
  3. package/dist/databases/all/db_index.spec.js.map +1 -0
  4. package/dist/databases/all/expr.spec.d.ts +0 -2
  5. package/dist/databases/all/expr.spec.js +2 -547
  6. package/dist/databases/all/expr.spec.js.map +1 -1
  7. package/dist/databases/all/functions.spec.d.ts +1 -2
  8. package/dist/databases/all/functions.spec.js +2 -751
  9. package/dist/databases/all/functions.spec.js.map +1 -1
  10. package/dist/databases/all/join.spec.d.ts +1 -2
  11. package/dist/databases/all/join.spec.js +2 -276
  12. package/dist/databases/all/join.spec.js.map +1 -1
  13. package/dist/databases/all/nomodel.spec.d.ts +1 -2
  14. package/dist/databases/all/nomodel.spec.js +2 -923
  15. package/dist/databases/all/nomodel.spec.js.map +1 -1
  16. package/dist/databases/all/orderby.spec.d.ts +1 -2
  17. package/dist/databases/all/orderby.spec.js +2 -191
  18. package/dist/databases/all/orderby.spec.js.map +1 -1
  19. package/dist/databases/all/problems.spec.d.ts +1 -2
  20. package/dist/databases/all/problems.spec.js +2 -80
  21. package/dist/databases/all/problems.spec.js.map +1 -1
  22. package/dist/databases/all/sql_expressions.spec.d.ts +1 -2
  23. package/dist/databases/all/sql_expressions.spec.js +2 -62
  24. package/dist/databases/all/sql_expressions.spec.js.map +1 -1
  25. package/dist/databases/all/time.spec.d.ts +1 -3
  26. package/dist/databases/all/time.spec.js +2 -615
  27. package/dist/databases/all/time.spec.js.map +1 -1
  28. package/dist/databases/{all/index.spec.d.ts → shared/db_index.d.ts} +1 -0
  29. package/dist/databases/{all/index.spec.js → shared/db_index.js} +2 -33
  30. package/dist/databases/shared/db_index.js.map +1 -0
  31. package/dist/databases/shared/expr.d.ts +3 -0
  32. package/dist/databases/shared/expr.js +551 -0
  33. package/dist/databases/shared/expr.js.map +1 -0
  34. package/dist/databases/shared/functions.d.ts +3 -0
  35. package/dist/databases/shared/functions.js +754 -0
  36. package/dist/databases/shared/functions.js.map +1 -0
  37. package/dist/databases/shared/join.d.ts +3 -0
  38. package/dist/databases/shared/join.js +302 -0
  39. package/dist/databases/shared/join.js.map +1 -0
  40. package/dist/databases/shared/nomodel.d.ts +3 -0
  41. package/dist/databases/shared/nomodel.js +950 -0
  42. package/dist/databases/shared/nomodel.js.map +1 -0
  43. package/dist/databases/shared/orderby.d.ts +3 -0
  44. package/dist/databases/shared/orderby.js +217 -0
  45. package/dist/databases/shared/orderby.js.map +1 -0
  46. package/dist/databases/shared/problems.d.ts +3 -0
  47. package/dist/databases/shared/problems.js +106 -0
  48. package/dist/databases/shared/problems.js.map +1 -0
  49. package/dist/databases/shared/sql_expressions.d.ts +3 -0
  50. package/dist/databases/shared/sql_expressions.js +88 -0
  51. package/dist/databases/shared/sql_expressions.js.map +1 -0
  52. package/dist/databases/shared/test_list.js +18 -18
  53. package/dist/databases/shared/test_list.js.map +1 -1
  54. package/dist/databases/shared/time.d.ts +3 -0
  55. package/dist/databases/shared/time.js +640 -0
  56. package/dist/databases/shared/time.js.map +1 -0
  57. package/dist/index.d.ts +9 -10
  58. package/dist/index.js +19 -21
  59. package/dist/index.js.map +1 -1
  60. package/package.json +6 -6
  61. package/src/databases/all/db_index.spec.ts +37 -0
  62. package/src/databases/all/expr.spec.ts +2 -670
  63. package/src/databases/all/functions.spec.ts +1 -1101
  64. package/src/databases/all/join.spec.ts +1 -315
  65. package/src/databases/all/nomodel.spec.ts +2 -1124
  66. package/src/databases/all/orderby.spec.ts +1 -234
  67. package/src/databases/all/problems.spec.ts +1 -87
  68. package/src/databases/all/sql_expressions.spec.ts +1 -71
  69. package/src/databases/all/time.spec.ts +1 -761
  70. package/src/databases/{all/index.spec.ts → shared/db_index.ts} +2 -13
  71. package/src/databases/shared/expr.ts +695 -0
  72. package/src/databases/shared/functions.ts +1126 -0
  73. package/src/databases/shared/join.ts +340 -0
  74. package/src/databases/shared/nomodel.ts +1150 -0
  75. package/src/databases/shared/orderby.ts +260 -0
  76. package/src/databases/shared/problems.ts +113 -0
  77. package/src/databases/shared/sql_expressions.ts +96 -0
  78. package/src/databases/shared/test_list.ts +9 -9
  79. package/src/databases/shared/time.ts +786 -0
  80. package/src/index.ts +10 -11
  81. package/dist/databases/all/index.spec.js.map +0 -1
@@ -24,679 +24,11 @@
24
24
 
25
25
  import {RuntimeList, allDatabases} from '../../runtimes';
26
26
  import '../../util/db-jest-matchers';
27
- import {databasesFromEnvironmentOr, mkSqlEqWith, testIf} from '../../util';
27
+ import {databasesFromEnvironmentOr} from '../../util';
28
+ import {exprSharedTests} from '../..';
28
29
 
29
30
  const runtimes = new RuntimeList(databasesFromEnvironmentOr(allDatabases));
30
31
 
31
- const expressionModelText = `
32
- source: aircraft_models is table('malloytest.aircraft_models') extend {
33
- primary_key: aircraft_model_code
34
- measure:
35
- airport_count is count(*),
36
- aircraft_model_count is count(),
37
- total_seats is sum(seats),
38
- boeing_seats is sum(seats) {? manufacturer ? 'BOEING'},
39
- percent_boeing is boeing_seats / total_seats * 100,
40
- percent_boeing_floor is floor(boeing_seats / total_seats * 100),
41
- dimension: seats_bucketed is floor(seats/20)*20.0
42
- }
43
-
44
- source: aircraft is table('malloytest.aircraft') extend {
45
- primary_key: tail_num
46
- join_one: aircraft_models with aircraft_model_code
47
- measure: aircraft_count is count(*)
48
- query: by_manufacturer is {
49
- top: 5
50
- group_by: aircraft_models.manufacturer
51
- aggregate: aircraft_count
52
- }
53
- }
54
- `;
55
-
56
- export const exprSharedTests = (
57
- runtimes: RuntimeList,
58
- _splitFunction?: (column: string, splitChar: string) => string
59
- ) => {
60
- describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
61
- const expressionModel = runtime.loadModel(expressionModelText);
62
- // basic calculations for sum, filtered sum, without a join.
63
- it('basic calculations', async () => {
64
- const result = await expressionModel
65
- .loadQuery(
66
- `
67
- query: aircraft_models->{
68
- aggregate:
69
- total_seats,
70
- total_seats2 is sum(seats),
71
- boeing_seats,
72
- boeing_seats2 is sum(seats) {? manufacturer ? 'BOEING'},
73
- boeing_seats3 is total_seats {? manufacturer ? 'BOEING'},
74
- percent_boeing,
75
- percent_boeing2 is boeing_seats / total_seats * 100,
76
- -- percent_boeing_floor,
77
- -- percent_boeing_floor2 is FLOOR(boeing_seats / total_seats * 100)
78
- }
79
- `
80
- )
81
- .run();
82
- expect(result.data.path(0, 'total_seats').value).toBe(452415);
83
- expect(result.data.path(0, 'total_seats2').value).toBe(452415);
84
- expect(result.data.path(0, 'boeing_seats').value).toBe(252771);
85
- expect(result.data.path(0, 'boeing_seats2').value).toBe(252771);
86
- expect(result.data.path(0, 'boeing_seats3').value).toBe(252771);
87
- expect(
88
- Math.floor(result.data.path(0, 'percent_boeing').number.value)
89
- ).toBe(55);
90
- expect(
91
- Math.floor(result.data.path(0, 'percent_boeing2').number.value)
92
- ).toBe(55);
93
- // expect(result.data.path(0, "percent_boeing_floor").value).toBe(55);
94
- // expect(result.data.path(0, "percent_boeing_floor2").value).toBe(55);
95
- });
96
-
97
- // Floor is broken (doesn't compile because the expression returned isn't an aggregate.)
98
- it('Floor() -or any function bustage with aggregates', async () => {
99
- const result = await expressionModel
100
- .loadQuery(
101
- `
102
- query: aircraft_models->{
103
- aggregate:
104
- percent_boeing_floor
105
- percent_boeing_floor2 is FLOOR(boeing_seats / total_seats * 100)
106
- }
107
- `
108
- )
109
- .run();
110
- expect(result.data.path(0, 'percent_boeing_floor').value).toBe(55);
111
- expect(result.data.path(0, 'percent_boeing_floor2').value).toBe(55);
112
- });
113
-
114
- // Model based version of sums.
115
- it('model: expression fixups.', async () => {
116
- const result = await expressionModel
117
- .loadQuery(
118
- `
119
- query: aircraft->{
120
- aggregate:
121
- aircraft_models.total_seats
122
- aircraft_models.boeing_seats
123
- }
124
- `
125
- )
126
- .run();
127
- expect(result.data.path(0, 'total_seats').value).toBe(18294);
128
- expect(result.data.path(0, 'boeing_seats').value).toBe(6244);
129
- });
130
-
131
- // turtle expressions
132
- it('model: turtle', async () => {
133
- const result = await expressionModel
134
- .loadQuery(
135
- `
136
- query: aircraft->by_manufacturer
137
- `
138
- )
139
- .run();
140
- expect(result.data.path(0, 'manufacturer').value).toBe('CESSNA');
141
- });
142
-
143
- // filtered turtle expressions
144
- testIf(runtime.supportsNesting)('model: filtered turtle', async () => {
145
- const result = await expressionModel
146
- .loadQuery(
147
- `
148
- query: aircraft->{
149
- nest: b is by_manufacturer{? aircraft_models.manufacturer ?~'B%'}
150
- }
151
- `
152
- )
153
- .run();
154
- expect(result.data.path(0, 'b', 0, 'manufacturer').value).toBe('BEECH');
155
- });
156
-
157
- // having.
158
- it('model: simple having', async () => {
159
- const result = await expressionModel
160
- .loadQuery(
161
- `
162
- query: aircraft->{
163
- having: aircraft_count >90
164
- group_by: state
165
- aggregate: aircraft_count
166
- order_by: 2
167
- }
168
- `
169
- )
170
- .run();
171
- expect(result.data.path(0, 'aircraft_count').value).toBe(91);
172
- });
173
-
174
- testIf(runtime.supportsNesting)('model: turtle having2', async () => {
175
- const result = await expressionModel
176
- .loadQuery(
177
- `
178
- -- hacking a null test for now
179
- query: aircraft->{
180
- top: 10
181
- order_by: 1
182
- where: region != NULL
183
- group_by: region
184
- nest: by_state is {
185
- top: 10
186
- order_by: 1 desc
187
- having: aircraft_count > 50
188
- group_by: state
189
- aggregate: aircraft_count
190
- }
191
- }
192
- `
193
- )
194
- .run();
195
- expect(result.data.path(0, 'by_state', 0, 'state').value).toBe('VA');
196
- });
197
-
198
- testIf(runtime.supportsNesting)(
199
- 'model: turtle having on main',
200
- async () => {
201
- const result = await expressionModel
202
- .loadQuery(
203
- `
204
- query: aircraft->{
205
- order_by: 2 asc
206
- having: aircraft_count ? >500
207
- group_by: region
208
- aggregate: aircraft_count
209
- nest: by_state is {
210
- order_by: 2 asc
211
- having: aircraft_count >45
212
- group_by: state
213
- aggregate: aircraft_count
214
- nest: by_city is {
215
- order_by: 2 asc
216
- having: aircraft_count ? >5
217
- group_by: city
218
- aggregate: aircraft_count
219
- }
220
- }
221
- }
222
- `
223
- )
224
- .run();
225
- expect(
226
- result.data.path(0, 'by_state', 0, 'by_city', 0, 'city').value
227
- ).toBe('ALBUQUERQUE');
228
- }
229
- );
230
-
231
- // bigquery doesn't like to partition by floats,
232
- testIf(runtime.supportsNesting)(
233
- 'model: having float group by partition',
234
- async () => {
235
- await expect(runtime).queryMatches(
236
- `${expressionModelText}
237
- query: aircraft_models->{
238
- order_by: 1
239
- where: seats_bucketed > 0
240
- having: aircraft_model_count > 400
241
- group_by: seats_bucketed
242
- aggregate: aircraft_model_count
243
- nest: foo is {
244
- group_by: engines
245
- aggregate: aircraft_model_count
246
- }
247
- }`,
248
- {aircraft_model_count: 448}
249
- );
250
- }
251
- );
252
-
253
- it('model: aggregate functions distinct min max', async () => {
254
- const result = await expressionModel
255
- .loadQuery(
256
- `
257
- query: aircraft_models->{
258
- aggregate:
259
- distinct_seats is count(distinct seats),
260
- boeing_distinct_seats is count(distinct seats) {?manufacturer ? 'BOEING'},
261
- min_seats is min(seats),
262
- cessna_min_seats is min(seats) {? manufacturer ? 'CESSNA'},
263
- max_seats is max(seats),
264
- cessna_max_seats is max(seats) {? manufacturer ? 'CESSNA'},
265
- min_code is min(aircraft_model_code),
266
- boeing_min_model is min(model) {? manufacturer ? 'BOEING'},
267
- max_model is max(model),
268
- boeing_max_model is max(model) {? manufacturer ? 'BOEING'},
269
- }
270
- `
271
- )
272
- .run();
273
- expect(result.data.path(0, 'distinct_seats').value).toBe(187);
274
- expect(result.data.path(0, 'boeing_distinct_seats').value).toBe(85);
275
- expect(result.data.path(0, 'min_seats').value).toBe(0);
276
- expect(result.data.path(0, 'cessna_min_seats').value).toBe(1);
277
- expect(result.data.path(0, 'max_seats').value).toBe(660);
278
- expect(result.data.path(0, 'min_code').value).toBe('0030109');
279
- expect(result.data.path(0, 'cessna_max_seats').value).toBe(14);
280
- expect(result.data.path(0, 'boeing_min_model').value).toBe('100');
281
- expect(result.data.path(0, 'max_model').value).toBe('ZWEIFEL PA18');
282
- expect(result.data.path(0, 'boeing_max_model').value).toBe('YL-15');
283
- });
284
-
285
- (databaseName !== 'bigquery' ? it.skip : it)(
286
- 'model: dates named',
287
- async () => {
288
- const result = await expressionModel
289
- .loadQuery(
290
- `
291
- query: table('malloytest.alltypes')->{
292
- group_by:
293
- t_date,
294
- t_date_month is t_date.month,
295
- t_date_year is t_date.year,
296
- t_timestamp,
297
- t_timestamp_date is t_timestamp.day,
298
- t_timestamp_hour is t_timestamp.hour,
299
- t_timestamp_minute is t_timestamp.minute,
300
- t_timestamp_second is t_timestamp.second,
301
- t_timestamp_month is t_timestamp.month,
302
- t_timestamp_year is t_timestamp.year,
303
- }
304
-
305
- `
306
- )
307
- .run();
308
- expect(result.data.path(0, 't_date').value).toEqual(
309
- new Date('2020-03-02')
310
- );
311
- expect(result.data.path(0, 't_date_month').value).toEqual(
312
- new Date('2020-03-01')
313
- );
314
- expect(result.data.path(0, 't_date_year').value).toEqual(
315
- new Date('2020-01-01')
316
- );
317
- expect(result.data.path(0, 't_timestamp').value).toEqual(
318
- new Date('2020-03-02T12:35:56.000Z')
319
- );
320
- expect(result.data.path(0, 't_timestamp_second').value).toEqual(
321
- new Date('2020-03-02T12:35:56.000Z')
322
- );
323
- expect(result.data.path(0, 't_timestamp_minute').value).toEqual(
324
- new Date('2020-03-02T12:35:00.000Z')
325
- );
326
- expect(result.data.path(0, 't_timestamp_hour').value).toEqual(
327
- new Date('2020-03-02T12:00:00.000Z')
328
- );
329
- expect(result.data.path(0, 't_timestamp_date').value).toEqual(
330
- new Date('2020-03-02')
331
- );
332
- expect(result.data.path(0, 't_timestamp_month').value).toEqual(
333
- new Date('2020-03-01')
334
- );
335
- expect(result.data.path(0, 't_timestamp_year').value).toEqual(
336
- new Date('2020-01-01')
337
- );
338
- }
339
- );
340
-
341
- it.skip('defines in model', async () => {
342
- // const result1 = await model.makeQuery(`
343
- // define a is ('malloytest.alltypes');
344
- // explore a | reduce x is count(*)
345
- // `);
346
- // const result = await model.makeQuery(`
347
- // define a is ('malloytest.alltypes');
348
- // explore a | reduce x is count(*)
349
- // `);
350
- });
351
-
352
- it('named query metadata undefined', async () => {
353
- const result = await expressionModel
354
- .loadQuery(
355
- `
356
- query: aircraft->{
357
- aggregate: aircraft_count is count()
358
- }
359
- `
360
- )
361
- .run();
362
- // TODO The result explore should really be unnamed. This test currently
363
- // inspects inner information because we have no way to have unnamed
364
- // explores today.
365
- // expect(result.getResultExplore().name).toBe(undefined);
366
- expect(result._queryResult.queryName).toBe(undefined);
367
- });
368
-
369
- it('named query metadata named', async () => {
370
- const result = await expressionModel
371
- .loadQuery(
372
- `
373
- query: aircraft->by_manufacturer
374
- `
375
- )
376
- .run();
377
- expect(result.resultExplore.name).toBe('by_manufacturer');
378
- });
379
-
380
- it('named query metadata named head of pipeline', async () => {
381
- const result = await expressionModel
382
- .loadQuery(
383
- `
384
- query: aircraft->by_manufacturer->{ aggregate: c is count()}
385
- `
386
- )
387
- .run();
388
- // TODO Same as above -- this test should check the explore name
389
- // expect(result.getResultExplore().name).toBe(undefined);
390
- expect(result._queryResult.queryName).toBe(undefined);
391
- });
392
-
393
- it('filtered explores basic', async () => {
394
- const result = await expressionModel
395
- .loadQuery(
396
- `
397
- source: b is aircraft{ where: aircraft_models.manufacturer ? ~'B%' }
398
-
399
- query: b->{aggregate: m_count is count(distinct aircraft_models.manufacturer) }
400
- `
401
- )
402
- .run();
403
- expect(result.data.path(0, 'm_count').value).toBe(63);
404
- });
405
-
406
- testIf(runtime.supportsNesting)(
407
- 'query with aliasname used twice',
408
- async () => {
409
- const result = await expressionModel
410
- .loadQuery(
411
- `
412
- query: aircraft->{
413
- group_by: first is substr(city,1,1)
414
- aggregate: aircraft_count is count()
415
- nest: aircraft is {
416
- group_by: first_two is substr(city,1,2)
417
- aggregate: aircraft_count is count()
418
- nest: aircraft is {
419
- group_by: first_three is substr(city,1,3)
420
- aggregate: aircraft_count is count()
421
- }
422
- }
423
- } -> {
424
- project:
425
- aircraft.aircraft.first_three
426
- aircraft_count
427
- order_by: 2 desc, 1
428
- }
429
- `
430
- )
431
- .run();
432
- expect(result.data.path(0, 'first_three').value).toBe('SAB');
433
- }
434
- );
435
-
436
- it.skip('join foreign_key reverse', async () => {
437
- const result = await expressionModel
438
- .loadQuery(
439
- `
440
- source: a is table('malloytest.aircraft') {
441
- primary_key: tail_num
442
- measure: aircraft_count is count()
443
- }
444
- query: table('malloytest.aircraft_models') {
445
- primary_key: aircraft_model_code
446
- join_many: a on a.aircraft_model_code
447
-
448
- some_measures is {
449
- aggregate: am_count is count()
450
- aggregate: a.aircraft_count
451
- }
452
- } -> some_measure
453
- `
454
- )
455
- .run();
456
- expect(result.data.path(0, 'first_three').value).toBe('SAN');
457
- });
458
-
459
- it('joined filtered explores', async () => {
460
- const result = await expressionModel
461
- .loadQuery(
462
- `
463
- source: a_models is table('malloytest.aircraft_models'){
464
- where: manufacturer ? ~'B%'
465
- primary_key: aircraft_model_code
466
- measure:model_count is count()
467
- }
468
-
469
- source: aircraft2 is table('malloytest.aircraft'){
470
- join_one: model is a_models with aircraft_model_code
471
- measure: aircraft_count is count()
472
- }
473
-
474
- query: aircraft2->{
475
- aggregate:
476
- model.model_count
477
- aircraft_count
478
- }
479
- `
480
- )
481
- .run();
482
- expect(result.data.path(0, 'model_count').value).toBe(244);
483
- expect(result.data.path(0, 'aircraft_count').value).toBe(3599);
484
- });
485
-
486
- it('joined filtered explores with dependancies', async () => {
487
- const result = await expressionModel
488
- .loadQuery(
489
- `
490
- source: bo_models is
491
- from(
492
- table('malloytest.aircraft_models') {? manufacturer ? ~ 'BO%' }
493
- -> { project: aircraft_model_code, manufacturer, seats }
494
- ) {
495
- primary_key: aircraft_model_code
496
- measure: bo_count is count()
497
- }
498
-
499
- source: b_models is
500
- from(
501
- table('malloytest.aircraft_models') {? manufacturer ? ~ 'B%' }
502
- -> { project: aircraft_model_code, manufacturer, seats }
503
- ) {
504
- where: bo_models.seats > 200
505
- primary_key: aircraft_model_code
506
- measure: b_count is count()
507
- join_one: bo_models with aircraft_model_code
508
- }
509
-
510
- source: models is table('malloytest.aircraft_models') {
511
- join_one: b_models with aircraft_model_code
512
- measure: model_count is count()
513
- }
514
-
515
- query: models -> {
516
- aggregate: model_count
517
- aggregate: b_models.b_count
518
- -- aggregate: b_models.bo_models.bo_count
519
- }
520
- `
521
- )
522
- .run();
523
- expect(result.data.path(0, 'model_count').value).toBe(60461);
524
- expect(result.data.path(0, 'b_count').value).toBe(355);
525
- });
526
-
527
- it('group by explore - simple group by', async () => {
528
- const result = await expressionModel
529
- .loadQuery(
530
- `
531
- query: aircraft->{
532
- group_by: aircraft_models
533
- aggregate: aircraft_count
534
- }
535
- `
536
- )
537
- .run();
538
- expect(result.data.path(0, 'aircraft_count').value).toBe(58);
539
- expect(result.data.path(0, 'aircraft_models_id').value).toBe('7102802');
540
- });
541
-
542
- it('group by explore - pipeline', async () => {
543
- const result = await expressionModel
544
- .loadQuery(
545
- `
546
- query: aircraft->{
547
- group_by: aircraft_models
548
- aggregate: aircraft_count
549
- } -> {
550
- group_by: aircraft_models.manufacturer
551
- aggregate: aircraft_count is aircraft_count.sum()
552
- }
553
- `
554
- )
555
- .run();
556
- expect(result.data.path(0, 'aircraft_count').value).toBe(1048);
557
- expect(result.data.path(0, 'manufacturer').value).toBe('CESSNA');
558
- });
559
-
560
- it('group by explore - pipeline 2 levels', async () => {
561
- const result = await expressionModel
562
- .loadQuery(
563
- `
564
- source: f is table('malloytest.flights'){
565
- join_one: a is table('malloytest.aircraft') {
566
- join_one: state_facts is table('malloytest.state_facts'){primary_key: state} with state
567
- } on tail_num = a.tail_num
568
- }
569
-
570
- query: f-> {
571
- group_by: a.state_facts
572
- aggregate: flight_count is count()
573
- } -> {
574
- group_by: state_facts.popular_name
575
- aggregate: flight_count is flight_count.sum()
576
- }
577
- `
578
- )
579
- .run();
580
- // console.log(result.data.toObject());
581
- expect(result.data.path(0, 'flight_count').value).toBe(199726);
582
- expect(result.data.path(0, 'popular_name').value).toBe('Isabella');
583
- });
584
- });
585
-
586
- describe.each(runtimes.runtimeList)('%s', (databaseName, runtime) => {
587
- const sqlEq = mkSqlEqWith(runtime, {
588
- malloy: `+ {
589
- dimension: friName is 'friday'
590
- dimension: friDay is 5
591
- dimension: satName is 'saturday'
592
- dimension: satDay is 6
593
- }`,
594
- });
595
-
596
- describe.skip('alternations with not-eq', () => {
597
- /*
598
- Here's the desired truth table ...
599
-
600
- x x != y | z
601
- ====== ============
602
- y false
603
- z false
604
- ^[yz] true
605
- */
606
- test('x not-eq y or z : x eq y', async () => {
607
- const result = await sqlEq('6 != (6|7)', false);
608
- expect(result).isSqlEq();
609
- });
610
- test('x not-eq y or z : x eq z', async () => {
611
- const result = await sqlEq('7 != (6|7)', false);
612
- expect(result).isSqlEq();
613
- });
614
- test('x not-eq y or z : else', async () => {
615
- const result = await sqlEq('5 != (6|7)', true);
616
- expect(result).isSqlEq();
617
- });
618
- /*
619
- Writing this the old way, should have the same truth table ...
620
- x != y & != z
621
- */
622
- test('x not-eq y and not-eq z : x eq y', async () => {
623
- const result = await sqlEq('6 != (6 & !=7)', false);
624
- expect(result).isSqlEq();
625
- });
626
- test('x not-eq y and not-eq z : x eq z', async () => {
627
- const result = await sqlEq('7 != (6 & != 7)', false);
628
- expect(result).isSqlEq();
629
- });
630
- test('x not-eq y and not-eq z : else', async () => {
631
- const result = await sqlEq('5 != (6 & !=7)', true);
632
- expect(result).isSqlEq();
633
- });
634
- });
635
-
636
- describe('string literal quoting', () => {
637
- const dq = '"';
638
- const tick = "'";
639
- const back = '\\';
640
- test('quote single character', async () => {
641
- expect(await sqlEq(`'${back}x'`, 'x')).isSqlEq();
642
- });
643
- test('quote single quote', async () => {
644
- expect(await sqlEq(`'${back}${tick}'`, tick)).isSqlEq();
645
- });
646
- test('quote double quote', async () => {
647
- await expect(runtime).queryMatches(
648
- `sql: x is {connection:"${databaseName}" select:"""SELECT 1 as x"""}
649
- query: from_sql(x) -> {
650
- project: double_quote is "${back}${dq}"
651
- }
652
- `,
653
- {double_quote: '"'}
654
- );
655
- });
656
- test('quote backslash', async () => {
657
- expect(await sqlEq(`'${back}${back}'`, back)).isSqlEq();
658
- });
659
- });
660
-
661
- test('nullish ?? operator', async () => {
662
- await expect(runtime).queryMatches(
663
- `sql: nullTest is { connection: "${databaseName}" select: """
664
- SELECT '' as null_value, '' as string_value
665
- UNION ALL SELECT null, 'correct'
666
- """ }
667
- query: from_sql(nullTest) -> {
668
- where: null_value = null
669
- project:
670
- found_null is null_value ?? 'correct',
671
- else_pass is string_value ?? 'incorrect'
672
- literal_null is null ?? 'correct'
673
- }`,
674
- {found_null: 'correct', else_pass: 'correct', literal_null: 'correct'}
675
- );
676
- });
677
-
678
- test('dimension expressions expanded with parens properly', async () => {
679
- await expect(runtime).queryMatches(
680
- `
681
- sql: tbl is { connection: "${databaseName}" select: """SELECT 1 as n"""}
682
- query: from_sql(tbl) + {
683
- dimension: fot is (false) or (true)
684
- } -> {
685
- project:
686
- no_paren is false and fot
687
- paren is false and (fot)
688
- }
689
- `,
690
- {paren: false, no_paren: false}
691
- );
692
- });
693
- });
694
-
695
- afterAll(async () => {
696
- await runtimes.closeAll();
697
- });
698
- };
699
-
700
32
  /*
701
33
  * This test file reuses common tests definitions.
702
34
  * For actual test development please go to: test/src/databases/shared/expr.spec.ts