Skip to content

Commit

Permalink
More tests + fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mrspartak committed May 17, 2020
1 parent 7674ba9 commit 106bef6
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Hasura object mapping",
"main": "src/index.js",
"scripts": {
"test": "nyc --reporter=lcovonly ava",
"test": "nyc --reporter=html --reporter=lcovonly ava",
"test_dev": "nyc --reporter=html --reporter=text ava --watch",
"release": "npm-github-release",
"coverage": "nyc report --reporter=text-lcov | coveralls"
Expand Down
7 changes: 4 additions & 3 deletions src/gql/fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ exports.fieldsToGql = function (input) {
if (typeof input == 'string') return input;
else if (Array.isArray(input)) {
input.forEach((el) => {
if (Array.isArray(el)) throw new Error('array cant contain array');
if (typeof el == 'string') baseArray.push(el);
else if (Array.isArray(el)) throw new Error('array cant contain array');
else if (typeof el == 'object') {
if (typeof el.key == 'undefined' || typeof el.values == 'undefined') throw new Error('in array object must have keys: `key` & `values`');

Expand All @@ -42,7 +43,7 @@ exports.fieldsToGql = function (input) {
${subFragment}
}
`);
} else baseArray.push(el);
} else throw new Error(`unsupported type ${typeof el}`);
});
return baseArray.join('\n');
} else if (typeof input == 'object') {
Expand All @@ -60,5 +61,5 @@ exports.fieldsToGql = function (input) {
} else baseArray.push(key);
});
return baseArray.join('\n');
}
} else throw new Error(`unsupported type ${typeof input}`);
};
27 changes: 21 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class Hasura {

let query = `
${Object.values(queryFragments).join('\n')}
query ${queryName.join('_')} (${queryVariables.join(', ')}) {
query ${queryName.join('_')} ${queryVariables.length ? '(' + queryVariables.join(', ') + ')' : ''} {
${queryFields.join('\n')}
}
`;
Expand All @@ -159,9 +159,26 @@ class Hasura {
/*
{
[table_name]: {
insert: {},
update: {},
delete: {}
insert: {
objects
fields
fragment
},
update: {
where
_set
_inc
fields
fragment
},
delete: {
where
fields
fragment
}
}
}
*/
Expand Down Expand Up @@ -214,8 +231,6 @@ class Hasura {
queryFlatSetting.push(built.query.flatSetting);
variables = Object.assign({}, variables, built.variables);
});

console.log('queryFlatSetting', queryFlatSetting);
});

let query = `
Expand Down
2 changes: 1 addition & 1 deletion src/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class Table {
name: `Q${this.params.name}`,
variables: query_variables,
fields: `
${this.params.name}(${query_field_variables.join(', ')}) {
${this.params.name} ${query_field_variables.length ? '(' + query_field_variables.join(', ') + ')' : ''} {
${fields}
}
`,
Expand Down
20 changes: 20 additions & 0 deletions tests/fragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,24 @@ test('check for incopatable fields format', (t) => {
},
{ instanceOf: Error },
);

t.throws(
() => {
return new Fragment({
table: 'test',
fields: 123,
});
},
{ instanceOf: Error },
);

t.throws(
() => {
return new Fragment({
table: 'test',
fields: [123],
});
},
{ instanceOf: Error },
);
});
34 changes: 34 additions & 0 deletions tests/hasura.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require('dotenv').config();
const test = require('ava');
const { Hasura } = require('../src/');

test('throws without params', (t) => {
t.throws(
() => {
const orm = new Hasura();
},
{ instanceOf: Error },
);
});

test('still throws without params', (t) => {
t.throws(
() => {
const orm = new Hasura({
graphqlUrl: 'ufhreioor',
});
},
{ instanceOf: Error },
);
});

test('graphqlUrl is not an url', (t) => {
t.throws(
() => {
const orm = new Hasura({
graphqlUrl: 123,
});
},
{ instanceOf: Error },
);
});
194 changes: 193 additions & 1 deletion tests/real_query.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,201 @@ test.before(async (t) => {
t.context.orm = orm;
});

test('test tables existing', (t) => {
test.serial('test tables existing', (t) => {
let orm = t.context.orm;

t.is(typeof orm.tables._om_test, 'object');
t.is(typeof orm.tables._om_test_types, 'object');
});

test.serial('delete all records', async (t) => {
let orm = t.context.orm;

var [err, response] = await orm.mutate({
_om_test: {
delete: {
where: {},
},
},
_om_test_types: {
delete: {
where: {},
},
},
});
if (err) throw err;

t.is(typeof response._om_test.delete, 'object');
t.is(typeof response._om_test_types.delete, 'object');
});

test.serial('add records with transaction', async (t) => {
let orm = t.context.orm;

/*
Note!
By default all selects are only on base table fields,
so nested object is created, but not returned
until you define a fragment or whole scheme to return
*/
var [err, response] = await orm.mutate({
_om_test: {
insert: {
objects: {
text: 'test',
types: {
data: {
type: 'some_type',
description: 'this is good type',
},
},
},
},
},
_om_test_types: {
insert: {
objects: {
type: 'another_type',
},
},
},
});
if (err) throw err;

t.is(response._om_test.insert[0].text, 'test');
t.is(response._om_test.insert[0].type, 'some_type');

t.is(response._om_test_types.insert[0].type, 'another_type');
});

test.serial('return nested data with custom scheme', async (t) => {
let orm = t.context.orm;

var [err, response] = await orm.mutate({
_om_test: {
insert: {
objects: {
text: 'test 2',
types: {
data: {
type: 'some_type_2',
description: 'this is good type',
},
},
},
fields: `
id
types {
description
}
`,
},
},
});
if (err) throw err;

/*
Note!
Relationship here is N - 1, so we directly accessing description
*/
t.is(response._om_test.insert[0].types.description, 'this is good type');
});

test.serial('insert and update', async (t) => {
let orm = t.context.orm;

var [err, response] = await orm.mutate({
_om_test: {
insert: {
objects: {
text: 'test 3',
},
},
update: {
where: {
type: {
_eq: 'some_type_2',
},
},
_set: {
text: 'changed',
},
_inc: {
increment: 10,
},
},
},
});
if (err) throw err;

t.is(err, null);
t.is(typeof response, 'object');

t.is(response._om_test.insert[0].text, 'test 3');
t.is(response._om_test.insert[0].type, null);

t.is(response._om_test.update[0].type, 'some_type_2');
t.is(response._om_test.update[0].text, 'changed');
t.is(response._om_test.update[0].increment, 10);
});

test.serial('failing transaction', async (t) => {
let orm = t.context.orm;

var [err, response] = await orm.mutate({
_om_test: {
insert: {
objects: {
text: 'will not exist',
},
},
update: {
where: {
type: {
_eq: 'some_type_2',
},
},
_inc: {
increment: -100,
},
},
},
});

t.true(err instanceof Error);

var [err, response] = await orm.query({
_om_test: {
where: {
text: {
_eq: 'will not exist',
},
},
},
});
if (err) throw err;

/*
Note!
By default if only 1 table is used
the table key will be flatened
so response is avialable just in variable
*/
t.is(response.length, 0);
});

test.serial('error building query', async (t) => {
let orm = t.context.orm;

var [err, response] = await orm.query({
fields: 123,
});

t.true(err instanceof Error);

var [err, response] = await orm.mutate({
fields: 123,
});

t.true(err instanceof Error);
});

0 comments on commit 106bef6

Please sign in to comment.