123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import { AssociationPath, Attribute, sql } from '@sequelize/core';
- import { Unquote } from '@sequelize/core/_non-semver-use-at-your-own-risk_/expression-builders/dialect-aware-fn.js';
- import {
- parseAttributeSyntax,
- parseNestedJsonKeySyntax,
- } from '@sequelize/core/_non-semver-use-at-your-own-risk_/utils/attribute-syntax.js';
- import { expect } from 'chai';
- describe('parseAttributeSyntax', () => {
- it('parses simple attributes', () => {
- expect(parseAttributeSyntax('foo')).to.deep.eq(new Attribute('foo'));
- });
- it('parses simple associations', () => {
- expect(parseAttributeSyntax('$bar$')).to.deep.eq(new Attribute('bar'));
- expect(parseAttributeSyntax('$foo.bar$')).to.deep.eq(new AssociationPath(['foo'], 'bar'));
- expect(parseAttributeSyntax('$foo.zzz.bar$')).to.deep.eq(
- new AssociationPath(['foo', 'zzz'], 'bar'),
- );
- });
- it('throws for unbalanced association syntax', () => {
- // The error points at the erroneous character each time, but we only test the first one
- expect(() => parseAttributeSyntax('foo$')).to
- .throwWithCause(`Failed to parse syntax of attribute. Parse error at index 3:
- foo$
- ^`);
- expect(() => parseAttributeSyntax('$foo')).to
- .throwWithCause(`Failed to parse syntax of attribute. Parse error at index 4:
- $foo
- ^`);
- });
- it('parses cast syntax', () => {
- expect(parseAttributeSyntax('foo::bar')).to.deep.eq(sql.cast(new Attribute('foo'), 'bar'));
- });
- it('parses consecutive casts', () => {
- expect(parseAttributeSyntax('foo::bar::baz')).to.deep.eq(
- sql.cast(sql.cast(new Attribute('foo'), 'bar'), 'baz'),
- );
- });
- it('parses modifier syntax', () => {
- expect(parseAttributeSyntax('foo:unquote')).to.deep.eq(sql.unquote(new Attribute('foo')));
- });
- it('parses consecutive modifiers', () => {
- expect(parseAttributeSyntax('foo:unquote:unquote')).to.deep.eq(
- sql.unquote(sql.unquote(new Attribute('foo'))),
- );
- });
- it('parses casts and modifiers', () => {
- expect(parseAttributeSyntax('textAttr::json:unquote::integer')).to.deep.eq(
- sql.cast(sql.unquote(sql.cast(new Attribute('textAttr'), 'json')), 'integer'),
- );
- });
- it('treats everything after ::/: as a cast/modifier', () => {
- // "json.property" is treated as a cast, not a JSON path
- // but it's not a valid cast, so it will throw
- expect(() => parseAttributeSyntax('textAttr::json.property')).to
- .throwWithCause(`Failed to parse syntax of attribute. Parse error at index 14:
- textAttr::json.property
- ^`);
- // "json.property" is treated as a modifier (which does not exist and will throw), not a JSON path
- expect(() => parseAttributeSyntax('textAttr:json.property')).to
- .throwWithCause(`Failed to parse syntax of attribute. Parse error at index 13:
- textAttr:json.property
- ^`);
- });
- it('parses JSON paths', () => {
- expect(parseAttributeSyntax('foo.bar')).to.deep.eq(sql.jsonPath(new Attribute('foo'), ['bar']));
- expect(parseAttributeSyntax('foo."bar"')).to.deep.eq(
- sql.jsonPath(new Attribute('foo'), ['bar']),
- );
- expect(parseAttributeSyntax('foo."bar\\""')).to.deep.eq(
- sql.jsonPath(new Attribute('foo'), ['bar"']),
- );
- expect(parseAttributeSyntax('foo."bar\\\\"')).to.deep.eq(
- sql.jsonPath(new Attribute('foo'), ['bar\\']),
- );
- expect(parseAttributeSyntax('foo[123]')).to.deep.eq(sql.jsonPath(new Attribute('foo'), [123]));
- expect(parseAttributeSyntax('foo."123"')).to.deep.eq(
- sql.jsonPath(new Attribute('foo'), ['123']),
- );
- expect(parseAttributeSyntax('foo.abc[0]."def"[1]')).to.deep.eq(
- sql.jsonPath(new Attribute('foo'), ['abc', 0, 'def', 1]),
- );
- });
- });
- describe('parseNestedJsonKeySyntax', () => {
- it('parses JSON paths', () => {
- expect(parseNestedJsonKeySyntax('foo.bar')).to.deep.eq({
- pathSegments: ['foo', 'bar'],
- castsAndModifiers: [],
- });
- expect(parseNestedJsonKeySyntax('abc-def.ijk-lmn')).to.deep.eq({
- pathSegments: ['abc-def', 'ijk-lmn'],
- castsAndModifiers: [],
- });
- expect(parseNestedJsonKeySyntax('"foo"."bar"')).to.deep.eq({
- pathSegments: ['foo', 'bar'],
- castsAndModifiers: [],
- });
- expect(parseNestedJsonKeySyntax('[0]')).to.deep.eq({
- pathSegments: [0],
- castsAndModifiers: [],
- });
- });
- it('parses casts and modifiers', () => {
- expect(parseNestedJsonKeySyntax('[0]:unquote::text:unquote::text')).to.deep.eq({
- pathSegments: [0],
- castsAndModifiers: [Unquote, 'text', Unquote, 'text'],
- });
- });
- });
|