Skip to content
This repository has been archived by the owner on Feb 21, 2023. It is now read-only.

Commit

Permalink
Added proper unit tests using Jest
Browse files Browse the repository at this point in the history
  • Loading branch information
pratyushmittal committed Jan 16, 2016
1 parent 8983096 commit 1cb8816
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 28 deletions.
3 changes: 3 additions & 0 deletions .babelrc
@@ -0,0 +1,3 @@
{
"presets": ["stage-0"]
}
4 changes: 3 additions & 1 deletion .jshintrc
Expand Up @@ -13,6 +13,8 @@
"beforeEach": false,
"afterEach": false,
"module": false,
"inject": false
"inject": false,
"async": false,
"await": false
}
}
75 changes: 48 additions & 27 deletions package.json
@@ -1,30 +1,51 @@
{
"name": "react-native-store",
"version": "0.2.4",
"description": "A simple database base on react-native AsyncStorage.",
"main": "./src/index.js",
"scripts": {
"build": "babel src --watch --stage 0 --out-dir libs"
},
"repository": {
"type": "git",
"url": "https://github.com/thewei/react-native-store.git"
},
"keywords": [
"react-component",
"react-native",
"ios",
"react",
"AsyncStorage",
"dataBase"
"name": "react-native-store",
"version": "0.2.4",
"description": "A simple database base on react-native AsyncStorage.",
"main": "./src/index.js",
"scripts": {
"build": "babel src --watch --stage 0 --out-dir libs",
"test": "jest"
},
"repository": {
"type": "git",
"url": "https://github.com/thewei/react-native-store.git"
},
"jest": {
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"testPathIgnorePatterns": [
"/node_modules/"
],
"author": "thewei",
"license": "MIT",
"bugs": {
"url": "https://github.com/thewei/react-native-store/issues"
},
"homepage": "https://github.com/thewei/react-native-store",
"devDependencies": {
"babel": "^5.8.23"
}
"testFileExtensions": [
"js"
],
"testPathDirs": [
"src"
],
"unmockedModulePathPatterns": [
"promise",
"source-map"
]
},
"keywords": [
"react-component",
"react-native",
"ios",
"react",
"AsyncStorage",
"dataBase"
],
"author": "thewei",
"license": "MIT",
"bugs": {
"url": "https://github.com/thewei/react-native-store/issues"
},
"homepage": "https://github.com/thewei/react-native-store",
"devDependencies": {
"babel-jest": "^6.0.1",
"babel-preset-stage-0": "^6.3.13",
"jest": "^0.1.40",
"jest-cli": "^0.8.2",
"react-native": "^0.18.0-rc"
}
}
77 changes: 77 additions & 0 deletions src/__tests__/filter_test.js
@@ -0,0 +1,77 @@
'use strict';
jest.dontMock('../filter.js');

const testDataSet = {
'1': { _id: 1, name: 'j', price: 3, location: { name: 'USA', coords: { lat: 123, lng: 123 } } },
'2': { _id: 2, name: 'a', price: 4, location: { name: 'USA', coords: { lat: 123, lng: 123 } } },
'3': { _id: 3, name: 'v', price: 1, location: { name: 'USA', coords: { lat: 123, lng: 123 } } },
'4': { _id: 4, name: 'a', price: 2, location: { name: 'USA', coords: { lat: 123, lng: 123 } } },
'5': { _id: 5, name: 's', price: 1, location: { name: 'EU', coords: { lat: 423, lng: 123 } } },
'6': { _id: 6, name: 'c', price: 1, location: { name: 'EU', coords: { lat: 423, lng: 123 } } },
'7': { _id: 7, name: 'r', price: 7, location: { name: 'EU', coords: { lat: 423, lng: 123 } } },
'8': { _id: 8, name: 'i', price: 9, location: { name: 'Outer Space', coords: { lat: 999, lng: 999 } } },
'9': { _id: 9, name: 'p', price: 4, location: { name: 'InterGalatic Space', coords: { lat: 9001, lng: 42 } } },
'10': { _id: 10, name: 't', price: 999, location: { name: 'Outside', coords: { lat: -1, lng: 0 } } },
};

describe('filter Tests', function() {
var Filter;

beforeEach(function() {
var Filter_ = require('../filter.js');
Filter = new Filter_();
});

it('should filter using find', function() {
var filter = {
where: {
or: [
{
price: { between: [0, 5] },
location: { name: 'EU' }
}, {
location: { name: { regexp: 'space' } }
}
]
},
fields: {name: false},
order: {price: 'ASC'}
};
var results = Filter.apply(testDataSet, filter);
expect(results.length).toEqual(4);
var expected = [
{ _id:5, price: 1, location: { name: 'EU', coords: { lat: 423, lng: 123 } } },
{ _id:6, price: 1, location: { name: 'EU', coords: { lat: 423, lng: 123 } } },
{ _id:9, price: 4, location: { name: 'InterGalatic Space', coords: { lat: 9001, lng: 42 } } },
{ _id:8, price: 9, location: { name: 'Outer Space', coords: { lat: 999, lng: 999 } } }
];
expect(results).toEqual(expected);
});

it('should filter using findById', function() {
var findById = {
where: {_id: 3}
};
var results = Filter.apply(testDataSet, findById);
var expected = [
{ _id: 3, name: 'v', price: 1, location: { name: 'USA', coords: { lat: 123, lng: 123 } } }
];
expect(results).toEqual(expected);
});

it('should filter entries lexicographically', function() {
var lexiFind = {
where: {
name: { lte: 'f' }
}
};
var results = Filter.apply(testDataSet, lexiFind);
var expected = [
{ _id: 2, name: 'a', price: 4, location: { name: 'USA', coords: { lat: 123, lng: 123 } } },
{ _id: 4, name: 'a', price: 2, location: { name: 'USA', coords: { lat: 123, lng: 123 } } },
{ _id: 6, name: 'c', price: 1, location: { name: 'EU', coords: { lat: 423, lng: 123 } } }
];
expect(results).toEqual(expected);
});

});
33 changes: 33 additions & 0 deletions src/__tests__/mockStorage.js
@@ -0,0 +1,33 @@
"use strict";
var cache = {};
var mock = {
setItem: jest.genMockFunction().mockImplementation((key, value) => {
return new Promise((resolve, reject) => {
resolve(cache[key] = value);
});
}),
getItem: jest.genMockFunction().mockImplementation(key => {
return new Promise((resolve, reject) => {
if (cache.hasOwnProperty(key))
resolve(cache[key]);
resolve('');
});
}),
removeItem: jest.genMockFunction().mockImplementation(key => {
return new Promise((resolve, reject) => {
if (cache.hasOwnProperty(key))
resolve(delete cache[key]);
reject('No such item!');
});
}),
clear: jest.genMockFunction().mockImplementation(() => {
return new Promise((resolve, reject) => {
resolve(cache = {});
});
}),
_forceClear() {
cache = {};
}
};

module.exports = mock;
127 changes: 127 additions & 0 deletions src/__tests__/model_test.js
@@ -0,0 +1,127 @@
'use strict';
jest.dontMock('../filter.js');
jest.dontMock('../model.js');
var astore = require.requireActual('./mockStorage.js');
jest.setMock('react-native', {AsyncStorage: astore});

// To view log of any syncstorage calls, use inside code:
// console.log('set calls', astore.setItem.mock.calls)

describe('model Tests', function() {
var Model;

beforeEach(function() {
var Model_ = require('../model.js');
Model = new Model_('modelName', 'dbName');
});

afterEach(() => {
astore._forceClear();
});

pit('should test create database', function() {
return Model.getDatabase().then(resp => {
expect(resp).toEqual({});
expect(astore.getItem).toBeCalled();
expect(astore.setItem).toBeCalledWith('dbName', '{}');
});
});

pit('should add the data to AsyncStorage', function() {
return Model.add({foo: 'bar'}).then(resp => {
expect(resp).toEqual({_id: 1, foo: 'bar'});
var dbJson = '{"modelName":{"totalrows":1,"autoinc":2,"rows":{"1":{"foo":"bar","_id":1}}}}';
expect(astore.setItem).toBeCalledWith('dbName', dbJson);
});
});

pit('should test findById', function() {
return Model.findById(3).then(resp => {
expect(resp).toEqual(null);
});
});

pit('should destroy the model', function() {
return Model.add({foo: 'bar'})
.then(resp => {
Model.destroy();
})
.then(resp => {
expect(astore.removeItem).toBeCalledWith('dbName');
});
});

pit('should update existing rows on filter', async () => {
var testData = [
{foo: 0, bar: 0, foobar: 'foobar'},
{foo: 0, bar: 1, foobar: 'foobar'},
{foo: 1, bar: 0, foobar: 'foo'},
{foo: 1, bar: 1, foobar: 'foobar'},
];
await Model.multiAdd(testData);
var resp = await Model.update(
{foobar: 'bar'}, {where: {bar: 1}}
);
var expected = [
{_id: 2, foo: 0, bar: 1, foobar: 'bar'},
{_id: 4, foo: 1, bar: 1, foobar: 'bar'},
];
expect(resp).toEqual(expected);
var dbJson = {"modelName":{"totalrows":4,"autoinc":5,"rows":{
1: {"foo":0,"bar":0,"foobar":"foobar","_id":1},
2: {"foo":0,"bar":1,"foobar":"bar","_id":2},
3: {"foo":1,"bar":0,"foobar":"foo","_id":3},
4: {"foo":1,"bar":1,"foobar":"bar","_id":4}
}}};
expect(astore.setItem).toBeCalledWith('dbName', JSON.stringify(dbJson));
});

pit('should update row with given id', async () => {
var testData = [
{foo: 0, bar: 0, foobar: 'foobar'},
{foo: 0, bar: 1, foobar: 'foobar'},
{foo: 1, bar: 0, foobar: 'foo'},
{foo: 1, bar: 1, foobar: 'foobar'},
];
await Model.multiAdd(testData);
var resp = await Model.updateById({foobar: 'barfoo'}, 2);
var expected = { _id: 2, foo: 0, bar: 1, foobar: 'barfoo'};
expect(resp).toEqual(expected);
});

pit('should remove rows based on filter', async() => {
var testData = [
{foo: 0, bar: 0, foobar: 'foobar'},
{foo: 0, bar: 1, foobar: 'foobar'},
{foo: 1, bar: 0, foobar: 'foo'},
{foo: 1, bar: 1, foobar: 'foobar'},
];
await Model.multiAdd(testData);
astore.setItem.mockClear();
var resp = await Model.remove({where: {foo: 1}});
var dbJson = {"modelName":{"totalrows":2,"autoinc":5,"rows":{
1: {"foo":0,"bar":0,"foobar":"foobar","_id":1},
2: {"foo":0,"bar":1,"foobar":"foobar","_id":2},
}}};
expect(astore.setItem).toBeCalledWith('dbName', JSON.stringify(dbJson));
});

pit('should remove rows based on id', async() => {
var testData = [
{foo: 0, bar: 0, foobar: 'foobar'},
{foo: 0, bar: 1, foobar: 'foobar'},
{foo: 1, bar: 0, foobar: 'foo'},
{foo: 1, bar: 1, foobar: 'foobar'},
];
await Model.multiAdd(testData);
astore.setItem.mockClear();
var resp = await Model.removeById(1);
var dbJson = {"modelName":{"totalrows":3,"autoinc":5,"rows":{
2: {"foo":0,"bar":1,"foobar":"foobar","_id":2},
3: {"foo":1,"bar":0,"foobar":"foo","_id":3},
4: {"foo":1,"bar":1,"foobar":"foobar","_id":4}
}}};
expect(astore.setItem).toBeCalledWith('dbName', JSON.stringify(dbJson));
});

});

0 comments on commit 1cb8816

Please sign in to comment.