@malloydata/malloy-tests 0.0.247-dev250321153536 → 0.0.247-dev250321211927

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.247-dev250321153536",
25
- "@malloydata/db-duckdb": "^0.0.247-dev250321153536",
26
- "@malloydata/db-postgres": "^0.0.247-dev250321153536",
27
- "@malloydata/db-snowflake": "^0.0.247-dev250321153536",
28
- "@malloydata/db-trino": "^0.0.247-dev250321153536",
29
- "@malloydata/malloy": "^0.0.247-dev250321153536",
30
- "@malloydata/malloy-tag": "^0.0.247-dev250321153536",
31
- "@malloydata/render": "^0.0.247-dev250321153536",
24
+ "@malloydata/db-bigquery": "^0.0.247-dev250321211927",
25
+ "@malloydata/db-duckdb": "^0.0.247-dev250321211927",
26
+ "@malloydata/db-postgres": "^0.0.247-dev250321211927",
27
+ "@malloydata/db-snowflake": "^0.0.247-dev250321211927",
28
+ "@malloydata/db-trino": "^0.0.247-dev250321211927",
29
+ "@malloydata/malloy": "^0.0.247-dev250321211927",
30
+ "@malloydata/malloy-tag": "^0.0.247-dev250321211927",
31
+ "@malloydata/render": "^0.0.247-dev250321211927",
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.247-dev250321153536"
41
+ "version": "0.0.247-dev250321211927"
42
42
  }
@@ -352,17 +352,21 @@ describe.each(runtimes.runtimeList)('filter expressions %s', (dbName, db) => {
352
352
  });
353
353
 
354
354
  type TL = 'timeLiteral';
355
- type TS = {type: 'timestamp'};
356
355
 
357
356
  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};
357
+ function lit(t: string, type: 'timestamp' | 'date'): string {
358
+ const typeDef: {type: 'timestamp' | 'date'} = {type};
359
+ const timeLiteral: TL = 'timeLiteral';
360
+ const n = {
361
+ node: timeLiteral,
362
+ typeDef,
363
+ literal: t,
364
+ };
362
365
  return db.dialect.sqlLiteralTime({}, n);
363
366
  }
364
367
 
365
368
  const fTimestamp = 'yyyy-LL-dd HH:mm:ss';
369
+ const fDate = 'yyyy-LL-dd';
366
370
 
367
371
  /**
368
372
  * Create a source for testing a range. It will have five rows
@@ -378,13 +382,37 @@ describe.each(runtimes.runtimeList)('filter expressions %s', (dbName, db) => {
378
382
  function mkRange(start: string, end: string) {
379
383
  const begin = LuxonDateTime.fromFormat(start, fTimestamp);
380
384
  const b4 = begin.minus({second: 1});
381
- const last = LuxonDateTime.fromFormat(end, fTimestamp).minus({second: 1});
385
+ const last = lit(
386
+ LuxonDateTime.fromFormat(end, fTimestamp)
387
+ .minus({second: 1})
388
+ .toFormat(fTimestamp),
389
+ 'timestamp'
390
+ );
391
+ const before = lit(b4.toFormat(fTimestamp), 'timestamp');
382
392
  const rangeModel = `
383
393
  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'
394
+ SELECT ${before} AS ${q`t`}, 'before' AS ${q`n`}
395
+ UNION ALL SELECT ${lit(start, 'timestamp')}, 'first'
396
+ UNION ALL SELECT ${last} , 'last'
397
+ UNION ALL SELECT ${lit(end, 'timestamp')}, 'zend'
398
+ UNION ALL SELECT NULL, ' null '
399
+ """)
400
+ -> {select: *; order_by: n}`;
401
+ return db.loadModel(rangeModel);
402
+ }
403
+ function mkDateRange(start: string, end: string) {
404
+ const begin = LuxonDateTime.fromFormat(start, fDate);
405
+ const b4 = begin.minus({day: 1});
406
+ const last = LuxonDateTime.fromFormat(end, fDate).minus({day: 1});
407
+ const rangeModel = `
408
+ query: range is ${dbName}.sql("""
409
+ SELECT ${lit(
410
+ b4.toFormat(fDate),
411
+ 'date'
412
+ )} AS ${q`t`}, 'before' AS ${q`n`}
413
+ UNION ALL SELECT ${lit(start, 'date')}, 'first'
414
+ UNION ALL SELECT ${lit(last.toFormat(fDate), 'date')} , 'last'
415
+ UNION ALL SELECT ${lit(end, 'date')}, 'zend'
388
416
  UNION ALL SELECT NULL, ' null '
389
417
  """)
390
418
  -> {select: *; order_by: n}`;
@@ -396,10 +424,123 @@ describe.each(runtimes.runtimeList)('filter expressions %s', (dbName, db) => {
396
424
  */
397
425
  function nowIs(timeStr: string) {
398
426
  const spyNow = jest.spyOn(db.dialect, 'sqlNowExpr');
399
- spyNow.mockImplementation(() => ts(timeStr));
427
+ spyNow.mockImplementation(() => lit(timeStr, 'timestamp'));
400
428
  }
401
429
  afterEach(() => jest.restoreAllMocks());
402
430
 
431
+ test('date after quarter', async () => {
432
+ const range = mkDateRange('2001-01-01', '2001-04-01');
433
+ await expect(`
434
+ run: range + { where: t ~ f'after 2001-Q1' }
435
+ `).malloyResultMatches(range, {n: 'zend'});
436
+ });
437
+ test('date before month', async () => {
438
+ const range = mkDateRange('2001-01-01', '2001-02-01');
439
+ await expect(`
440
+ run: range + { where: t ~ f'before 2001-01' }
441
+ `).malloyResultMatches(range, {n: 'before'});
442
+ });
443
+ test('date in year', async () => {
444
+ const range = mkDateRange('2001-01-01', '2002-01-01');
445
+ await expect(`
446
+ run: range + { where: t ~ f'2001' }
447
+ `).malloyResultMatches(range, inRange);
448
+ });
449
+ test('2 days ago', async () => {
450
+ nowIs('2001-01-15 12:00:00');
451
+ const range = mkRange('2001-01-13 00:00:00', '2001-01-14 00:00:00');
452
+ await expect(`
453
+ run: range + { where: t ~ f'2 days ago' }
454
+ `).malloyResultMatches(range, inRange);
455
+ });
456
+ test('2 days', async () => {
457
+ nowIs('2001-01-15 12:00:00');
458
+ const range = mkRange('2001-01-14 00:00:00', '2001-01-16 00:00:00');
459
+ await expect(`
460
+ run: range + { where: t ~ f'2 days' }
461
+ `).malloyResultMatches(range, inRange);
462
+ });
463
+ test('2 days from now', async () => {
464
+ nowIs('2001-01-15 12:00:00');
465
+ const range = mkRange('2001-01-17 00:00:00', '2001-01-18 00:00:00');
466
+ await expect(`
467
+ run: range + { where: t ~ f'2 days from now' }
468
+ `).malloyResultMatches(range, inRange);
469
+ });
470
+ test('2000 to 2001', async () => {
471
+ const range = mkRange('2000-01-01 00:00:00', '2001-01-01 00:00:00');
472
+ await expect(`
473
+ run: range + { where: t ~ f'2000 to 2001' }
474
+ `).malloyResultMatches(range, inRange);
475
+ });
476
+ test('next 2 days', async () => {
477
+ nowIs('2001-01-01 12:00:00');
478
+ const range = mkRange('2001-01-02 00:00:00', '2001-01-04 00:00:00');
479
+ await expect(`
480
+ run: range + { where: t ~ f'next 2 days' }
481
+ `).malloyResultMatches(range, inRange);
482
+ });
483
+ test('last 2 months', async () => {
484
+ nowIs('2001-01-01 12:00:00');
485
+ const range = mkRange('2000-11-01 00:00:00', '2001-01-01 00:00:00');
486
+ await expect(`
487
+ run: range + { where: t ~ f'last 2 months' }
488
+ `).malloyResultMatches(range, inRange);
489
+ });
490
+ test('before y2k', async () => {
491
+ const range = mkRange('2001-01-01 00:00:00', '2002-01-01 00:00:00');
492
+ await expect(`
493
+ run: range + { where: t ~ f'before 2001' }
494
+ `).malloyResultMatches(range, [{n: 'before'}]);
495
+ });
496
+ test('after y2k', async () => {
497
+ const range = mkRange('2001-01-01 00:00:00', '2002-01-01 00:00:00');
498
+ await expect(`
499
+ run: range + { where: t ~ f'after 2001' }
500
+ `).malloyResultMatches(range, [{n: 'zend'}]);
501
+ });
502
+ test('y2k for 1 minute', async () => {
503
+ const range = mkRange('2001-01-01 00:00:00', '2001-01-01 00:01:00');
504
+ await expect(`
505
+ run: range + { where: t ~ f'2001 for 1 minute' }
506
+ `).malloyResultMatches(range, inRange);
507
+ });
508
+ test('y2k for 2 hour', async () => {
509
+ const range = mkRange('2001-01-01 00:00:00', '2001-01-01 02:00:00');
510
+ await expect(`
511
+ run: range + { where: t ~ f'2001 for 2 hour' }
512
+ `).malloyResultMatches(range, inRange);
513
+ });
514
+ test('y2k for 1 day', async () => {
515
+ const range = mkRange('2001-01-01 00:00:00', '2001-01-02 00:00:00');
516
+ await expect(`
517
+ run: range + { where: t ~ f'2001 for 1 day' }
518
+ `).malloyResultMatches(range, inRange);
519
+ });
520
+ test('y2k for 1 week', async () => {
521
+ const range = mkRange('2001-01-01 00:00:00', '2001-01-08 00:00:00');
522
+ await expect(`
523
+ run: range + { where: t ~ f'2001 for 1 week' }
524
+ `).malloyResultMatches(range, inRange);
525
+ });
526
+ test('y2k for 1 month', async () => {
527
+ const range = mkRange('2001-01-01 00:00:00', '2001-02-01 00:00:00');
528
+ await expect(`
529
+ run: range + { where: t ~ f'2001 for 1 month' }
530
+ `).malloyResultMatches(range, inRange);
531
+ });
532
+ test('y2k for 1 quarter', async () => {
533
+ const range = mkRange('2001-01-01 00:00:00', '2001-04-01 00:00:00');
534
+ await expect(`
535
+ run: range + { where: t ~ f'2001 for 1 quarter' }
536
+ `).malloyResultMatches(range, inRange);
537
+ });
538
+ test('y2k for 1 year', async () => {
539
+ const range = mkRange('2001-01-01 00:00:00', '2002-01-01 00:00:00');
540
+ await expect(`
541
+ run: range + { where: t ~ f'2001 for 1 year' }
542
+ `).malloyResultMatches(range, inRange);
543
+ });
403
544
  test('null', async () => {
404
545
  const range = mkRange('2001-01-01 00:00:00', '2002-01-01 00:00:00');
405
546
  await expect(`