From 44812f24dba4e9f9c3e442eb2032a2376f5575ce Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 31 Mar 2021 00:23:07 +1100 Subject: [PATCH] Improved the test --- source/index.js | 3 +- source/parse-query-tree.js | 5 +- test/index.js | 93 ++++++++++++++++++++++++++++++++------ 3 files changed, 85 insertions(+), 16 deletions(-) diff --git a/source/index.js b/source/index.js index 3682004..783d576 100644 --- a/source/index.js +++ b/source/index.js @@ -35,7 +35,8 @@ const sineQL = (schema, { queryHandlers }, options = {}) => { const result = await queryHandlers[queryTree.typeName](queryTree, typeGraph); if (options.debug) { - console.log('Query tree results:\n', result); + console.log('Query tree results:'); + console.dir(result, { depth: null }); } return [200, result]; diff --git a/source/parse-query-tree.js b/source/parse-query-tree.js index 312f067..140f82e 100644 --- a/source/parse-query-tree.js +++ b/source/parse-query-tree.js @@ -35,7 +35,7 @@ const readBlock = (tokens, current, superType, typeGraph, options) => { break; } - //check for block-level keywords + //check for block-level keywords (modifiers need to form a chain from the leaf) let modifier = null; if (['match'].includes(tokens[current - 1])) { modifier = tokens[current - 1]; @@ -68,7 +68,8 @@ const readBlock = (tokens, current, superType, typeGraph, options) => { current = pos; //pos points past the end of the block if (options.debug) { - console.log(`${fieldName}: ${JSON.stringify(result[fieldName])}`); + console.log(`${fieldName}:`); + console.dir(result[fieldName], { depth: null }); } continue; diff --git a/test/index.js b/test/index.js index c175f60..616b5eb 100644 --- a/test/index.js +++ b/test/index.js @@ -12,9 +12,38 @@ const books = { const { attributes, where } = args; - //TODO: make this more generic - console.log('books attributes:', attributes); - console.log('books where', where); + //filter out non-matching elements + arr = arr.filter(element => { + if (Object.keys(where).length == 0) { + return true; + } + + if (where.title && where.published) { + return element.title == where.title.eq && element.published == where.published.eq; + } + + if (where.title) { + return element.title == where.title.eq; + } + + if (where.published) { + return element.published == where.published.eq; + } + + return false; + }); + + //filter out non-used attributes + arr = arr.map(element => { + //only they element keys that are in attributes + const keys = Object.keys(element).filter(key => attributes.includes(key)); + + //determine which fields to carry over + const ret = {}; + keys.forEach(key => ret[key] = element[key]); + + return ret; + }); return arr; } @@ -30,8 +59,38 @@ const authors = { const { attributes, where } = args; - console.log('authors attributes:', attributes); - console.log('authors where', where); + //filter out non-matching elements + arr = arr.filter(element => { + if (Object.keys(where).length == 0) { + return true; + } + + if (where.name && where.books) { + return element.name == where.name.eq; //books is always true because they are never queried + } + + if (where.name) { + return element.name == where.name.eq; + } + + if (where.books) { + return true; //books is always true because they are never queried + } + + return false; + }); + + //filter out non-used attributes + arr = arr.map(element => { + //only they element keys that are in attributes + const keys = Object.keys(element).filter(key => attributes.includes(key)); + + //determine which fields to carry over + const ret = {}; + keys.forEach(key => ret[key] = element[key]); + + return ret; + }); return arr; } @@ -70,7 +129,7 @@ const queryHandlers = { //get the fields alone const { typeName, ...fields } = query; - //get the names of matched fields + //get the names of matched fields (fields to find) const matchedNames = Object.keys(fields).filter(field => fields[field].match); //short-circuit if querying everything @@ -78,7 +137,7 @@ const queryHandlers = { if (matchedNames.length > 0) { //build the "where" object matchedNames.forEach(mn => { - if (query[mn].match !== true) { + if (query[mn].match !== true) { //true means it's a compound type where[mn] = { [Op.eq]: query[mn].match }; } }); @@ -88,8 +147,8 @@ const queryHandlers = { const scalars = Object.keys(fields).filter(field => graph[fields[field].typeName].scalar); const nonScalars = Object.keys(fields).filter(field => !graph[fields[field].typeName].scalar); - const authorResults = await authors.findAll({ - attributes: scalars, //fields to find (keys) + let authorResults = await authors.findAll({ + attributes: Object.keys(fields), //fields to find (keys) where: where }); //sequelize ORM model @@ -99,7 +158,12 @@ const queryHandlers = { //for each author, update this non-scalar field with the non-scalar's recursed value authorResults.forEach(author => { - author[nonScalar] = nonScalarArray.filter(ns => author[nonScalar].includes(ns.id)); + author[nonScalar] = nonScalarArray.filter(ns => author[nonScalar].includes(ns.id)); //using the hacked-in ID field + }); + + //prune the authors when matching, but their results are empty + authorResults = authorResults.filter(author => { + return !(fields[nonScalar].match && author[nonScalar].length == 0); }); }); @@ -116,6 +180,9 @@ const queryHandlers = { //get the fields alone const { typeName, ...fields } = query; + //hack the book id into the fields list (if it's not there already) + fields.id = fields.id || { typeName: 'Integer', scalar: true }; + //get the names of matched fields const matchedNames = Object.keys(fields).filter(field => fields[field].match); @@ -157,10 +224,10 @@ type Author { const sineQL = require('../source/index.js'); //run the function in debug mode (builds type graph) -const sine = sineQL(schema, { queryHandlers }, { debug: true }); +const sine = sineQL(schema, { queryHandlers }, { debug: false }); (async () => { - const [code, result] = await sine('Author { name match books { match title "The Wind in the Willows" published } }'); + const [code, result] = await sine('Author { match name "Frank" books { title published } }'); - console.log('\n\n', JSON.stringify(result)); + console.dir(result, { depth: null }); })();