mirror of
https://github.com/Ratstail91/sineQL.git
synced 2025-11-29 02:34:28 +11:00
Working on test framework
This commit is contained in:
@@ -138,8 +138,9 @@ The fields can be altered as well, using the query language's built-in keywords:
|
||||
* delete
|
||||
* match
|
||||
* set
|
||||
* typeName
|
||||
|
||||
`create`, `update` and `delete` work as expected.
|
||||
`create`, `update` and `delete` are still to be defined properly, but they'll probably work like this:
|
||||
|
||||
### Create
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ const parseInput = require('./parse-input');
|
||||
const buildTypeGraph = (schema, options) => {
|
||||
//the default graph
|
||||
let graph = {
|
||||
String: { scalar: true },
|
||||
Integer: { scalar: true },
|
||||
Float: { scalar: true },
|
||||
Boolean: { scalar: true },
|
||||
String: { typeName: 'String', scalar: true },
|
||||
Integer: { typeName: 'Integer', scalar: true },
|
||||
Float: { typeName: 'Float', scalar: true },
|
||||
Boolean: { typeName: 'Boolean', scalar: true },
|
||||
};
|
||||
|
||||
//parse the schema
|
||||
@@ -35,7 +35,7 @@ const buildTypeGraph = (schema, options) => {
|
||||
throw 'Unexpected keyword ' + tokens[pos];
|
||||
}
|
||||
|
||||
graph[tokens[pos++]] = { scalar: true };
|
||||
graph[tokens[pos++]] = { typeName: tokens[pos - 1], scalar: true };
|
||||
|
||||
if (options.debug) {
|
||||
console.log(`Defined ${tokens[pos - 1]}:\n`, graph[tokens[pos - 1]]);
|
||||
@@ -63,7 +63,7 @@ const parseCompoundType = (tokens, pos, scalars, options) => {
|
||||
}
|
||||
|
||||
//graph component to be returned
|
||||
const compound = {};
|
||||
const compound = { typeName: tokens[pos - 1] };
|
||||
|
||||
//for each line of the compound type
|
||||
while (tokens[pos++] && tokens[pos] !== '}') {
|
||||
|
||||
@@ -1 +1 @@
|
||||
["type", "scalar", "create", "update", "delete", "set", "match"]
|
||||
["type", "scalar", "create", "update", "delete", "set", "match", "typeName"]
|
||||
125
test/index.js
125
test/index.js
@@ -1,7 +1,122 @@
|
||||
//the library to test
|
||||
const sineQL = require('../source/index.js');
|
||||
//mock tools
|
||||
const books = {
|
||||
findAll: async args => {
|
||||
let arr = [
|
||||
{ title: 'The Wind in the Willows', published: '1908-06-15' }
|
||||
];
|
||||
|
||||
//the dummy values
|
||||
const { attributes, where } = args;
|
||||
|
||||
arr = arr.filter(el => !where || el.title == where.title || el.published == where.published); //TODO: fix this
|
||||
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
|
||||
const authors = {
|
||||
findAll: async args => {
|
||||
const arr = [
|
||||
{ name: 'Kenneth Grahame', bookIds: [1] },
|
||||
];
|
||||
|
||||
const { attributes, where } = args;
|
||||
|
||||
arr = arr.filter(el => !where || el.title == where.title || el.published == where.published); //TODO: fix this
|
||||
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
|
||||
//the handler functions return arrays for each type, containing every element that satisfies the queries
|
||||
|
||||
//the "query" argument contains the object built from the sineQL query
|
||||
//the "graph" argument contains the typeGraph
|
||||
|
||||
//the task of the handler functions is to query the database, and return the correct results
|
||||
|
||||
/* possible values for "query" include:
|
||||
|
||||
{
|
||||
typeName: 'Author',
|
||||
name: { typeName: 'String', scalar: true, match: 'Kenneth Grahame' },
|
||||
books: { typeName: 'Book', match: {
|
||||
typeName: 'Book',
|
||||
title: { typeName: 'String', scalar: true, match: 'The wind in the Willows' }
|
||||
published: { typeName: 'Date', scalar: true }
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//depth-first search seems to be the best option
|
||||
//Each query shouldn't know if it's a sub-query
|
||||
|
||||
const handler = {
|
||||
//complex compound
|
||||
Author: async (query, graph) => {
|
||||
//get the fields alone
|
||||
const { typeName, ...fields } = query;
|
||||
|
||||
//get the names of matched fields
|
||||
const matchedNames = Object.keys(fields.filter(field => field.match));
|
||||
|
||||
//short-circuit if querying everything
|
||||
const where = {};
|
||||
if (matchedNames.length > 0) {
|
||||
//build the "where" object
|
||||
matchedNames.forEach(mn => {
|
||||
where[mn] = {
|
||||
[Op.eq]: query[mn].match
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//these are field names
|
||||
const scalars = Object.keys(fields).filter(field => graph[field.typeName].scalar);
|
||||
const nonScalars = Object.keys(fields).filter(field => !graph[field.typeName].scalar);
|
||||
|
||||
const results = await authors.findAll({
|
||||
attributes: scalars, //fields to find (keys)
|
||||
where: where
|
||||
}); //sequelize ORM model
|
||||
|
||||
nonScalars.forEach(nonScalar => {
|
||||
//delegate to a deeper part of the tree
|
||||
results[nonScalar] = handler[fields[nonScalar].typeName](fields[nonScalar], graph);
|
||||
});
|
||||
|
||||
//finally, return the results
|
||||
return results;
|
||||
},
|
||||
|
||||
//simple compound
|
||||
Book: async (query, graph) => {
|
||||
//get the fields alone
|
||||
const { typeName, ...fields } = query;
|
||||
|
||||
//get the names of matched fields
|
||||
const matchedNames = Object.keys(fields.filter(field => field.match));
|
||||
|
||||
//short-circuit if querying everything
|
||||
const where = {};
|
||||
if (matchedNames.length > 0) {
|
||||
//build the "where" object
|
||||
matchedNames.forEach(mn => {
|
||||
where[mn] = {
|
||||
[Op.eq]: query[mn].match
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//return the result
|
||||
return await books.findAll({
|
||||
attributes: Object.keys(fields), //fields to find
|
||||
where: where
|
||||
}); //sequelize ORM model
|
||||
}
|
||||
};
|
||||
|
||||
//the matching schema
|
||||
const schema = `
|
||||
scalar Date
|
||||
|
||||
@@ -16,8 +131,8 @@ type Author {
|
||||
}
|
||||
`;
|
||||
|
||||
const handler = null;
|
||||
//the library to test
|
||||
const sineQL = require('../source/index.js');
|
||||
|
||||
//run the function in debug mode (builds type graph)
|
||||
const sine = sineQL(schema, handler, { debug: true });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user