Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"presets": ["es2015", "stage-2"],
"plugins": [
["transform-builtin-extend", {"globals": ["Error"]}],
["transform-object-rest-spread"]
],
"env": {
"test": {
"sourceMap": "inline"
},
"development": {
"ignore": [
"test",
"__test__"
]
},
"production": {
"ignore": [
"test",
"__test__"
]
}
}
}
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
coverage
dist
**/node_modules/*
lib
24 changes: 19 additions & 5 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
{
"ecmaFeatures": {
"modules": false
},
"env": {
"browser": true,
"node": true,
"mocha": true
},
"extends": "airbnb-base",
"globals": {
"expect": true
},
"parserOptions": {
"sourceyType": "script"
},
"plugins": ["import-use"],
"rules": {
"semi": ["error", "never"],
"object-curly-spacing": ["error", "never"],
"no-use-before-define": ["error", {"functions": false, "classes": true}],
"no-underscore-dangle": 0
},
"env": {
"browser": true,
"node": true
"no-param-reassign": [2, {"props": false}],
"no-underscore-dangle": 0,
"import-use/flag-import": 2,
"object-shorthand": ["error", "properties"]
}
}
77 changes: 74 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,78 @@
# lg-toolbox
# Lg-Toolbox

Shared Learners Guild utilities.
This is the Lg-Toolbox, a set of tools that can be used across multiple services of the LOS.

## LICENSE
## Install

```
npm install lg-toolbox --save

yarn add lg-toolbox
```

## Usage

- In Ecmascript 6:
```javascript
import {dataService} from 'lg-toolbox'
```
- In Ecmascript 5 or lower:
```javascript
const toolbox = require('lg-toolbox')
toolbox.dataService(rethinkdb, options)
```
If rethinkdbdash is already currently instantiated:
```javascript
const rethinkDashInstance = rethinkdbdash()

const ds = dataService(rethinkDashInstance)
```
- If config object is provided, dataService will return a rethinkdbdash instance with the given config:
```javascript
const config = {
host: hostname,
port: port,
db: pathname,
authKey: auth,
ssl: dbCert,
relativeTo: DATA_SERVICE_DIR,
migrationsDirectory: directory name,
}

const ds = dataService(config)
```
- When adding optional Thinky Models and/or Queries:
```javascript
const options = {
models: [array-of-models] || relative directoryPath,
queries: [array-of-queries] || relative directoryPath
}

const ds = dataService(config, options)

ds will contain:
r: { rethinkdbdash instance },
models: [ array of thinky models ],
queries: [ array of query functions ]

const { r, models, queries } = ds

```
## Includes

- dataService

## Third Party modules

- auto-loader
- rethinkdb
- rethinkdbdash
- thinky

## Contributing

Create Github issues for all bugs, features & requests. Pull requests are welcome. Make sure tests are included.

## License

See the [LICENSE](./LICENSE) file.
13 changes: 13 additions & 0 deletions eslint-plugin-import-use/flag-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
rules: {
'flag-import': {
create: function (context) {
return {
ImportDeclaration(node) {
context.report(node, 'Cannot use Import in CommonJs Module')
},
}
},
},
},
}
11 changes: 11 additions & 0 deletions eslint-plugin-import-use/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "eslint-plugin-import-use",
"version": "0.0.1",
"main": "flag-import.js",
"devDependencies": {
"eslint": "~4.4.1"
},
"engines": {
"node": ">=0.10.0"
}
}
34 changes: 32 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,53 @@
"name": "lg-toolbox",
"version": "1.0.0",
"description": "Shared Learners Guild utilities",
"lib": "main",
"engines": {
"node": "6.11.x",
"npm": "3.7.x"
},
"scripts": {
"test": "./node_modules/.bin/eslint src/**/*.js"
"build": "NODE_ENV=production npm run clean && ./node_modules/.bin/babel -d lib/ src/",
"clean": "./node_modules/.bin/rimraf ./lib/*",
"prepublish": "npm run build && npm test",
"test:run": "NODE_ENV=test ./node_modules/.bin/mocha --opts ./src/test/mocha.opts $(find . -path './**/__tests__/*.test.js' ! -ipath '*node_modules*')",
"test:lint": "./node_modules/.bin/eslint .",
"test": "npm run build && npm run test:lint && npm run test:run"
},
"authors": [
{
"name": "Learners Guild",
"email": "sj@learnersguild.org"
},
{
"name": "Abraham Ferguson",
"email": "jhnfgie1989@gmail.com"
},
{
"name": "Jose Chavez",
"email": "jbchavez19@gmail.com"
}
],
"license": "MIT",
"devDependencies": {
"chai": "^4.1.1",
"chai-as-promised": "^7.1.1",
"eslint": "^4.4.1",
"eslint-config-airbnb-base": "^11.3.1",
"eslint-plugin-import": "^2.7.0"
"eslint-plugin-import-use": "file:eslint-plugin-import-use",
"jsdom": "^8.0.4",
"mocha": "^3.5.0",
"sinon-chai": "^2.13.0"
},
"dependencies": {
"auto-loader": "^0.2.0",
"babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"rethinkdb": "^2.3.3",
"rethinkdbdash": "^2.3.31",
"thinky": "^2.3.8"
}
}
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export {default} from './services'
const dataService = require('./services/dataService')

module.exports = dataService
129 changes: 129 additions & 0 deletions src/services/dataService/__tests__/dataService.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
const path = require('path')

const rethinkdbdash = require('rethinkdbdash')

const dataService = require('../index')
const truncateTables = require('../../../util/index').truncateTables
const dummyModelModel = require('./models/dummyModel')
const dummyModelModelTwo = require('./models/dummyModelTwo')
const dummyQuery = require('./queries/dummyQuery')
const dummyQueryTwo = require('./queries/dummyQueryTwo')

const dbName = 'lgToolboxTest'
const rethinkdb = rethinkdbdash({db: dbName})

describe('data service', () => {
describe('rethinkdb param', () => {
describe('is a config object', () => {
it('returns a rethinkdb instance with provided config', () => {
const ds = dataService({})
expect(ds.r).to.be.a('function')
})
})
describe('it is a rethinkdb client', () => {
it('returns the same rethinkdb instance', () => {
const ds = dataService(rethinkdb)
expect(ds.r).to.be.a('function')
expect(ds.r).to.be.eql(rethinkdb)
})
})
it('throws an error if null', () => {
expect(dataService).to.throw('rethinkdb parameter config or client is required')
})
it('throws an error if not a config object or a rethinkdb client', () => {
expect(() => dataService('I\'m a random string')).to.throw('first parameter must be a config object or client')
})
})

describe('options param', () => {
describe('models', () => {
it('throws an error if not file path or array', () => {
expect(() => dataService(rethinkdb, {models: 5})).to.throw('options.models must be a path to directory or array of model definition functions')
})
describe('is a file path', () => {
it('returns thinky models', () => {
const options = {models: path.join(__dirname, '/models')}
const ds = dataService(rethinkdb, options)
expect(ds).to.have.own.property('DummyModel')
expect(ds).to.have.own.property('DummyModelTwo')
})
})
describe('is an array', () => {
it('returns thinky models', () => {
const options = {models: [dummyModelModel, dummyModelModelTwo]}
const ds = dataService(rethinkdb, options)
expect(ds).to.have.own.property('DummyModel')
expect(ds).to.have.own.property('DummyModelTwo')
})
})
})
describe('queries', () => {
it('throws an error if not file path or array', () => {
expect(() => dataService(rethinkdb, {queries: 5})).to.throw('options.queries must be a path to directory or array of query functions')
})
describe('is a file path', () => {
it('returns query functions contained within the data service object', () => {
const options = {queries: path.join(__dirname, '/queries')}
const ds = dataService(rethinkdb, options)
expect(ds).to.have.own.property('dummyQuery')
expect(ds).to.have.own.property('dummyQueryTwo')
})
})
describe('is an array', () => {
it('returns query functions contained within the data service object', () => {
const options = {queries: [dummyQuery, dummyQueryTwo]}
const ds = dataService(rethinkdb, options)
expect(ds).to.have.own.property('dummyQuery')
expect(ds).to.have.own.property('dummyQueryTwo')
})
})
})
})
describe('thinky models', async () => {
const options = {models: [dummyModelModel, dummyModelModelTwo]}
const ds = dataService(rethinkdb, options)
const {DummyModel} = ds

let dummy
beforeEach(async () => {
await truncateTables(rethinkdb)
dummy = await DummyModel.save({})
})
it('save method sets updatedAt property', async () => {
expect(dummy).to.be.an('object')
expect(dummy).to.have.own.property('id')
expect(dummy).to.have.own.property('updatedAt')
expect(dummy.id).to.be.a('string')
expect(dummy.updatedAt).to.be.an.instanceof(Date)
})
it('updateWithTimestamp sets updatedAt property to current time', async () => {
const updatedDummy = await DummyModel
.get(dummy.id)
.updateWithTimestamp()
expect(dummy.id).to.be.equal(updatedDummy.id)
expect(dummy.updatedAt).to.be.an.instanceof(Date)
expect(updatedDummy.updatedAt).to.be.an.instanceof(Date)
expect(dummy.updatedAt).to.not.be.equal(updatedDummy.updatedAt)
})
it('upsert either saves or updates rows based on whether instance exists', async () => {
const savedDummy = await DummyModel.upsert()
expect(savedDummy).to.be.an('object')
expect(savedDummy).to.have.own.property('id')
expect(savedDummy).to.have.own.property('updatedAt')
const updatedDummy = await DummyModel.upsert(dummy)
expect(dummy.id).to.be.equal(updatedDummy.id)
expect(dummy.updatedAt).to.not.be.equal(updatedDummy.updatedAt)
})
it('creates thinky model associations', async () => {
const {DummyModelTwo} = ds
const dummyTwo = await DummyModelTwo.save({
dummyModelId: dummy.id,
name: 'My Name is DummyTwo and I belong to Dummy',
})
const dummyTwoJoined = await DummyModelTwo.get(dummyTwo.id)
.getJoin()
.run()
expect(dummyTwoJoined).has.own.property('dummys')
})
})
})
20 changes: 20 additions & 0 deletions src/services/dataService/__tests__/models/dummyModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function dummyModelModel(thinky) {
const {r, type: {string, date}} = thinky
return {
name: 'DummyModel',
table: 'dummys',
schema: {
id: string()
.uuid(4)
.allowNull(false),
updatedAt: date()
.allowNull(false)
.default(r.now()),
},
associate: (DummyModel, models) => {
DummyModel.hasOne(models.DummyModelTwo, 'twoDummys', 'id', 'dummyModelId', {init: false})
},
}
}

module.exports = dummyModelModel
Loading