|
| 1 | +import { assert } from 'chai'; |
| 2 | +import { ObjectElement, MemberElement, toValue } from '@swagger-api/apidom-core'; |
| 3 | +import { InfoElement } from '@swagger-api/apidom-ns-openapi-3-0'; |
| 4 | + |
| 5 | +import { |
| 6 | + JSONPointerIndexError, |
| 7 | + JSONPointerTypeError, |
| 8 | + JSONPointerKeyError, |
| 9 | + JSONPointerEvaluateError, |
| 10 | + URIFragmentIdentifier, |
| 11 | +} from '../../../../src/index.js'; |
| 12 | +import { evaluate } from '../../../../src/evaluate/realms/apidom/index.js'; |
| 13 | + |
| 14 | +describe('evaluate', function () { |
| 15 | + context('ApiDOM realm - contextual evaluate', function () { |
| 16 | + const element = new ObjectElement({ |
| 17 | + foo: ['bar', 'baz'], |
| 18 | + '': 0, |
| 19 | + 'a/b': 1, |
| 20 | + 'c%d': 2, |
| 21 | + 'e^f': 3, |
| 22 | + 'g|h': 4, |
| 23 | + 'i\\j': 5, |
| 24 | + 'k"l': 6, |
| 25 | + ' ': 7, |
| 26 | + 'm~n': 8, |
| 27 | + }); |
| 28 | + |
| 29 | + context('RFC 6901 JSON String tests', function () { |
| 30 | + const jsonStringRepEntries = [ |
| 31 | + ['', toValue(element)], |
| 32 | + ['/foo', ['bar', 'baz']], |
| 33 | + ['/foo/0', 'bar'], |
| 34 | + ['/', 0], |
| 35 | + ['/a~1b', 1], |
| 36 | + ['/c%d', 2], |
| 37 | + ['/e^f', 3], |
| 38 | + ['/g|h', 4], |
| 39 | + ['/i\\j', 5], |
| 40 | + ['/k"l', 6], |
| 41 | + ['/ ', 7], |
| 42 | + ['/m~0n', 8], |
| 43 | + ]; |
| 44 | + |
| 45 | + jsonStringRepEntries.forEach(([jsonString, expected]) => { |
| 46 | + specify('should correctly evaluate JSON Pointer from JSON String', function () { |
| 47 | + const actual = toValue(evaluate(element, jsonString)); |
| 48 | + |
| 49 | + assert.deepEqual(actual, expected); |
| 50 | + }); |
| 51 | + }); |
| 52 | + }); |
| 53 | + |
| 54 | + context('RFC 6901 URI Fragment Identifier tests', function () { |
| 55 | + const fragmentRepEntries = [ |
| 56 | + ['#', toValue(element)], |
| 57 | + ['#/foo', ['bar', 'baz']], |
| 58 | + ['#/foo/0', 'bar'], |
| 59 | + ['#/', 0], |
| 60 | + ['#/a~1b', 1], |
| 61 | + ['#/c%25d', 2], |
| 62 | + ['#/e%5Ef', 3], |
| 63 | + ['#/g%7Ch', 4], |
| 64 | + ['#/i%5Cj', 5], |
| 65 | + ['#/k%22l', 6], |
| 66 | + ['#/%20', 7], |
| 67 | + ['#/m~0n', 8], |
| 68 | + ]; |
| 69 | + |
| 70 | + fragmentRepEntries.forEach(([fragment, expected]) => { |
| 71 | + specify('should correctly evaluate JSON Pointer from URI Fragment Identifier', function () { |
| 72 | + const actual = toValue(evaluate(element, URIFragmentIdentifier.from(fragment))); |
| 73 | + |
| 74 | + assert.deepEqual(actual, expected); |
| 75 | + }); |
| 76 | + }); |
| 77 | + }); |
| 78 | + |
| 79 | + context('given ApiDOM namespace element', function () { |
| 80 | + specify('should evaluate', function () { |
| 81 | + const infoElement = InfoElement.refract({ |
| 82 | + contact: { |
| 83 | + name: 'SwaggerExpert', |
| 84 | + |
| 85 | + }, |
| 86 | + }); |
| 87 | + const actual = toValue(evaluate(infoElement, '/contact/name')); |
| 88 | + |
| 89 | + assert.strictEqual(actual, 'SwaggerExpert'); |
| 90 | + }); |
| 91 | + }); |
| 92 | + |
| 93 | + context('invalid JSON Pointers (should throw errors)', function () { |
| 94 | + specify('should throw JSONPointerEvaluateError for invalid JSON Pointer', function () { |
| 95 | + assert.throws(() => evaluate(element, 'invalid-pointer'), JSONPointerEvaluateError); |
| 96 | + }); |
| 97 | + |
| 98 | + specify( |
| 99 | + 'should throw JSONPointerTypeError for accessing property on non-object/array', |
| 100 | + function () { |
| 101 | + assert.throws(() => evaluate(element, '/foo/0/bad'), JSONPointerTypeError); |
| 102 | + }, |
| 103 | + ); |
| 104 | + |
| 105 | + specify('should throw JSONPointerKeyError for non-existing key', function () { |
| 106 | + assert.throws(() => evaluate(element, '/nonexistent'), JSONPointerKeyError); |
| 107 | + }); |
| 108 | + |
| 109 | + specify('should throw JSONPointerIndexError for non-numeric array index', function () { |
| 110 | + assert.throws(() => evaluate(element, '/foo/x'), JSONPointerIndexError); |
| 111 | + }); |
| 112 | + |
| 113 | + specify('should throw JSONPointerIndexError for out-of-bounds array index', function () { |
| 114 | + assert.throws(() => evaluate(element, '/foo/5'), JSONPointerIndexError); |
| 115 | + }); |
| 116 | + |
| 117 | + specify('should throw JSONPointerIndexError for leading zero in array index', function () { |
| 118 | + assert.throws(() => evaluate(element, '/foo/01'), JSONPointerIndexError); |
| 119 | + }); |
| 120 | + |
| 121 | + specify('should throw JSONPointerIndexError for "-" when strictArrays is true', function () { |
| 122 | + assert.throws( |
| 123 | + () => evaluate(element, '/foo/-', { strictArrays: true }), |
| 124 | + JSONPointerIndexError, |
| 125 | + ); |
| 126 | + }); |
| 127 | + |
| 128 | + specify('should return undefined for "-" when strictArrays is false', function () { |
| 129 | + assert.strictEqual(evaluate(element, '/foo/-', { strictArrays: false }), undefined); |
| 130 | + }); |
| 131 | + |
| 132 | + specify( |
| 133 | + 'should throw JSONPointerKeyError for accessing chain of object properties that do not exist', |
| 134 | + function () { |
| 135 | + assert.throws(() => evaluate(element, '/missing/key'), JSONPointerKeyError); |
| 136 | + }, |
| 137 | + ); |
| 138 | + |
| 139 | + specify( |
| 140 | + 'should return undefined accessing object property that does not exist when strictObject is false', |
| 141 | + function () { |
| 142 | + assert.isUndefined(evaluate(element, '/missing', { strictObjects: false })); |
| 143 | + }, |
| 144 | + ); |
| 145 | + |
| 146 | + specify('should throw JSONPointerTypeError when evaluating on primitive', function () { |
| 147 | + assert.throws(() => evaluate('not-an-object', '/foo'), JSONPointerTypeError); |
| 148 | + }); |
| 149 | + |
| 150 | + specify( |
| 151 | + 'should throw JSONPointerTypeError when trying to access deep path on primitive', |
| 152 | + function () { |
| 153 | + assert.throws(() => evaluate({ foo: 42 }, '/foo/bar'), JSONPointerTypeError); |
| 154 | + }, |
| 155 | + ); |
| 156 | + }); |
| 157 | + |
| 158 | + context('given member name is not unique in an object', function () { |
| 159 | + specify('should throw JSONPointerKeyError', function () { |
| 160 | + const objectElement = new ObjectElement({ a: 'b' }); |
| 161 | + objectElement.content.push(new MemberElement('a', 'c')); |
| 162 | + |
| 163 | + assert.throws(() => evaluate(objectElement, '/a'), JSONPointerKeyError); |
| 164 | + }); |
| 165 | + }); |
| 166 | + }); |
| 167 | +}); |
0 commit comments