@malloydata/malloy-tests 0.0.246-dev250320195825 → 0.0.246-dev250320220920

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
@@ -21,14 +21,14 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@jest/globals": "^29.4.3",
24
- "@malloydata/db-bigquery": "^0.0.246-dev250320195825",
25
- "@malloydata/db-duckdb": "^0.0.246-dev250320195825",
26
- "@malloydata/db-postgres": "^0.0.246-dev250320195825",
27
- "@malloydata/db-snowflake": "^0.0.246-dev250320195825",
28
- "@malloydata/db-trino": "^0.0.246-dev250320195825",
29
- "@malloydata/malloy": "^0.0.246-dev250320195825",
30
- "@malloydata/malloy-tag": "^0.0.246-dev250320195825",
31
- "@malloydata/render": "^0.0.246-dev250320195825",
24
+ "@malloydata/db-bigquery": "^0.0.246-dev250320220920",
25
+ "@malloydata/db-duckdb": "^0.0.246-dev250320220920",
26
+ "@malloydata/db-postgres": "^0.0.246-dev250320220920",
27
+ "@malloydata/db-snowflake": "^0.0.246-dev250320220920",
28
+ "@malloydata/db-trino": "^0.0.246-dev250320220920",
29
+ "@malloydata/malloy": "^0.0.246-dev250320220920",
30
+ "@malloydata/malloy-tag": "^0.0.246-dev250320220920",
31
+ "@malloydata/render": "^0.0.246-dev250320220920",
32
32
  "events": "^3.3.0",
33
33
  "jsdom": "^22.1.0",
34
34
  "luxon": "^2.4.0",
@@ -38,5 +38,5 @@
38
38
  "@types/jsdom": "^21.1.1",
39
39
  "@types/luxon": "^2.4.0"
40
40
  },
41
- "version": "0.0.246-dev250320195825"
41
+ "version": "0.0.246-dev250320220920"
42
42
  }
@@ -8,6 +8,7 @@
8
8
  import {RuntimeList, allDatabases} from '../../runtimes';
9
9
  import '../../util/db-jest-matchers';
10
10
  import {databasesFromEnvironmentOr} from '../../util';
11
+ import {DateTime as LuxonDateTime} from 'luxon';
11
12
 
12
13
  const runtimes = new RuntimeList(databasesFromEnvironmentOr(allDatabases));
13
14
 
@@ -349,4 +350,262 @@ describe.each(runtimes.runtimeList)('filter expressions %s', (dbName, db) => {
349
350
  }`).malloyResultMatches(facts, [{t: 'false'}, {t: 'true'}]);
350
351
  });
351
352
  });
353
+
354
+ type TL = 'timeLiteral';
355
+ type TS = {type: 'timestamp'};
356
+
357
+ describe('temporal filters', () => {
358
+ function ts(t: string): string {
359
+ const node: TL = 'timeLiteral';
360
+ const typeDef: TS = {type: 'timestamp'};
361
+ const n = {node, typeDef, literal: t};
362
+ return db.dialect.sqlLiteralTime({}, n);
363
+ }
364
+
365
+ const fTimestamp = 'yyyy-LL-dd HH:mm:ss';
366
+
367
+ /**
368
+ * Create a source for testing a range. It will have five rows
369
+ * { t: 1 second before start, n: 'before' }
370
+ * { t: start, n: 'first' }
371
+ * { t: 1 second before end, n: 'last' }
372
+ * { t: end, n: 'zend' }
373
+ * { t: NULL n: ' null ' }
374
+ * Use malloyResultMatches(range, inRange) or (range, notInRange)
375
+ */
376
+ const inRange = [{n: 'first'}, {n: 'last'}];
377
+ const notInRange = [{n: 'before'}, {n: 'zend'}];
378
+ function mkRange(start: string, end: string) {
379
+ const begin = LuxonDateTime.fromFormat(start, fTimestamp);
380
+ const b4 = begin.minus({second: 1});
381
+ const last = LuxonDateTime.fromFormat(end, fTimestamp).minus({second: 1});
382
+ const rangeModel = `
383
+ query: range is ${dbName}.sql("""
384
+ SELECT ${ts(b4.toFormat(fTimestamp))} AS ${q`t`}, 'before' AS ${q`n`}
385
+ UNION ALL SELECT ${ts(start)}, 'first'
386
+ UNION ALL SELECT ${ts(last.toFormat(fTimestamp))} , 'last'
387
+ UNION ALL SELECT ${ts(end)}, 'zend'
388
+ UNION ALL SELECT NULL, ' null '
389
+ """)
390
+ -> {select: *; order_by: n}`;
391
+ return db.loadModel(rangeModel);
392
+ }
393
+
394
+ /**
395
+ * All the relative time tests need a way to set what time it is now
396
+ */
397
+ function nowIs(timeStr: string) {
398
+ const spyNow = jest.spyOn(db.dialect, 'sqlNowExpr');
399
+ spyNow.mockImplementation(() => ts(timeStr));
400
+ }
401
+ afterEach(() => jest.restoreAllMocks());
402
+
403
+ test('null', async () => {
404
+ const range = mkRange('2001-01-01 00:00:00', '2002-01-01 00:00:00');
405
+ await expect(`
406
+ run: range + { where: t ~ f'null' }
407
+ `).malloyResultMatches(range, [{n: ' null '}]);
408
+ });
409
+ test('not null', async () => {
410
+ const range = mkRange('2001-01-01 00:00:00', '2002-01-01 00:00:00');
411
+ await expect(`
412
+ run: range + { where: t ~ f'not null' }
413
+ `).malloyResultMatches(range, [
414
+ {n: 'before'},
415
+ {n: 'first'},
416
+ {n: 'last'},
417
+ {n: 'zend'},
418
+ ]);
419
+ });
420
+ test('year literal', async () => {
421
+ const range = mkRange('2001-01-01 00:00:00', '2002-01-01 00:00:00');
422
+ await expect(`
423
+ run: range + { where: t ~ f'2001' }
424
+ `).malloyResultMatches(range, inRange);
425
+ });
426
+ test('not month literal', async () => {
427
+ const range = mkRange('2001-06-01 00:00:00', '2001-07-01 00:00:00');
428
+ await expect(`
429
+ run: range + { where: t ~ f'not 2001-06' }
430
+ `).malloyResultMatches(range, notInRange);
431
+ });
432
+ test('day literal', async () => {
433
+ const range = mkRange('2001-06-15 00:00:00', '2001-06-16 00:00:00');
434
+ await expect(`
435
+ run: range + { where: t ~ f'2001-06-15' }
436
+ `).malloyResultMatches(range, inRange);
437
+ });
438
+ test('hour literal', async () => {
439
+ const range = mkRange('2001-02-03 04:00:00', '2001-02-03 05:00:00');
440
+ await expect(`
441
+ run: range + { where: t ~ f'2001-02-03 04' }
442
+ `).malloyResultMatches(range, inRange);
443
+ });
444
+ test('minute literal', async () => {
445
+ const range = mkRange('2001-02-03 04:05:00', '2001-02-03 04:06:00');
446
+ await expect(`
447
+ run: range + { where: t ~ f'2001-02-03 04:05' }
448
+ `).malloyResultMatches(range, inRange);
449
+ });
450
+ test('quarter literal', async () => {
451
+ const range = mkRange('2001-01-01 00:00:00', '2001-04-01 00:00:00');
452
+ await expect(`
453
+ run: range + { where: t ~ f'2001-Q1' }
454
+ `).malloyResultMatches(range, inRange);
455
+ });
456
+ test('week literal', async () => {
457
+ const range = mkRange('2023-01-01 00:00:00', '2023-01-08 00:00:00');
458
+ await expect(`
459
+ run: range + { where: t ~ f'2023-01-01-WK' }
460
+ `).malloyResultMatches(range, inRange);
461
+ });
462
+ test('today', async () => {
463
+ nowIs('2001-02-03 12:00:00');
464
+ const range = mkRange('2001-02-03 00:00:00', '2001-02-04 00:00:00');
465
+ await expect(`
466
+ run: range + { where: t ~ f'today' }
467
+ `).malloyResultMatches(range, inRange);
468
+ });
469
+ test('yesterday', async () => {
470
+ nowIs('2001-02-03 12:00:00');
471
+ const range = mkRange('2001-02-02 00:00:00', '2001-02-03 00:00:00');
472
+ await expect(`
473
+ run: range + { where: t ~ f'yesterday' }
474
+ `).malloyResultMatches(range, inRange);
475
+ });
476
+ test('tomorrow', async () => {
477
+ nowIs('2001-02-03 12:00:00');
478
+ const range = mkRange('2001-02-04 00:00:00', '2001-02-05 00:00:00');
479
+ await expect(`
480
+ run: range + { where: t ~ f'tomorrow' }
481
+ `).malloyResultMatches(range, inRange);
482
+ });
483
+ test('this week', async () => {
484
+ nowIs('2023-01-03 00:00:00');
485
+ const range = mkRange('2023-01-01 00:00:00', '2023-01-08 00:00:00');
486
+ await expect(`
487
+ run: range + { where: t ~ f'this week' }
488
+ `).malloyResultMatches(range, inRange);
489
+ });
490
+ test('last month', async () => {
491
+ nowIs('2001-02-01 12:00:00');
492
+ const range = mkRange('2001-01-01 00:00:00', '2001-02-01 00:00:00');
493
+ await expect(`
494
+ run: range + { where: t ~ f'last month' }
495
+ `).malloyResultMatches(range, inRange);
496
+ });
497
+ test('next quarter', async () => {
498
+ nowIs('2001-01-02 12:00:00');
499
+ const range = mkRange('2001-04-01 00:00:00', '2001-07-01 00:00:00');
500
+ await expect(`
501
+ run: range + { where: t ~ f'next quarter' }
502
+ `).malloyResultMatches(range, inRange);
503
+ });
504
+ test('this year', async () => {
505
+ nowIs('2001-01-02 12:00:00');
506
+ const range = mkRange('2001-01-01 00:00:00', '2002-01-01 00:00:00');
507
+ await expect(`
508
+ run: range + { where: t ~ f'this year' }
509
+ `).malloyResultMatches(range, inRange);
510
+ });
511
+ // 2023-01-01 is a sunday
512
+ test('(last) sunday', async () => {
513
+ nowIs('2023-01-03 00:00:00');
514
+ const range = mkRange('2023-01-01 00:00:00', '2023-01-02 00:00:00');
515
+ await expect(`
516
+ run: range + { where: t ~ f'sunday' }
517
+ `).malloyResultMatches(range, inRange);
518
+ });
519
+ test('last monday', async () => {
520
+ nowIs('2023-01-03 00:00:00');
521
+ const range = mkRange('2023-01-02 00:00:00', '2023-01-03 00:00:00');
522
+ await expect(`
523
+ run: range + { where: t ~ f'last monday' }
524
+ `).malloyResultMatches(range, inRange);
525
+ });
526
+ test('last-tuesday', async () => {
527
+ nowIs('2023-01-03 00:00:00');
528
+ const range = mkRange('2022-12-27 00:00:00', '2022-12-28 00:00:00');
529
+ await expect(`
530
+ run: range + { where: t ~ f'tuesday' }
531
+ `).malloyResultMatches(range, inRange);
532
+ });
533
+ test('last-wednesday', async () => {
534
+ nowIs('2023-01-03 00:00:00');
535
+ const range = mkRange('2022-12-28 00:00:00', '2022-12-29 00:00:00');
536
+ await expect(`
537
+ run: range + { where: t ~ f'wednesday' }
538
+ `).malloyResultMatches(range, inRange);
539
+ });
540
+ test('last-thursday', async () => {
541
+ nowIs('2023-01-03 00:00:00');
542
+ const range = mkRange('2022-12-29 00:00:00', '2022-12-30 00:00:00');
543
+ await expect(`
544
+ run: range + { where: t ~ f'thursday' }
545
+ `).malloyResultMatches(range, inRange);
546
+ });
547
+ test('last-friday', async () => {
548
+ nowIs('2023-01-03 00:00:00');
549
+ const range = mkRange('2022-12-30 00:00:00', '2022-12-31 00:00:00');
550
+ await expect(`
551
+ run: range + { where: t ~ f'friday' }
552
+ `).malloyResultMatches(range, inRange);
553
+ });
554
+ test('last saturday', async () => {
555
+ nowIs('2023-01-03 00:00:00');
556
+ const range = mkRange('2022-12-31 00:00:00', '2023-01-01 00:00:00');
557
+ await expect(`
558
+ run: range + { where: t ~ f'last saturday' }
559
+ `).malloyResultMatches(range, inRange);
560
+ });
561
+ test('next sunday', async () => {
562
+ nowIs('2023-01-03 00:00:00');
563
+ const range = mkRange('2023-01-08 00:00:00', '2023-01-09 00:00:00');
564
+ await expect(`
565
+ run: range + { where: t ~ f'next sunday' }
566
+ `).malloyResultMatches(range, inRange);
567
+ });
568
+ test('next monday', async () => {
569
+ nowIs('2023-01-03 00:00:00');
570
+ const range = mkRange('2023-01-09 00:00:00', '2023-01-10 00:00:00');
571
+ await expect(`
572
+ run: range + { where: t ~ f'next monday' }
573
+ `).malloyResultMatches(range, inRange);
574
+ });
575
+ test('next tuesday', async () => {
576
+ nowIs('2023-01-03 00:00:00');
577
+ const range = mkRange('2023-01-10 00:00:00', '2023-01-11 00:00:00');
578
+ await expect(`
579
+ run: range + { where: t ~ f'next tuesday' }
580
+ `).malloyResultMatches(range, inRange);
581
+ });
582
+ test('next wednesday', async () => {
583
+ nowIs('2023-01-03 00:00:00');
584
+ const range = mkRange('2023-01-04 00:00:00', '2023-01-05 00:00:00');
585
+ await expect(`
586
+ run: range + { where: t ~ f'next wednesday' }
587
+ `).malloyResultMatches(range, inRange);
588
+ });
589
+ test('next thursday', async () => {
590
+ nowIs('2023-01-03 00:00:00');
591
+ const range = mkRange('2023-01-05 00:00:00', '2023-01-06 00:00:00');
592
+ await expect(`
593
+ run: range + { where: t ~ f'next thursday' }
594
+ `).malloyResultMatches(range, inRange);
595
+ });
596
+ test('next friday', async () => {
597
+ nowIs('2023-01-03 00:00:00');
598
+ const range = mkRange('2023-01-06 00:00:00', '2023-01-07 00:00:00');
599
+ await expect(`
600
+ run: range + { where: t ~ f'next friday' }
601
+ `).malloyResultMatches(range, inRange);
602
+ });
603
+ test('next saturday', async () => {
604
+ nowIs('2023-01-03 00:00:00');
605
+ const range = mkRange('2023-01-07 00:00:00', '2023-01-08 00:00:00');
606
+ await expect(`
607
+ run: range + { where: t ~ f'next saturday' }
608
+ `).malloyResultMatches(range, inRange);
609
+ });
610
+ });
352
611
  });
@@ -140,7 +140,8 @@ expect.extend({
140
140
  } catch (e) {
141
141
  return {
142
142
  pass: false,
143
- message: () => `Could not prepare query to run: ${e.message}`,
143
+ message: () =>
144
+ `Could not prepare query to run: ${e.message}\nQuery:\n${querySrc}`,
144
145
  };
145
146
  }
146
147