diff --git a/src/index.js b/src/index.js index 830fdfd..fd8c04e 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,7 @@ import walk from './lang/walk.js'; import stringify from './lang/stringify.js'; import compile from './lang/compile.js'; import buildin from './lang/compile-buildin.js'; -import methods from './methods.js'; +import methods, {methodsInfo, makeMethodInfoFacade, createMethodInfoArg, createMethodInfo} from './methods.js'; import assertions from './assertions.js'; import createStatApi from './stat.js'; @@ -90,10 +90,12 @@ function createQuery(source, options) { const statMode = Boolean(options.stat); const tolerantMode = Boolean(options.tolerant); const localMethods = options.methods ? { ...methods, ...options.methods } : methods; - const localAssetions = options.assertions ? { ...assertions, ...options.assertions } : assertions; + const localAssertions = options.assertions ? { ...assertions, ...options.assertions } : assertions; const cache = statMode ? (tolerantMode ? cacheTollerantStat : cacheStrictStat) : (tolerantMode ? cacheTollerant : cacheStrict); + const methodInfoFacade = makeMethodInfoFacade(methodsInfo, options.methodsInfo); + let fn; source = String(source); @@ -105,20 +107,24 @@ function createQuery(source, options) { cache.set(source, fn); } - fn = fn(buildin, localMethods, localAssetions); + fn = fn(buildin, localMethods, localAssertions); return statMode - ? Object.assign((data, context) => createStatApi(source, fn(data, context)), { query: fn }) + ? Object.assign((data, context) => createStatApi(source, fn(data, context), { + localMethods: {...methods, ...options.methods}, + getMethodInfo: methodInfoFacade.get + }), {query: fn, setMethodInfo: methodInfoFacade.set}) : fn; } -function setup(customMethods, customAssertions) { +function setup(customMethods, customAssertions, {methodsInfo} = {}) { const cacheStrict = new Map(); const cacheStrictStat = new Map(); const cacheTollerant = new Map(); const cacheTollerantStat = new Map(); const localMethods = { ...methods }; const localAssetions = { ...assertions }; + const methodInfoFacade = makeMethodInfoFacade(methodsInfo); for (const [name, fn] of Object.entries(customMethods || {})) { if (typeof fn === 'string') { @@ -169,7 +175,10 @@ function setup(customMethods, customAssertions) { } else { const perform = compileFunction(source, statMode, tolerantMode, options.debug)(buildin, localMethods, localAssetions); fn = statMode - ? Object.assign((data, context) => createStatApi(source, perform(data, context)), { query: perform }) + ? Object.assign((data, context) => createStatApi(source, perform(data, context), { + localMethods: {...methods, ...customMethods}, + getMethodInfo: methodInfoFacade.get + }), {query: perform, setMethodInfo: methodInfoFacade.set}) : perform; cache.set(source, fn); } @@ -182,6 +191,9 @@ export default Object.assign(createQuery, { version, buildin, methods, + methodsInfo, + createMethodInfo, + createMethodInfoArg, assertions, setup, syntax: { diff --git a/src/lang/compile.js b/src/lang/compile.js index 894fb28..f782e21 100644 --- a/src/lang/compile.js +++ b/src/lang/compile.js @@ -44,6 +44,10 @@ export default function compile(ast, tolerant = false, suggestions = null) { normalizedSuggestRanges.push(range); + if (type === 'path') { + normalizedSuggestRanges.push([start, end, JSON.stringify('localMethods')]); + } + return spName; } diff --git a/src/methods.js b/src/methods.js index 4487b03..8108e08 100644 --- a/src/methods.js +++ b/src/methods.js @@ -72,6 +72,45 @@ function stableSort(array, cmp) { .map(item => item.value); } +export function createMethodInfo(args = [], returns = 'any', options = {}) { + return { + args, + returns, + description: options.description || '' + }; +} + +export function createMethodInfoArg(name, type = 'any', options = {}) { + return { + name, + type, + description: options.description || '', + options: { + isOptional: options.isOptional || options.defaultValue !== undefined, + defaultValue: options.defaultValue + } + }; +} + +export function makeMethodInfoFacade(...methodsInfoList) { + const map = new Map(Object.entries(methodsInfoList.reduce((all, item) => Object.assign(all, item), {}))); + + function set(name, info) { + map.set(name, info); + } + + function get(name) { + return map.get(name) || null; + } + + return {map, set, get, create: createMethodInfo, createArg: createMethodInfoArg}; +} + +export const methodsInfo = Object.freeze({ + bool: createMethodInfo([createMethodInfoArg('arg')], 'bool', { + description: 'Similar to `Boolean()` in JavaScript, but treats *empty arrays* and *objects with no keys* as falsy' + }) +}); export default Object.freeze({ bool: buildin.bool, diff --git a/src/stat.js b/src/stat.js index dc2e1c5..4c4e743 100644 --- a/src/stat.js +++ b/src/stat.js @@ -9,7 +9,8 @@ const contextToType = { 'in-value': 'value', 'value-subset': 'value', 'var': 'variable', - 'assertion': 'assertion' + 'assertion': 'assertion', + 'localMethods': 'method' }; function addObjectKeysToSet(object, set) { @@ -111,7 +112,7 @@ function valuesToSuggestions(context, values, related, suggestions = new Set()) function findSourcePosRanges(source, pos, points, includeEmpty = false) { const ranges = []; - for (let [from, to, context, values, related = null] of points) { + for (let [from, to, context, values = [], related = null] of points) { if (pos >= from && pos <= to && (includeEmpty || values.size || values.length)) { let text = source.substring(from, to); @@ -174,7 +175,7 @@ function defaultFilterFactory(pattern) { return value => (typeof value === 'string' ? value : String(value)).toLowerCase().indexOf(pattern) !== -1; } -export default (source, { value, stats, assertions }) => ({ +export default (source, { value, stats, assertions }, {localMethods, getMethodInfo}) => ({ get value() { return value; }, @@ -231,6 +232,11 @@ export default (source, { value, stats, assertions }) => ({ } } break; + case 'localMethods': + for (const method of Object.keys(localMethods)) { + suggestions.add(method); + } + break; default: valuesToSuggestions(context, values, related, suggestions); @@ -275,5 +281,6 @@ export default (source, { value, stats, assertions }) => ({ } return result.length ? result : null; - } + }, + getMethodInfo: getMethodInfo }); diff --git a/test/misc.js b/test/misc.js index 40e62cb..4b12271 100644 --- a/test/misc.js +++ b/test/misc.js @@ -21,3 +21,35 @@ describe('query/misc', () => { }); } }); + +describe('method info helpers', () => { + it('createMethodInfo', () => { + assert.deepEqual(query.createMethodInfo([], 'some return type', {description: 'some description'}), { + args: [], + description: 'some description', + returns: 'some return type' + }); + }); + + it('createMethodInfoArg', () => { + assert.deepEqual(query.createMethodInfoArg('arg1', 'some arg type', {description: 'some description'}), { + name: 'arg1', + description: 'some description', + options: { + defaultValue: undefined, + isOptional: false + }, + type: 'some arg type' + }); + + assert.deepEqual(query.createMethodInfoArg('arg1', 'some arg type', {description: 'some description', defaultValue: '123'}), { + name: 'arg1', + description: 'some description', + options: { + defaultValue: '123', + isOptional: true + }, + type: 'some arg type' + }); + }); +}); diff --git a/test/stat.js b/test/stat.js index cd4ef78..0ddfb72 100644 --- a/test/stat.js +++ b/test/stat.js @@ -2,6 +2,8 @@ import assert from 'assert'; import jora from 'jora'; import { naturalCompare } from '@discoveryjs/natural-compare'; +const localMethodNames = Object.keys(jora.methods); + describe('query/stat mode', () => { describe('default', () => { const options = { stat: true }; @@ -29,6 +31,18 @@ describe('query/stat mode', () => { }]); }); + describe('getMethodInfo() method', () => { + it('basic', () =>{ + const methodsInfo = { + foo: jora.createMethodInfo([]) + }; + const res = jora('.[]', {...options, methodsInfo})([]); + assert.deepEqual(res.getMethodInfo('foo'), methodsInfo.foo); + assert.deepEqual(res.getMethodInfo('bar'), null); + assert.deepEqual(res.getMethodInfo('bool'), jora.methodsInfo.bool); + }); + }); + describe('suggestion() method', () => { it('default behaviour (no options)', () => { const data = [{ id: 1, foo: 1 }, { id: 2, foo: 42 }]; @@ -40,6 +54,12 @@ describe('query/stat mode', () => { to: 5, text: 'foo', suggestions: ['id', 'foo'] + }, { + type: 'method', + from: 2, + to: 5, + text: 'foo', + suggestions: localMethodNames }]); assert.deepEqual(res.suggestion(6), [{ type: 'value', @@ -53,6 +73,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['id', 'foo'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: localMethodNames }]); }); @@ -73,6 +99,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['id'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: localMethodNames.filter(n => n.match(/i/i)) }]); }); @@ -146,6 +178,12 @@ describe('query/stat mode', () => { to: 5, text: 'foo', suggestions: ['id', 'foo', 'bar'] + }, { + type: 'method', + from: 2, + to: 5, + text: 'foo', + suggestions: localMethodNames.slice(0, 3) }]); assert.deepEqual(res.suggestion(6, { limit: 3 }), [{ type: 'value', @@ -159,6 +197,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['id', 'foo', 'bar'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: localMethodNames.slice(0, 3) }]); }); @@ -190,6 +234,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['id', 'fix'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: localMethodNames.filter(n => n.match(/i/i)).slice(0, 2) }]); }); @@ -208,6 +258,12 @@ describe('query/stat mode', () => { to: 5, text: 'Foo', suggestions: ['ABC', 'Foo', 'bar', 'id', 'qux'] + }, { + type: 'method', + from: 2, + to: 5, + text: 'Foo', + suggestions: [...localMethodNames].sort() }]); assert.deepEqual(res.suggestion(6, { sort: true }), [{ type: 'value', @@ -221,6 +277,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['ABC', 'Foo', 'bar', 'id', 'qux'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: [...localMethodNames].sort() }]); }); @@ -240,6 +302,12 @@ describe('query/stat mode', () => { to: 5, text: 'Foo', suggestions: ['ABC', 'bar', 'Foo', 'id', 'qux'] + }, { + type: 'method', + from: 2, + to: 5, + text: 'Foo', + suggestions: [...localMethodNames].sort(naturalCompare) }]); assert.deepEqual(res.suggestion(6, { sort }), [{ type: 'value', @@ -253,6 +321,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['ABC', 'bar', 'Foo', 'id', 'qux'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: [...localMethodNames].sort(naturalCompare) }]); }); @@ -284,6 +358,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['fix', 'id', 'index'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: localMethodNames.filter(n => n.match(/i/i)).sort() }]); }); @@ -302,6 +382,12 @@ describe('query/stat mode', () => { to: 5, text: 'foo', suggestions: ['bar', 'foo', 'id'] + }, { + type: 'method', + from: 2, + to: 5, + text: 'foo', + suggestions: [...localMethodNames].sort().slice(0, 3) }]); assert.deepEqual(res.suggestion(6, { sort: true, limit: 3 }), [{ type: 'value', @@ -315,6 +401,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['bar', 'foo', 'id'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: [...localMethodNames].sort().slice(0, 3) }]); }); @@ -347,6 +439,12 @@ describe('query/stat mode', () => { to: 7, text: 'i', suggestions: ['aid', 'fix', 'id', 'index'] + }, { + type: 'method', + from: 6, + to: 7, + text: 'i', + suggestions: localMethodNames.filter(n => n.match(/i/i)).sort().slice(0, 4) }]); }); }); @@ -400,6 +498,12 @@ describe('query/stat mode', () => { to: 5, text: 'foo', suggestions: ['id', 'foo'] + }, { + from: 2, + text: 'foo', + to: 5, + type: 'method', + suggestions: [...localMethodNames] }]); assert.deepEqual(res.suggestion(6), [{ type: 'value', @@ -413,6 +517,12 @@ describe('query/stat mode', () => { to: 6, text: '', suggestions: ['id', 'foo'] + }, { + text: '', + from: 6, + to: 6, + type: 'method', + suggestions: [...localMethodNames] }]); }); }); diff --git a/test/suggestions.js b/test/suggestions.js index d1595a4..8296ecb 100644 --- a/test/suggestions.js +++ b/test/suggestions.js @@ -1,6 +1,8 @@ import assert from 'assert'; import query from 'jora'; +const localMethodNames = Object.keys(query.methods).map(n=>`${n}:method`); + const data = { foo: [ { a: 1, b: 2}, @@ -100,14 +102,14 @@ describe('query/suggestions', () => { assert.deepEqual( suggestQuery('|', data), [ - suggestion('', ['foo', 'bar'], 0, 0) + suggestion('', ['foo', 'bar', ...localMethodNames], 0, 0) ] ); }); it('simple path', () => { - const foo = suggestion('foo', ['foo', 'bar'], 0, 3); - const bar = suggestion('bar', ['a', 'b', 'c', 'd'], 4, 7); + const foo = suggestion('foo', ['foo', 'bar', ...localMethodNames], 0, 3); + const bar = suggestion('bar', ['a', 'b', 'c', 'd', ...localMethodNames], 4, 7); assert.deepEqual( suggestQuery('|f|o|o|.|b|a|r|', data), @@ -118,6 +120,15 @@ describe('query/suggestions', () => { ); }); + it('custom helpers', () => { + assert.deepEqual( + suggestQuery('|', data, {methods: {h1: Boolean, h2: Boolean}}), + [ + suggestion('', ['foo', 'bar', ...localMethodNames, 'h1:method', 'h2:method'], 0, 0) + ] + ); + }); + Object.entries({ filter: ['.[', ']'], map: ['.(', ')'], @@ -132,8 +143,8 @@ describe('query/suggestions', () => { describe(name, () => { Object.entries({ - '': ['foo', 'bar'], - foo: ['a', 'b', 'c', 'd'] + '': ['foo', 'bar', ...localMethodNames], + foo: ['a', 'b', 'c', 'd', ...localMethodNames] }).forEach(([prefix, list]) => { describe('with prefix `' + prefix + '`', () => { const emptyQuery = `${prefix}${sbegin}${send}`; @@ -189,11 +200,11 @@ describe('query/suggestions', () => { suggestQuery('{| |a|,| |b| |}', data), [ null, - suggestion('a', ['foo', 'bar'], 2, 3), - suggestion('a', ['foo', 'bar'], 2, 3), + suggestion('a', ['foo', 'bar', ...localMethodNames], 2, 3), + suggestion('a', ['foo', 'bar', ...localMethodNames], 2, 3), null, - suggestion('b', ['foo', 'bar'], 5, 6), - suggestion('b', ['foo', 'bar'], 5, 6), + suggestion('b', ['foo', 'bar', ...localMethodNames], 5, 6), + suggestion('b', ['foo', 'bar', ...localMethodNames], 5, 6), null ] ); @@ -204,11 +215,11 @@ describe('query/suggestions', () => { suggestQuery('[| |a|,| |b| |]', data), [ null, - suggestion('a', ['foo', 'bar'], 2, 3), - suggestion('a', ['foo', 'bar'], 2, 3), + suggestion('a', ['foo', 'bar', ...localMethodNames], 2, 3), + suggestion('a', ['foo', 'bar', ...localMethodNames], 2, 3), null, - suggestion('b', ['foo', 'bar'], 5, 6), - suggestion('b', ['foo', 'bar'], 5, 6), + suggestion('b', ['foo', 'bar', ...localMethodNames], 5, 6), + suggestion('b', ['foo', 'bar', ...localMethodNames], 5, 6), null ] ); @@ -219,7 +230,7 @@ describe('query/suggestions', () => { suggestQuery('map(|<|>|)', data), [ null, - suggestion('', ['foo', 'bar'], 5, 5), + suggestion('', ['foo', 'bar', ...localMethodNames], 5, 5), null ] ); @@ -231,15 +242,15 @@ describe('query/suggestions', () => { [ null, null, - suggestion('', ['foo', 'bar'], 6, 6) + suggestion('', ['foo', 'bar', ...localMethodNames], 6, 6) ] ); }); describeCases('pick', { '$[| |]': [ - suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar'], 2, 2), - suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar'], 3, 3) + suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 2, 2), + suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 3, 3) ], '$[| |"|"| |]': [ null, @@ -279,8 +290,8 @@ describe('query/suggestions', () => { ], '$[| |a| |]': [ null, - suggestion('a', ['"foo":value', '"bar":value', 'foo', 'bar'], 3, 4), - suggestion('a', ['"foo":value', '"bar":value', 'foo', 'bar'], 3, 4), + suggestion('a', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 3, 4), + suggestion('a', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 3, 4), null ], '$a;$[| |$|a| |]': [ @@ -301,18 +312,18 @@ describe('query/suggestions', () => { describeCases('string templates', { '`${| |}`': [ - suggestion('', ['foo', 'bar'], 3, 3), - suggestion('', ['foo', 'bar'], 4, 4) + suggestion('', ['foo', 'bar', ...localMethodNames], 3, 3), + suggestion('', ['foo', 'bar', ...localMethodNames], 4, 4) ], '`${| |}${| |}`': [ - suggestion('', ['foo', 'bar'], 3, 3), - suggestion('', ['foo', 'bar'], 4, 4), - suggestion('', ['foo', 'bar'], 7, 7), - suggestion('', ['foo', 'bar'], 8, 8) + suggestion('', ['foo', 'bar', ...localMethodNames], 3, 3), + suggestion('', ['foo', 'bar', ...localMethodNames], 4, 4), + suggestion('', ['foo', 'bar', ...localMethodNames], 7, 7), + suggestion('', ['foo', 'bar', ...localMethodNames], 8, 8) ], '`${}${| |}`': [ - suggestion('', ['foo', 'bar'], 6, 6), - suggestion('', ['foo', 'bar'], 7, 7) + suggestion('', ['foo', 'bar', ...localMethodNames], 6, 6), + suggestion('', ['foo', 'bar', ...localMethodNames], 7, 7) ] }); @@ -321,7 +332,7 @@ describe('query/suggestions', () => { const actual = suggestQuery('.[$=|]', values)[0]; const expected = suggestion('', values.slice(0, 20).map(v => JSON.stringify(v) + ':value'), 4, 4); - assert.equal(actual.length, values.length); + assert.equal(actual.length, values.length + localMethodNames.length); // compare first N items only for performance reasons (deepEqual is too slow for such big arrays) assert.deepEqual( @@ -337,9 +348,9 @@ describe('query/suggestions', () => { assert.deepEqual( suggestQuery(prefix + 'size(| | |)', data), [ - suggestion('', ['foo', 'bar'], prefix.length + 5), - suggestion('', ['foo', 'bar'], prefix.length + 6), - suggestion('', ['foo', 'bar'], prefix.length + 7) + suggestion('', ['foo', 'bar', ...localMethodNames], prefix.length + 5), + suggestion('', ['foo', 'bar', ...localMethodNames], prefix.length + 6), + suggestion('', ['foo', 'bar', ...localMethodNames], prefix.length + 7) ] ); }); @@ -349,8 +360,8 @@ describe('query/suggestions', () => { suggestQuery(prefix + 'size(| |a| |)', data), [ null, - suggestion('a', ['foo', 'bar'], prefix.length + 6, prefix.length + 7), - suggestion('a', ['foo', 'bar'], prefix.length + 6, prefix.length + 7), + suggestion('a', ['foo', 'bar', ...localMethodNames], prefix.length + 6, prefix.length + 7), + suggestion('a', ['foo', 'bar', ...localMethodNames], prefix.length + 6, prefix.length + 7), null ] ); @@ -361,18 +372,18 @@ describe('query/suggestions', () => { suggestQuery(prefix + 'size(| |a|,| |b|,| |c| |,| |d| |)', data), [ null, - suggestion('a', ['foo', 'bar'], prefix.length + 6, prefix.length + 7), - suggestion('a', ['foo', 'bar'], prefix.length + 6, prefix.length + 7), + suggestion('a', ['foo', 'bar', ...localMethodNames], prefix.length + 6, prefix.length + 7), + suggestion('a', ['foo', 'bar', ...localMethodNames], prefix.length + 6, prefix.length + 7), null, - suggestion('b', ['foo', 'bar'], prefix.length + 9, prefix.length + 10), - suggestion('b', ['foo', 'bar'], prefix.length + 9, prefix.length + 10), + suggestion('b', ['foo', 'bar', ...localMethodNames], prefix.length + 9, prefix.length + 10), + suggestion('b', ['foo', 'bar', ...localMethodNames], prefix.length + 9, prefix.length + 10), null, - suggestion('c', ['foo', 'bar'], prefix.length + 12, prefix.length + 13), - suggestion('c', ['foo', 'bar'], prefix.length + 12, prefix.length + 13), + suggestion('c', ['foo', 'bar', ...localMethodNames], prefix.length + 12, prefix.length + 13), + suggestion('c', ['foo', 'bar', ...localMethodNames], prefix.length + 12, prefix.length + 13), null, null, - suggestion('d', ['foo', 'bar'], prefix.length + 16, prefix.length + 17), - suggestion('d', ['foo', 'bar'], prefix.length + 16, prefix.length + 17), + suggestion('d', ['foo', 'bar', ...localMethodNames], prefix.length + 16, prefix.length + 17), + suggestion('d', ['foo', 'bar', ...localMethodNames], prefix.length + 16, prefix.length + 17), null ] ); @@ -383,19 +394,19 @@ describe('query/suggestions', () => { describeCases('variables', { '|$|f|;|': [ - suggestion('$f', ['foo', 'bar'], 0, 2), - suggestion('$f', ['foo', 'bar'], 0, 2), - suggestion('$f', ['foo', 'bar'], 0, 2), - suggestion('', ['$f:variable', 'foo', 'bar'], 3) + suggestion('$f', ['foo', 'bar', ...localMethodNames], 0, 2), + suggestion('$f', ['foo', 'bar', ...localMethodNames], 0, 2), + suggestion('$f', ['foo', 'bar', ...localMethodNames], 0, 2), + suggestion('', ['$f:variable', 'foo', 'bar', ...localMethodNames], 3, 3) ], '|$|f|o|o|;| |': [ - suggestion('$foo', ['foo', 'bar'], 0, 4), - suggestion('$foo', ['foo', 'bar'], 0, 4), - suggestion('$foo', ['foo', 'bar'], 0, 4), - suggestion('$foo', ['foo', 'bar'], 0, 4), - suggestion('$foo', ['foo', 'bar'], 0, 4), - suggestion('', ['$foo:variable', 'foo', 'bar'], 5), - suggestion('', ['$foo:variable', 'foo', 'bar'], 6) + suggestion('$foo', ['foo', 'bar', ...localMethodNames], 0, 4), + suggestion('$foo', ['foo', 'bar', ...localMethodNames], 0, 4), + suggestion('$foo', ['foo', 'bar', ...localMethodNames], 0, 4), + suggestion('$foo', ['foo', 'bar', ...localMethodNames], 0, 4), + suggestion('$foo', ['foo', 'bar', ...localMethodNames], 0, 4), + suggestion('', ['$foo:variable', 'foo', 'bar', ...localMethodNames], 5), + suggestion('', ['$foo:variable', 'foo', 'bar', ...localMethodNames], 6) ], '$a;foo.(|$|)': [ suggestion('$', ['$a:variable'], 8, 9), @@ -413,37 +424,37 @@ describe('query/suggestions', () => { describeCases('mixed', { '.entries|(|).sort|(|)': [ null, - suggestion('', ['foo', 'bar'], 9, 9), + suggestion('', ['foo', 'bar', ...localMethodNames], 9, 9), null, - suggestion('', ['foo', 'bar'], 16, 16) + suggestion('', ['foo', 'bar', ...localMethodNames], 16, 16) ], '.entries|(|a|,| |b|).sort|(|a|,| |b|)': [ null, - suggestion('a', ['foo', 'bar'], 9, 10), - suggestion('a', ['foo', 'bar'], 9, 10), + suggestion('a', ['foo', 'bar', ...localMethodNames], 9, 10), + suggestion('a', ['foo', 'bar', ...localMethodNames], 9, 10), null, - suggestion('b', ['foo', 'bar'], 12, 13), - suggestion('b', ['foo', 'bar'], 12, 13), + suggestion('b', ['foo', 'bar', ...localMethodNames], 12, 13), + suggestion('b', ['foo', 'bar', ...localMethodNames], 12, 13), null, - suggestion('a', ['foo', 'bar'], 20, 21), - suggestion('a', ['foo', 'bar'], 20, 21), + suggestion('a', ['foo', 'bar', ...localMethodNames], 20, 21), + suggestion('a', ['foo', 'bar', ...localMethodNames], 20, 21), null, - suggestion('b', ['foo', 'bar'], 23, 24), - suggestion('b', ['foo', 'bar'], 23, 24) + suggestion('b', ['foo', 'bar', ...localMethodNames], 23, 24), + suggestion('b', ['foo', 'bar', ...localMethodNames], 23, 24) ], '{foo:[{},{bar:5}]}.foo.(|b|)': [ - suggestion('b', ['bar'], 24, 25), - suggestion('b', ['bar'], 24, 25) + suggestion('b', ['bar', ...localMethodNames], 24, 25), + suggestion('b', ['bar', ...localMethodNames], 24, 25) ], '$[| | |]': [ - suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar'], 2), - suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar'], 3), - suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar'], 4) + suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 2), + suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 3), + suggestion('', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 4) ], '$[| |a| |]': [ null, - suggestion('a', ['"foo":value', '"bar":value', 'foo', 'bar'], 3, 4), - suggestion('a', ['"foo":value', '"bar":value', 'foo', 'bar'], 3, 4), + suggestion('a', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 3, 4), + suggestion('a', ['"foo":value', '"bar":value', 'foo', 'bar', ...localMethodNames], 3, 4), null ] }); @@ -452,10 +463,10 @@ describe('query/suggestions', () => { describe('query/suggestions (tolerant mode)', () => { describeCasesTolerant('trailing full stop', { '.|': [ - suggestion('', ['foo', 'bar'], 1, 1) + suggestion('', ['foo', 'bar', ...localMethodNames], 1, 1) ], '.foo.|': [ - suggestion('', ['a', 'b', 'c', 'd'], 5, 5) + suggestion('', ['a', 'b', 'c', 'd', ...localMethodNames], 5, 5) ] }); @@ -469,7 +480,7 @@ describe('query/suggestions (tolerant mode)', () => { (it)(operator, () => { assert.deepEqual( suggestQuery(queryString, data), [ - suggestion('', ['foo', 'bar'], 1) + suggestion('', ['foo', 'bar', ...localMethodNames], 1) ] ); }); @@ -479,11 +490,11 @@ describe('query/suggestions (tolerant mode)', () => { describeCasesTolerant('trailing double full stop', { '.|.|': [ null, - suggestion('', ['foo', 'bar'], 2, 2) + suggestion('', ['foo', 'bar', ...localMethodNames], 2, 2) ], '.foo.|.|': [ null, - suggestion('', ['a', 'b', 'c', 'd'], 6, 6) + suggestion('', ['a', 'b', 'c', 'd', ...localMethodNames], 6, 6) ] }); @@ -491,59 +502,59 @@ describe('query/suggestions (tolerant mode)', () => { assert.deepEqual( suggestQuery('.foo.[.|].|', data), [ - suggestion('', ['a', 'b', 'c', 'd'], 7), - null + suggestion('', ['a', 'b', 'c', 'd', ...localMethodNames], 7, 7), + suggestion('', [...localMethodNames], 9, 9) ] ); }); describeCasesTolerant('trailing full stop with trailing whitespaces', { '.| |': [ - suggestion('', ['foo', 'bar'], 1), - suggestion('', ['foo', 'bar'], 2) + suggestion('', ['foo', 'bar', ...localMethodNames], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 2) ], '.|\n ': [ - suggestion('', ['foo', 'bar'], 1) + suggestion('', ['foo', 'bar', ...localMethodNames], 1) ] }); describeCasesTolerant('trailing full stop with trailing comment', { '.|/|/|': [ - suggestion('', ['foo', 'bar'], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 1), null, null ], '.|/|/|\n|': [ - suggestion('', ['foo', 'bar'], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 1), null, null, - suggestion('', ['foo', 'bar'], 4) + suggestion('', ['foo', 'bar', ...localMethodNames], 4) ], '.| //|': [ - suggestion('', ['foo', 'bar'], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 1), null ], '.| //1\n| |//2\n//3\n| |': [ - suggestion('', ['foo', 'bar'], 1), - suggestion('', ['foo', 'bar'], 7), - suggestion('', ['foo', 'bar'], 9), - suggestion('', ['foo', 'bar'], 17), - suggestion('', ['foo', 'bar'], 19) + suggestion('', ['foo', 'bar', ...localMethodNames], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 7), + suggestion('', ['foo', 'bar', ...localMethodNames], 9), + suggestion('', ['foo', 'bar', ...localMethodNames], 17), + suggestion('', ['foo', 'bar', ...localMethodNames], 19) ], '.| |/*1*/|\n |/*2\n3*/\n| |': [ - suggestion('', ['foo', 'bar'], 1), - suggestion('', ['foo', 'bar'], 3), - suggestion('', ['foo', 'bar'], 8), - suggestion('', ['foo', 'bar'], 11), - suggestion('', ['foo', 'bar'], 19), - suggestion('', ['foo', 'bar'], 21) + suggestion('', ['foo', 'bar', ...localMethodNames], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 3), + suggestion('', ['foo', 'bar', ...localMethodNames], 8), + suggestion('', ['foo', 'bar', ...localMethodNames], 11), + suggestion('', ['foo', 'bar', ...localMethodNames], 19), + suggestion('', ['foo', 'bar', ...localMethodNames], 21) ], '.foo.|//|': [ - suggestion('', ['a', 'b', 'c', 'd'], 5), + suggestion('', ['a', 'b', 'c', 'd', ...localMethodNames], 5), null ], '.foo.|/*|*/|': [ - suggestion('', ['a', 'b', 'c', 'd'], 5), + suggestion('', ['a', 'b', 'c', 'd', ...localMethodNames], 5), null, null ] @@ -553,7 +564,7 @@ describe('query/suggestions (tolerant mode)', () => { assert.deepEqual( suggestQuery('[foo,|]', data), [ - suggestion('', ['foo', 'bar'], 5) + suggestion('', ['foo', 'bar', ...localMethodNames], 5) ] ); }); @@ -567,10 +578,10 @@ describe('query/suggestions (tolerant mode)', () => { assert.deepEqual( suggestQuery('| |' + operator + '| |', data), [ - suggestion('', ['foo', 'bar'], 0), - suggestion('', ['foo', 'bar'], 1), - suggestion('', ['foo', 'bar'], operator.length + 1), - suggestion('', ['foo', 'bar'], operator.length + 2) + suggestion('', ['foo', 'bar', ...localMethodNames], 0), + suggestion('', ['foo', 'bar', ...localMethodNames], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], operator.length + 1), + suggestion('', ['foo', 'bar', ...localMethodNames], operator.length + 2) ] ); }); @@ -581,8 +592,8 @@ describe('query/suggestions (tolerant mode)', () => { assert.deepEqual( suggestQuery('foo <| |', data), [ - suggestion('', ['foo', 'bar'], 5), - suggestion('', ['foo', 'bar'], 6) + suggestion('', ['foo', 'bar', ...localMethodNames], 5), + suggestion('', ['foo', 'bar', ...localMethodNames], 6) ] ); }); @@ -593,8 +604,8 @@ describe('query/suggestions (tolerant mode)', () => { assert.deepEqual( suggestQuery('| |', data), [ - suggestion('', ['foo', 'bar'], 0), - suggestion('', ['foo', 'bar'], 1) + suggestion('', ['foo', 'bar', ...localMethodNames], 0), + suggestion('', ['foo', 'bar', ...localMethodNames], 1) ] ); }); @@ -602,8 +613,8 @@ describe('query/suggestions (tolerant mode)', () => { assert.deepEqual( suggestQuery('$ | |', data), [ - suggestion('', ['foo', 'bar'], 3), - suggestion('', ['foo', 'bar'], 4) + suggestion('', ['foo', 'bar', ...localMethodNames], 3), + suggestion('', ['foo', 'bar', ...localMethodNames], 4) ] ); }); @@ -653,7 +664,7 @@ describe('query/suggestions (tolerant mode)', () => { null ] : [ - suggestion('', ['foo', 'bar'], 0), + suggestion('', ['foo', 'bar', ...localMethodNames], 0), null ] ); @@ -674,7 +685,7 @@ describe('query/suggestions (tolerant mode)', () => { null ] : [ - suggestion('', ['foo', 'bar'], 0), + suggestion('', ['foo', 'bar', ...localMethodNames], 0), null ] ); @@ -698,7 +709,7 @@ describe('query/suggestions (tolerant mode)', () => { suggestQuery(queryString, data), [ null, - suggestion('', ['foo', 'bar'], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 1), null ] ); @@ -722,10 +733,10 @@ describe('query/suggestions (tolerant mode)', () => { null ] : [ - suggestion('', ['foo', 'bar'], 0), - suggestion('', ['foo', 'bar'], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 0), + suggestion('', ['foo', 'bar', ...localMethodNames], 1), null, - suggestion('', ['foo', 'bar'], 8), + suggestion('', ['foo', 'bar', ...localMethodNames], 8), null ] ); @@ -747,7 +758,7 @@ describe('query/suggestions (tolerant mode)', () => { ] : [ null, - suggestion('', ['foo', 'bar'], operator.length + 1) + suggestion('', ['foo', 'bar', ...localMethodNames], operator.length + 1) ] ); }); @@ -768,7 +779,7 @@ describe('query/suggestions (tolerant mode)', () => { ] : [ null, - suggestion('', ['foo', 'bar'], operator.length + 1) + suggestion('', ['foo', 'bar', ...localMethodNames], operator.length + 1) ] ); }); @@ -786,7 +797,7 @@ describe('query/suggestions (tolerant mode)', () => { suggestQuery(operator + '|[|]', data), [ null, - suggestion('', ['foo', 'bar'], operator.length + 1) + suggestion('', ['foo', 'bar', ...localMethodNames], operator.length + 1) ] ); }); @@ -796,34 +807,34 @@ describe('query/suggestions (tolerant mode)', () => { describeCasesTolerant('suggestion before and after operators in blocks', { '[| |or| |]': [ - suggestion('', ['foo', 'bar'], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 1), null, null, - suggestion('', ['foo', 'bar'], 5) + suggestion('', ['foo', 'bar', ...localMethodNames], 5) ], '(| |or| |)': [ - suggestion('', ['foo', 'bar'], 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 1), null, null, - suggestion('', ['foo', 'bar'], 5) + suggestion('', ['foo', 'bar', ...localMethodNames], 5) ], '.(| |or| |)': [ - suggestion('', ['foo', 'bar'], 2), + suggestion('', ['foo', 'bar', ...localMethodNames], 2), null, null, - suggestion('', ['foo', 'bar'], 6) + suggestion('', ['foo', 'bar', ...localMethodNames], 6) ], '.[| |or| |]': [ - suggestion('', ['foo', 'bar'], 2), + suggestion('', ['foo', 'bar', ...localMethodNames], 2), null, null, - suggestion('', ['foo', 'bar'], 6) + suggestion('', ['foo', 'bar', ...localMethodNames], 6) ], '..(| |or| |)': [ - suggestion('', ['foo', 'bar'], 3), + suggestion('', ['foo', 'bar', ...localMethodNames], 3), null, null, - suggestion('', ['foo', 'bar'], 7) + suggestion('', ['foo', 'bar', ...localMethodNames], 7) ] }); @@ -831,26 +842,26 @@ describe('query/suggestions (tolerant mode)', () => { describe('in', () => { Object.entries({ '|_| |i|n| ["a", "b", 3]': [ - suggestion('_', ['"a":value', '"b":value', '3:value', 'foo', 'bar'], 0, 1), - suggestion('_', ['"a":value', '"b":value', '3:value', 'foo', 'bar'], 0, 1), + suggestion('_', ['"a":value', '"b":value', '3:value', 'foo', 'bar', ...localMethodNames], 0, 1), + suggestion('_', ['"a":value', '"b":value', '3:value', 'foo', 'bar', ...localMethodNames], 0, 1), null, null, null ], '|_| |i|n| { "a": 1, "b": 2 }': [ - suggestion('_', ['"a":value', '"b":value', 'foo', 'bar'], 0, 1), - suggestion('_', ['"a":value', '"b":value', 'foo', 'bar'], 0, 1), + suggestion('_', ['"a":value', '"b":value', 'foo', 'bar', ...localMethodNames], 0, 1), + suggestion('_', ['"a":value', '"b":value', 'foo', 'bar', ...localMethodNames], 0, 1), null, null, null ], 'keys().[$ in [| |]]': [ - suggestion('', ['"foo":value', '"bar":value'], 14), - suggestion('', ['"foo":value', '"bar":value'], 15) + suggestion('', ['"foo":value', '"bar":value', ...localMethodNames], 14), + suggestion('', ['"foo":value', '"bar":value', ...localMethodNames], 15) ], 'foo.[b in [| |]]': [ - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], 11), - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], 12) + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], 11), + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], 12) ], // FIXME: split in several test cases '["a", "b", "c", "d", 1, 2].[$a:"a"; $ in [| |"|b|"|,| |d|,| |1|,| |$|a|,| |]]': [ @@ -860,8 +871,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('"b"', ['"a":value', '"c":value', '"d":value', '2:value'], 43, 46), suggestion('"b"', ['"a":value', '"c":value', '"d":value', '2:value'], 43, 46), null, - suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 48, 49), - suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 48, 49), + suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 48, 49), + suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 48, 49), null, suggestion('1', ['"a":value', '"c":value', '"d":value', '2:value'], 51, 52), suggestion('1', ['"a":value', '"c":value', '"d":value', '2:value'], 51, 52), @@ -869,8 +880,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('$a', ['$a:variable'], 54, 56), suggestion('$a', ['$a:variable'], 54, 56), suggestion('$a', ['$a:variable'], 54, 56), - suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 57), - suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 58) + suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 57), + suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 58) ] }).forEach(([queryString, expected]) => it(queryString, () => @@ -885,12 +896,12 @@ describe('query/suggestions (tolerant mode)', () => { describe('not in', () => { Object.entries({ 'keys().[$ not in [| |]]': [ - suggestion('', ['"foo":value', '"bar":value'], 18), - suggestion('', ['"foo":value', '"bar":value'], 19) + suggestion('', ['"foo":value', '"bar":value', ...localMethodNames], 18), + suggestion('', ['"foo":value', '"bar":value', ...localMethodNames], 19) ], 'foo.[b not in [| |]]': [ - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], 15), - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], 16) + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], 15), + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], 16) ], // FIXME: split in several test cases '["a", "b", "c", "d", 1, 2].[$a:"a"; $ not in [| |"|b|"|,| |d|,| |1|,| |$|a|,| |]]': [ @@ -900,8 +911,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('"b"', ['"a":value', '"c":value', '"d":value', '2:value'], 47, 50), suggestion('"b"', ['"a":value', '"c":value', '"d":value', '2:value'], 47, 50), null, - suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 52, 53), - suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 52, 53), + suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 52, 53), + suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 52, 53), null, suggestion('1', ['"a":value', '"c":value', '"d":value', '2:value'], 55, 56), suggestion('1', ['"a":value', '"c":value', '"d":value', '2:value'], 55, 56), @@ -909,8 +920,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('$a', ['$a:variable'], 58, 60), suggestion('$a', ['$a:variable'], 58, 60), suggestion('$a', ['$a:variable'], 58, 60), - suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 61), - suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 62) + suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 61), + suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 62) ] }).forEach(([queryString, expected]) => it(queryString, () => @@ -929,24 +940,24 @@ describe('query/suggestions (tolerant mode)', () => { null, null, null, - suggestion('_', ['"a":value', '"b":value', '3:value', 'foo', 'bar'], 18, 19), - suggestion('_', ['"a":value', '"b":value', '3:value', 'foo', 'bar'], 18, 19) + suggestion('_', ['"a":value', '"b":value', '3:value', 'foo', 'bar', ...localMethodNames], 18, 19), + suggestion('_', ['"a":value', '"b":value', '3:value', 'foo', 'bar', ...localMethodNames], 18, 19) ], '{ "a": 1, "b": 2 } |h|a|s| |_|': [ null, null, null, null, - suggestion('_', ['"a":value', '"b":value', 'foo', 'bar'], 23, 24), - suggestion('_', ['"a":value', '"b":value', 'foo', 'bar'], 23, 24) + suggestion('_', ['"a":value', '"b":value', 'foo', 'bar', ...localMethodNames], 23, 24), + suggestion('_', ['"a":value', '"b":value', 'foo', 'bar', ...localMethodNames], 23, 24) ], 'keys().[[| |] has $]': [ - suggestion('', ['"foo":value', '"bar":value'], 9), - suggestion('', ['"foo":value', '"bar":value'], 10) + suggestion('', ['"foo":value', '"bar":value', ...localMethodNames], 9), + suggestion('', ['"foo":value', '"bar":value', ...localMethodNames], 10) ], 'foo.[[| |] has b]': [ - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], 6), - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], 7) + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], 6), + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], 7) ], // FIXME: split in several test cases '["a", "b", "c", "d", 1, 2].[$a:"a";[| |"|b|"|,| |d|,| |1|,| |$|a|,| |] has $]': [ @@ -956,8 +967,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('"b"', ['"a":value', '"c":value', '"d":value', '2:value'], 37, 40), suggestion('"b"', ['"a":value', '"c":value', '"d":value', '2:value'], 37, 40), null, - suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 42, 43), - suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 42, 43), + suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 42, 43), + suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 42, 43), null, suggestion('1', ['"a":value', '"c":value', '"d":value', '2:value'], 45, 46), suggestion('1', ['"a":value', '"c":value', '"d":value', '2:value'], 45, 46), @@ -965,8 +976,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('$a', ['$a:variable'], 48, 50), suggestion('$a', ['$a:variable'], 48, 50), suggestion('$a', ['$a:variable'], 48, 50), - suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 51), - suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 52) + suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 51), + suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 52) ] }).forEach(([queryString, expected]) => it(queryString, () => @@ -981,12 +992,12 @@ describe('query/suggestions (tolerant mode)', () => { describe('has no', () => { Object.entries({ 'keys().[[| |] has no $]': [ - suggestion('', ['"foo":value', '"bar":value'], 9), - suggestion('', ['"foo":value', '"bar":value'], 10) + suggestion('', ['"foo":value', '"bar":value', ...localMethodNames], 9), + suggestion('', ['"foo":value', '"bar":value', ...localMethodNames], 10) ], 'foo.[[| |] has no b]': [ - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], 6), - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], 7) + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], 6), + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], 7) ], // FIXME: split in several test cases '["a", "b", "c", "d", 1, 2].[$a:"a";[| |"|b|"|,| |d|,| |1|,| |$|a|,| |] has no $]': [ @@ -996,8 +1007,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('"b"', ['"a":value', '"c":value', '"d":value', '2:value'], 37, 40), suggestion('"b"', ['"a":value', '"c":value', '"d":value', '2:value'], 37, 40), null, - suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 42, 43), - suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 42, 43), + suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 42, 43), + suggestion('d', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 42, 43), null, suggestion('1', ['"a":value', '"c":value', '"d":value', '2:value'], 45, 46), suggestion('1', ['"a":value', '"c":value', '"d":value', '2:value'], 45, 46), @@ -1005,8 +1016,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('$a', ['$a:variable'], 48, 50), suggestion('$a', ['$a:variable'], 48, 50), suggestion('$a', ['$a:variable'], 48, 50), - suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 51), - suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable'], 52) + suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 51), + suggestion('', ['"a":value', '"c":value', '"d":value', '2:value', '$a:variable', ...localMethodNames], 52) ] }).forEach(([queryString, expected]) => it(queryString, () => @@ -1024,8 +1035,8 @@ describe('query/suggestions (tolerant mode)', () => { assert.deepEqual( suggestQuery(queryString, data), [ - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], queryString.length - 4), - suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd'], queryString.length - 3) + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], queryString.length - 4), + suggestion('', ['2:value', '3:value', 'a', 'b', 'c', 'd', ...localMethodNames], queryString.length - 3) ] ); }); @@ -1042,7 +1053,7 @@ describe('query/suggestions (tolerant mode)', () => { assert.deepEqual( suggestQuery(queryString, { foo: 32, bar: { baz: 32 } }), [ - suggestion('', ['foo', 'bar'], queryString.indexOf('|')) + suggestion('', ['foo', 'bar', ...localMethodNames], queryString.indexOf('|')) ] ); }); @@ -1051,38 +1062,38 @@ describe('query/suggestions (tolerant mode)', () => { describeCasesTolerant('ternary operator', { '1?|': [ - suggestion('', ['foo', 'bar'], 2, 2) + suggestion('', ['foo', 'bar', ...localMethodNames], 2, 2) ], '1?:|': [ - suggestion('', ['foo', 'bar'], 3, 3) + suggestion('', ['foo', 'bar', ...localMethodNames], 3, 3) ] }); describeCasesTolerant('variables', { '|$|;|': [ - suggestion('$', ['foo', 'bar'], 0, 1), - suggestion('$', ['foo', 'bar'], 0, 1), - suggestion('', ['foo', 'bar'], 2) + suggestion('$', ['foo', 'bar', ...localMethodNames], 0, 1), + suggestion('$', ['foo', 'bar', ...localMethodNames], 0, 1), + suggestion('', ['foo', 'bar', ...localMethodNames], 2) ], '| |$| |;| |': [ null, - suggestion('$', ['foo', 'bar'], 1, 2), - suggestion('$', ['foo', 'bar'], 1, 2), + suggestion('$', ['foo', 'bar', ...localMethodNames], 1, 2), + suggestion('$', ['foo', 'bar', ...localMethodNames], 1, 2), null, - suggestion('', ['foo', 'bar'], 4), - suggestion('', ['foo', 'bar'], 5) + suggestion('', ['foo', 'bar', ...localMethodNames], 4), + suggestion('', ['foo', 'bar', ...localMethodNames], 5) ], '$|v|a|r|:|;|': [ null, null, null, null, - suggestion('', ['foo', 'bar'], 5), - suggestion('', ['$var:variable', 'foo', 'bar'], 6) + suggestion('', ['foo', 'bar', ...localMethodNames], 5), + suggestion('', ['$var:variable', 'foo', 'bar', ...localMethodNames], 6) ], '$foo;$var:|;|': [ - suggestion('', ['$foo:variable', 'foo', 'bar'], 10), - suggestion('', ['$foo:variable', '$var:variable', 'foo', 'bar'], 11) + suggestion('', ['$foo:variable', 'foo', 'bar', ...localMethodNames], 10), + suggestion('', ['$foo:variable', '$var:variable', 'foo', 'bar', ...localMethodNames], 11) ], '$|x|:|$|;|$|x|.|': [ null, @@ -1092,7 +1103,7 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('$x', ['$x:variable'], 5, 7), suggestion('$x', ['$x:variable'], 5, 7), suggestion('$x', ['$x:variable'], 5, 7), - suggestion('', ['foo', 'bar'], 8, 8) + suggestion('', ['foo', 'bar', ...localMethodNames], 8, 8) ], '$|x|:[{ qux: 1 }]+|$|-|$|;|$|x|.|': [ null, @@ -1104,16 +1115,16 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('$x', ['$x:variable'], 20, 22), suggestion('$x', ['$x:variable'], 20, 22), suggestion('$x', ['$x:variable'], 20, 22), - suggestion('', ['qux'], 23, 23) + suggestion('', ['qux', ...localMethodNames], 23, 23) ], '{x:|$|}.x.|': [ null, null, - suggestion('', ['foo', 'bar'], 8) + suggestion('', ['foo', 'bar', ...localMethodNames], 8) ], '$_:{ a: 1, b: 2 };{$|}.|': [ suggestion('$', ['$_:variable'], 19, 20), - null + suggestion('', [...localMethodNames], 22, 22) ], '$foo;{| |$|f|,| |f| |}': [ null, @@ -1121,8 +1132,8 @@ describe('query/suggestions (tolerant mode)', () => { suggestion('$f', ['$foo:variable'], 7, 9), suggestion('$f', ['$foo:variable'], 7, 9), null, - suggestion('f', ['$foo:variable', 'foo', 'bar'], 11, 12), - suggestion('f', ['$foo:variable', 'foo', 'bar'], 11, 12), + suggestion('f', ['$foo:variable', 'foo', 'bar', ...localMethodNames], 11, 12), + suggestion('f', ['$foo:variable', 'foo', 'bar', ...localMethodNames], 11, 12), null ], '$[| |$|a| |]': [ @@ -1133,26 +1144,26 @@ describe('query/suggestions (tolerant mode)', () => { null ], '$[=> $$ =| |]': [ - suggestion('', ['"foo":value', '"bar":value', 'a', 'b', 'c', 'd'], 9, 9), - suggestion('', ['"foo":value', '"bar":value', 'a', 'b', 'c', 'd'], 10, 10) + suggestion('', ['"foo":value', '"bar":value', 'a', 'b', 'c', 'd', ...localMethodNames], 9, 9), + suggestion('', ['"foo":value', '"bar":value', 'a', 'b', 'c', 'd', ...localMethodNames], 10, 10) ], '`${| |.| |}`': [ - suggestion('', ['foo', 'bar'], 3, 3), - suggestion('', ['foo', 'bar'], 4, 4), - suggestion('', ['foo', 'bar'], 5, 5), - suggestion('', ['foo', 'bar'], 6, 6) + suggestion('', ['foo', 'bar', ...localMethodNames], 3, 3), + suggestion('', ['foo', 'bar', ...localMethodNames], 4, 4), + suggestion('', ['foo', 'bar', ...localMethodNames], 5, 5), + suggestion('', ['foo', 'bar', ...localMethodNames], 6, 6) ], '`${| |.| |}${}`': [ - suggestion('', ['foo', 'bar'], 3, 3), - suggestion('', ['foo', 'bar'], 4, 4), - suggestion('', ['foo', 'bar'], 5, 5), - suggestion('', ['foo', 'bar'], 6, 6) + suggestion('', ['foo', 'bar', ...localMethodNames], 3, 3), + suggestion('', ['foo', 'bar', ...localMethodNames], 4, 4), + suggestion('', ['foo', 'bar', ...localMethodNames], 5, 5), + suggestion('', ['foo', 'bar', ...localMethodNames], 6, 6) ], '`${}${| |.| |}`': [ - suggestion('', ['foo', 'bar'], 6, 6), - suggestion('', ['foo', 'bar'], 7, 7), - suggestion('', ['foo', 'bar'], 8, 8), - suggestion('', ['foo', 'bar'], 9, 9) + suggestion('', ['foo', 'bar', ...localMethodNames], 6, 6), + suggestion('', ['foo', 'bar', ...localMethodNames], 7, 7), + suggestion('', ['foo', 'bar', ...localMethodNames], 8, 8), + suggestion('', ['foo', 'bar', ...localMethodNames], 9, 9) ] }); });