Skip to content

Commit a19b798

Browse files
committed
#268: Standardise Storage constructor
1 parent 7eb01fa commit a19b798

16 files changed

+142
-243
lines changed

core/loadModel.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Storage from '../lib/Storage.js';
1919
*/
2020
export default async function loadModel(next) {
2121
const modelPath = path.join(this.dir, this.config.modelsDir);
22-
const structure = {};
22+
const schema = {};
2323
let files = {};
2424

2525
/* Load all models in the model directory */
@@ -41,7 +41,7 @@ export default async function loadModel(next) {
4141

4242
const model = fs.readFileSync(path.join(modelPath, file));
4343

44-
/* Read the model JSON into the structure */
44+
/* Read the model JSON into the schema */
4545
try {
4646
/* Attempt to parse the JSON */
4747
const parsedModel = JSON.parse(model.toString());
@@ -63,21 +63,14 @@ export default async function loadModel(next) {
6363
}
6464

6565
/* Save */
66-
structure[table] = parsedModel;
66+
schema[table] = parsedModel;
6767
} catch {
6868
throw new SaplingError(`Error parsing model \`${table}\``);
6969
}
7070
}
7171

72-
this.structure = structure;
73-
7472
/* Create a storage instance based on the models */
75-
this.storage = new Storage(this, {
76-
name: this.name,
77-
schema: this.structure,
78-
config: this.config,
79-
dir: this.dir,
80-
});
73+
this.storage = new Storage(this, schema);
8174

8275
if (next) {
8376
next();

lib/Storage.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,12 @@ export default class Storage {
6262
* Initialise the Storage class
6363
*
6464
* @param {object} App The App instance
65-
* @param {object} opts Initialisation options
65+
* @param {object} schema Data structure
6666
*/
67-
constructor(App, options) {
67+
constructor(App, schema) {
6868
/* Load the options into the class */
6969
this.app = App;
70-
this.options = options;
71-
this.name = options.name;
72-
this.schema = options.schema;
73-
this.config = options.config;
74-
this.dir = options.dir;
70+
this.schema = schema || {};
7571

7672
/* Every app with storage needs a users collection */
7773
if ('users' in this.schema) {
@@ -98,7 +94,7 @@ export default class Storage {
9894
async importDriver() {
9995
if (this.db === null) {
10096
/* Connect to the database backend with the desired driver */
101-
const driver = String(this.config.db.driver).toLowerCase();
97+
const driver = String(this.app.config.db.driver).toLowerCase();
10298

10399
if (driver === 'memory') {
104100
/* eslint-disable-next-line new-cap */
@@ -128,9 +124,9 @@ export default class Storage {
128124
async createDatabase() {
129125
await this.importDriver();
130126

131-
const dbConfig = this.config.db;
132-
dbConfig.name = this.name;
133-
dbConfig.dataLimit = this.config.dataLimit;
127+
const dbConfig = this.app.config.db;
128+
dbConfig.name = this.app.name || 'app';
129+
dbConfig.dataLimit = this.app.config.dataLimit;
134130

135131
await this.db.connect(dbConfig);
136132

@@ -232,7 +228,7 @@ export default class Storage {
232228
this.app.user.isUserAuthenticatedForRoute(request, response);
233229

234230
/* Parse max limit */
235-
const limit = (this.config.limit && this.config.limit > 0) ? this.config.limit : false;
231+
const limit = (this.app.config.limit && this.app.config.limit > 0) ? this.app.config.limit : false;
236232

237233
/* Parse limit options */
238234
if ('limit' in request.query) {

test/_utils/app.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ export default () => {
1010
render: {
1111
driver: 'html'
1212
},
13+
db: {
14+
driver: 'Memory'
15+
},
1316
hooksDir: 'hooks/',
1417
viewsDir: 'views/',
1518
extension: 'html'
@@ -26,7 +29,8 @@ export default () => {
2629
get: [],
2730
post: []
2831
},
29-
hooks: {}
32+
hooks: {},
33+
schema: {}
3034
};
3135

3236
app.utils = new Utils(app);

test/core/loadCustomTags.test.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import test from 'ava';
22
import _ from 'underscore';
3-
import path from 'path';
4-
import { fileURLToPath } from 'url';
53

64
import Request from '../../lib/Request.js';
75
import Storage from '../../lib/Storage.js';
@@ -10,9 +8,6 @@ import User from '../../lib/User.js';
108
import loadCustomTags from '../../core/loadCustomTags.js';
119

1210

13-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
14-
15-
1611
test.beforeEach(async t => {
1712
t.context.app = (await import('../_utils/app.js')).default();
1813

@@ -25,12 +20,8 @@ test.beforeEach(async t => {
2520
t.context.app.user = new User(t.context.app);
2621
t.context.app.request = new Request(t.context.app);
2722

28-
t.context.app.storage = new Storage(t.context.app, {
29-
name: 'test',
30-
schema: {},
31-
config: { db: { driver: 'Memory' } },
32-
dir: __dirname
33-
});
23+
t.context.app.name = 'test';
24+
t.context.app.storage = new Storage(t.context.app);
3425
await t.context.app.storage.importDriver();
3526
});
3627

test/core/loadModel.test.js

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ test('loads string based model definition', async t => {
2626
await loadModel.call(t.context.app);
2727
});
2828

29-
t.true('posts' in t.context.app.structure);
30-
t.true('title' in t.context.app.structure.posts);
31-
t.true('viewCount' in t.context.app.structure.posts);
32-
t.true(_.isObject(t.context.app.structure.posts.title));
33-
t.true(_.isObject(t.context.app.structure.posts.viewCount));
34-
t.is(t.context.app.structure.posts.title.type, 'string');
35-
t.is(t.context.app.structure.posts.viewCount.type, 'number');
29+
t.true('posts' in t.context.app.storage.schema);
30+
t.true('title' in t.context.app.storage.schema.posts);
31+
t.true('viewCount' in t.context.app.storage.schema.posts);
32+
t.true(_.isObject(t.context.app.storage.schema.posts.title));
33+
t.true(_.isObject(t.context.app.storage.schema.posts.viewCount));
34+
t.is(t.context.app.storage.schema.posts.title.type, 'string');
35+
t.is(t.context.app.storage.schema.posts.viewCount.type, 'number');
3636
});
3737

3838
test('loads object based model definition', async t => {
@@ -42,16 +42,16 @@ test('loads object based model definition', async t => {
4242
await loadModel.call(t.context.app);
4343
});
4444

45-
t.true('posts' in t.context.app.structure);
46-
t.true('title' in t.context.app.structure.posts);
47-
t.true('viewCount' in t.context.app.structure.posts);
48-
t.true(_.isObject(t.context.app.structure.posts.title));
49-
t.true(_.isObject(t.context.app.structure.posts.viewCount));
50-
t.is(t.context.app.structure.posts.title.type, 'string');
51-
t.is(t.context.app.structure.posts.title.required, true);
52-
t.is(t.context.app.structure.posts.title.maxlen, 140);
53-
t.is(t.context.app.structure.posts.viewCount.type, 'number');
54-
t.is(t.context.app.structure.posts.viewCount.default, 0);
45+
t.true('posts' in t.context.app.storage.schema);
46+
t.true('title' in t.context.app.storage.schema.posts);
47+
t.true('viewCount' in t.context.app.storage.schema.posts);
48+
t.true(_.isObject(t.context.app.storage.schema.posts.title));
49+
t.true(_.isObject(t.context.app.storage.schema.posts.viewCount));
50+
t.is(t.context.app.storage.schema.posts.title.type, 'string');
51+
t.is(t.context.app.storage.schema.posts.title.required, true);
52+
t.is(t.context.app.storage.schema.posts.title.maxlen, 140);
53+
t.is(t.context.app.storage.schema.posts.viewCount.type, 'number');
54+
t.is(t.context.app.storage.schema.posts.viewCount.default, 0);
5555
});
5656

5757
test('normalises access object', async t => {
@@ -61,23 +61,23 @@ test('normalises access object', async t => {
6161
await loadModel.call(t.context.app);
6262
});
6363

64-
t.true('posts' in t.context.app.structure);
65-
t.true('title' in t.context.app.structure.posts);
66-
t.true('viewCount' in t.context.app.structure.posts);
67-
t.true('content' in t.context.app.structure.posts);
68-
t.true('access' in t.context.app.structure.posts.title);
69-
t.true('access' in t.context.app.structure.posts.viewCount);
70-
t.true('access' in t.context.app.structure.posts.content);
71-
t.true(_.isObject(t.context.app.structure.posts.title.access));
72-
t.true(_.isObject(t.context.app.structure.posts.viewCount.access));
73-
t.true(_.isObject(t.context.app.structure.posts.content.access));
74-
75-
t.is(t.context.app.structure.posts.title.access.r, 'anyone');
76-
t.is(t.context.app.structure.posts.title.access.w, 'owner');
77-
t.is(t.context.app.structure.posts.viewCount.access.r, 'anyone');
78-
t.is(t.context.app.structure.posts.viewCount.access.w, 'anyone');
79-
t.is(t.context.app.structure.posts.content.access.r, 'anyone');
80-
t.is(t.context.app.structure.posts.content.access.w, 'anyone');
64+
t.true('posts' in t.context.app.storage.schema);
65+
t.true('title' in t.context.app.storage.schema.posts);
66+
t.true('viewCount' in t.context.app.storage.schema.posts);
67+
t.true('content' in t.context.app.storage.schema.posts);
68+
t.true('access' in t.context.app.storage.schema.posts.title);
69+
t.true('access' in t.context.app.storage.schema.posts.viewCount);
70+
t.true('access' in t.context.app.storage.schema.posts.content);
71+
t.true(_.isObject(t.context.app.storage.schema.posts.title.access));
72+
t.true(_.isObject(t.context.app.storage.schema.posts.viewCount.access));
73+
t.true(_.isObject(t.context.app.storage.schema.posts.content.access));
74+
75+
t.is(t.context.app.storage.schema.posts.title.access.r, 'anyone');
76+
t.is(t.context.app.storage.schema.posts.title.access.w, 'owner');
77+
t.is(t.context.app.storage.schema.posts.viewCount.access.r, 'anyone');
78+
t.is(t.context.app.storage.schema.posts.viewCount.access.w, 'anyone');
79+
t.is(t.context.app.storage.schema.posts.content.access.r, 'anyone');
80+
t.is(t.context.app.storage.schema.posts.content.access.w, 'anyone');
8181
});
8282

8383
test('throws an error for a mangled model definition', async t => {
@@ -99,8 +99,8 @@ test('does not load dot files', async t => {
9999
await loadModel.call(t.context.app);
100100
});
101101

102-
t.is(Object.keys(t.context.app.structure).length, 1);
103-
t.false('dotfile' in t.context.app.structure);
102+
t.is(Object.keys(t.context.app.storage.schema).length, 1);
103+
t.false('dotfile' in t.context.app.storage.schema);
104104
});
105105

106106
test('warns about a non-existant model path', async t => {

test/core/loadPermissions.test.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,8 @@ test.beforeEach(async t => {
2626
t.context.app.user = new User(t.context.app);
2727
t.context.app.request = new Request(t.context.app);
2828

29-
t.context.app.storage = new Storage(t.context.app, {
30-
name: 'test',
31-
schema: {},
32-
config: { db: { driver: 'Memory' } },
33-
dir: __dirname
34-
});
29+
t.context.app.name = 'test';
30+
t.context.app.storage = new Storage(t.context.app);
3531
await t.context.app.storage.importDriver();
3632

3733
t.context.request = (await import('../_utils/request.js')).default();

test/core/loadRest.test.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import express from 'express';
44
import session from 'express-session';
55
import bodyParser from 'body-parser';
66
import request from 'supertest';
7-
import path from 'path';
8-
import { fileURLToPath } from 'url';
97

108
import Request from '../../lib/Request.js';
119
import Storage from '../../lib/Storage.js';
@@ -15,9 +13,6 @@ import runHook from '../../core/runHook.js';
1513
import loadRest from '../../core/loadRest.js';
1614

1715

18-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
19-
20-
2116
test.beforeEach(async t => {
2217
t.context.app = _.extend({
2318
name: 'test'
@@ -31,12 +26,8 @@ test.beforeEach(async t => {
3126
t.context.app.user = new User(t.context.app);
3227
t.context.app.request = new Request(t.context.app);
3328

34-
t.context.app.storage = new Storage(t.context.app, {
35-
name: 'test',
36-
schema: { posts: { title: { type: 'string' } } },
37-
config: { db: { driver: 'Memory' } },
38-
dir: __dirname
39-
});
29+
t.context.app.name = 'test';
30+
t.context.app.storage = new Storage(t.context.app, { posts: { title: { type: 'string' } } });
4031
await t.context.app.storage.importDriver();
4132

4233
t.context.app.runHook = runHook;

test/hooks/model/retrieve.test.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,12 @@ import Storage from '../../../lib/Storage.js';
1010
import retrieve from '../../../hooks/sapling/model/retrieve.js';
1111

1212

13-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
14-
15-
1613
test.beforeEach(async t => {
1714
t.context.app = _.defaults({
18-
storage: new Storage({}, {
15+
storage: new Storage({
1916
name: 'test',
2017
schema: {},
21-
config: { db: { driver: 'Memory' } },
22-
dir: __dirname
18+
config: { db: { driver: 'Memory' } }
2319
})
2420
}, (await import('../../_utils/app.js')).default());
2521
await t.context.app.storage.importDriver();

test/hooks/user/forgot.test.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import test from 'ava';
22
import _ from 'underscore';
3-
import path from 'path';
4-
import { fileURLToPath } from 'url';
53

64
import Request from '../../../lib/Request.js';
75
import Response from '../../../lib/Response.js';
@@ -12,9 +10,6 @@ import User from '../../../lib/User.js';
1210
import forgot from '../../../hooks/sapling/user/forgot.js';
1311

1412

15-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
16-
17-
1813
test.beforeEach(async t => {
1914
t.context.app = _.extend({
2015
name: 'untitled'
@@ -23,12 +18,8 @@ test.beforeEach(async t => {
2318
t.context.app.user = new User(t.context.app);
2419
t.context.app.request = new Request(t.context.app);
2520

26-
t.context.app.storage = new Storage(t.context.app, {
27-
name: 'test',
28-
schema: {},
29-
config: { db: { driver: 'Memory' } },
30-
dir: __dirname
31-
});
21+
t.context.app.name = 'test';
22+
t.context.app.storage = new Storage(t.context.app);
3223
await t.context.app.storage.importDriver();
3324

3425
t.context.request = (await import('../../_utils/request.js')).default();

test/hooks/user/logged.test.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import test from 'ava';
22
import _ from 'underscore';
3-
import path from 'path';
4-
import { fileURLToPath } from 'url';
53

64
import Request from '../../../lib/Request.js';
75
import Response from '../../../lib/Response.js';
@@ -11,21 +9,14 @@ import User from '../../../lib/User.js';
119
import logged from '../../../hooks/sapling/user/logged.js';
1210

1311

14-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
15-
16-
1712
test.beforeEach(async t => {
1813
t.context.app = (await import('../../_utils/app.js')).default();
1914

2015
t.context.app.user = new User(t.context.app);
2116
t.context.app.request = new Request(t.context.app);
2217

23-
t.context.app.storage = new Storage(t.context.app, {
24-
name: 'test',
25-
schema: {},
26-
config: { db: { driver: 'Memory' } },
27-
dir: __dirname
28-
});
18+
t.context.app.name = 'test';
19+
t.context.app.storage = new Storage(t.context.app);
2920
await t.context.app.storage.importDriver();
3021

3122
t.context.request = (await import('../../_utils/request.js')).default();

0 commit comments

Comments
 (0)