Commit a12ac40b656901d5dcfd3cf302343421e77045b0
Merge pull request #10 from ssbc/error-schemas
Error schemasPiet Geursen authored on 3/8/2018, 3:29:04 AM
GitHub committed on 3/8/2018, 3:29:04 AM
Parent: ac1a79fec1e45652d23a6905c8540851a850a868
Parent: db2104d584cf1698fa4167e05a3ff1a37cc9c5b5
Files changed
position/sync/chooseOneResults.js | ||
---|---|---|
@@ -1,6 +1,7 @@ | ||
1 | 1 | const isArray = require('isarray') |
2 | -const {ERROR_POSITION_CHOICE, ERROR_POSITION_TYPE, ERROR_POSITION_LATE} = require('../../types') | |
2 | +const PositionChoiceError = require('../../errors/sync/positionChoiceError') | |
3 | +const PositionLateError = require('../../errors/sync/positionLateError') | |
3 | 4 | |
4 | 5 | // Expects `poll` and `position` objects passed in to be of shape: |
5 | 6 | // { |
6 | 7 | // key, |
@@ -17,16 +18,14 @@ | ||
17 | 18 | const { author, content } = position.value |
18 | 19 | const { choice } = content.positionDetails |
19 | 20 | |
20 | 21 | if (isInvalidChoice({position, poll})) { |
21 | - // TODO change this to push errors into poll.errors | |
22 | - results.errors.push({type: ERROR_POSITION_CHOICE, position}) | |
22 | + results.errors.push(PositionChoiceError({position})) | |
23 | 23 | return results |
24 | 24 | } |
25 | 25 | |
26 | 26 | if (isPositionLate({position, poll})) { |
27 | - // TODO change this to push errors into poll.errors | |
28 | - results.errors.push({type: ERROR_POSITION_LATE, position}) | |
27 | + results.errors.push(PositionLateError({position})) | |
29 | 28 | return results |
30 | 29 | } |
31 | 30 | |
32 | 31 | // TODO convert from Array to Object |
test/errors/sync/index.test.js | ||
---|---|---|
@@ -1,0 +1,50 @@ | ||
1 | +const test = require('tape') | |
2 | + | |
3 | +const isPositionChoiceError = require('../../../errors/sync/isPositionChoiceError')() | |
4 | +const isPositionLateError = require('../../../errors/sync/isPositionLateError')() | |
5 | +const isPositionTypeError = require('../../../errors/sync/isPositionTypeError')() | |
6 | + | |
7 | +const PositionTypeError = require('../../../errors/sync/positionTypeError') | |
8 | +const PositionLateError = require('../../../errors/sync/positionLateError') | |
9 | +const PositionChoiceError = require('../../../errors/sync/positionChoiceError') | |
10 | + | |
11 | +const ChooseOne = require('../../../position/sync/chooseOne') | |
12 | + | |
13 | +test('positionTypeError', function (t) { | |
14 | + var validPosition = ChooseOne({ | |
15 | + poll: '%t+PhrNxxXkw/jMo6mnwUWfFjJapoPWxzsQoe0Np+nYw=.sha256', | |
16 | + choice: 0 | |
17 | + }) | |
18 | + var invalidError = PositionTypeError({}) | |
19 | + t.false(isPositionTypeError(invalidError), 'catches invalid error') | |
20 | + | |
21 | + var validError = PositionTypeError({position: validPosition}) | |
22 | + t.true(isPositionTypeError(validError), 'validates valid error') | |
23 | + t.end() | |
24 | +}) | |
25 | + | |
26 | +test('positionLateError', function (t) { | |
27 | + var validPosition = ChooseOne({ | |
28 | + poll: '%t+PhrNxxXkw/jMo6mnwUWfFjJapoPWxzsQoe0Np+nYw=.sha256', | |
29 | + choice: 0 | |
30 | + }) | |
31 | + var invalidError = PositionLateError({}) | |
32 | + t.false(isPositionTypeError(invalidError), 'catches invalid error') | |
33 | + | |
34 | + var validError = PositionLateError({position: validPosition}) | |
35 | + t.true(isPositionLateError(validError), 'validates valid error') | |
36 | + t.end() | |
37 | +}) | |
38 | + | |
39 | +test('positionChoiceError', function (t) { | |
40 | + var validPosition = ChooseOne({ | |
41 | + poll: '%t+PhrNxxXkw/jMo6mnwUWfFjJapoPWxzsQoe0Np+nYw=.sha256', | |
42 | + choice: 0 | |
43 | + }) | |
44 | + var invalidError = PositionChoiceError({}) | |
45 | + t.false(isPositionChoiceError(invalidError), 'catches invalid error') | |
46 | + | |
47 | + var validError = PositionChoiceError({position: validPosition}) | |
48 | + t.true(isPositionChoiceError(validError), 'validates valid error') | |
49 | + t.end() | |
50 | +}) |
types.js | ||
---|---|---|
@@ -1,9 +1,9 @@ | ||
1 | 1 | module.exports = { |
2 | 2 | CHOOSE_ONE: 'chooseOne', |
3 | 3 | ERROR_POSITION_TYPE: 'ERROR_POSITION_TYPE', |
4 | 4 | ERROR_POSITION_LATE: 'ERROR_POSITION_LATE', |
5 | - ERROR_POSTITION_CHOICE: 'ERROR_POSTITION_CHOICE' | |
5 | + ERROR_POSITION_CHOICE: 'ERROR_POSITION_CHOICE' | |
6 | 6 | } |
7 | 7 | |
8 | 8 | // Question: do these need to be different, could we just have 'chooseOne', |
9 | 9 | // because we already have: |
NOTES.md | ||
---|---|---|
@@ -1,0 +1,12 @@ | ||
1 | +# Notes | |
2 | + | |
3 | +## Open Questions | |
4 | + | |
5 | +- do we need schemas for internal types, eg Errors? | |
6 | +- how do we versioning well? | |
7 | + - do require in older versions and delegate to them somehow? | |
8 | + - sub folder with own package.json? | |
9 | +- ChooseOnePoll and ChooseOnePosition vs ChooseOne types in types.js | |
10 | + - With choose one, some of the code nicer. Trade off is perhaps collisions. | |
11 | +- also applies to PollDetails and PositionDetails types. They could just be details. | |
12 | +- should getters use backlinks or links2? |
errors/schema/positionChoiceError.js | ||
---|---|---|
@@ -1,0 +1,9 @@ | ||
1 | +const errorSchema = require('./positionError') | |
2 | +const cloneDeep = require('lodash.clonedeep') | |
3 | + | |
4 | +const schema = cloneDeep(errorSchema) | |
5 | + | |
6 | +// collapse the details down to be ONLY choice error | |
7 | +schema.properties.type = { $ref: '#/definitions/errorTypes/errorChoice' } | |
8 | + | |
9 | +module.exports = schema |
errors/schema/positionError.js | ||
---|---|---|
@@ -1,0 +1,39 @@ | ||
1 | +const { ERROR_POSITION_CHOICE, ERROR_POSITION_TYPE, ERROR_POSITION_LATE } = require('../../types') | |
2 | + | |
3 | +var schema = { | |
4 | + type: 'object', | |
5 | + required: ['type', 'position', 'message'], | |
6 | + properties: { | |
7 | + type: { | |
8 | + oneOf: [ | |
9 | + { $ref: '#/definitions/errorTypes/errorChoice' }, | |
10 | + { $ref: '#/definitions/errorTypes/errorTypes' }, | |
11 | + { $ref: '#/definitions/errorTypes/errorLate' } | |
12 | + ] | |
13 | + }, | |
14 | + position: { | |
15 | + type: 'object' | |
16 | + }, | |
17 | + message: { | |
18 | + type: 'string' | |
19 | + }, | |
20 | + definitions: { | |
21 | + errorTypes: { | |
22 | + errorChoice: { | |
23 | + type: 'string', | |
24 | + pattern: `^${ERROR_POSITION_CHOICE}$` | |
25 | + }, | |
26 | + errorType: { | |
27 | + type: 'string', | |
28 | + pattern: `^${ERROR_POSITION_TYPE}$` | |
29 | + }, | |
30 | + errorLate: { | |
31 | + type: 'string', | |
32 | + pattern: `^${ERROR_POSITION_LATE}$` | |
33 | + } | |
34 | + } | |
35 | + } | |
36 | + } | |
37 | +} | |
38 | + | |
39 | +module.exports = schema |
errors/schema/positionLateError.js | ||
---|---|---|
@@ -1,0 +1,9 @@ | ||
1 | +const errorSchema = require('./positionError') | |
2 | +const cloneDeep = require('lodash.clonedeep') | |
3 | + | |
4 | +const schema = cloneDeep(errorSchema) | |
5 | + | |
6 | +// collapse the details down to be ONLY late error | |
7 | +schema.properties.type = { $ref: '#/definitions/errorTypes/errorLate' } | |
8 | + | |
9 | +module.exports = schema |
errors/schema/positionTypeError.js | ||
---|---|---|
@@ -1,0 +1,9 @@ | ||
1 | +const errorSchema = require('./positionError') | |
2 | +const cloneDeep = require('lodash.clonedeep') | |
3 | + | |
4 | +const schema = cloneDeep(errorSchema) | |
5 | + | |
6 | +// collapse the details down to be ONLY type error | |
7 | +schema.properties.type = { $ref: '#/definitions/errorTypes/errorType' } | |
8 | + | |
9 | +module.exports = schema |
errors/sync/isPositionChoiceError.js | ||
---|---|---|
@@ -1,0 +1,15 @@ | ||
1 | +const Validator = require('is-my-json-valid') | |
2 | +const schema = require('../schema/positionChoiceError') | |
3 | +const validator = Validator(schema, {verbose: true}) | |
4 | + | |
5 | +// server is not used here. Closure pattern is just for consistency of use with other functions. | |
6 | +module.exports = function (server) { | |
7 | + return function isError (obj) { | |
8 | + const result = validator(obj) | |
9 | + | |
10 | + // exposes error messages provided by is-my-json-valid | |
11 | + isError.errors = validator.errors | |
12 | + | |
13 | + return result | |
14 | + } | |
15 | +} |
errors/sync/isPositionLateError.js | ||
---|---|---|
@@ -1,0 +1,15 @@ | ||
1 | +const Validator = require('is-my-json-valid') | |
2 | +const schema = require('../schema/positionLateError') | |
3 | +const validator = Validator(schema, {verbose: true}) | |
4 | + | |
5 | +// server is not used here. Closure pattern is just for consistency of use with other functions. | |
6 | +module.exports = function (server) { | |
7 | + return function isError (obj) { | |
8 | + const result = validator(obj) | |
9 | + | |
10 | + // exposes error messages provided by is-my-json-valid | |
11 | + isError.errors = validator.errors | |
12 | + | |
13 | + return result | |
14 | + } | |
15 | +} |
errors/sync/isPositionTypeError.js | ||
---|---|---|
@@ -1,0 +1,15 @@ | ||
1 | +const Validator = require('is-my-json-valid') | |
2 | +const schema = require('../schema/positionTypeError') | |
3 | +const validator = Validator(schema, {verbose: true}) | |
4 | + | |
5 | +// server is not used here. Closure pattern is just for consistency of use with other functions. | |
6 | +module.exports = function (server) { | |
7 | + return function isError (obj) { | |
8 | + const result = validator(obj) | |
9 | + | |
10 | + // exposes error messages provided by is-my-json-valid | |
11 | + isError.errors = validator.errors | |
12 | + | |
13 | + return result | |
14 | + } | |
15 | +} |
errors/sync/isPostionError.js | ||
---|---|---|
@@ -1,0 +1,15 @@ | ||
1 | +const Validator = require('is-my-json-valid') | |
2 | +const schema = require('../schema/postionError') | |
3 | +const validator = Validator(schema, {verbose: true}) | |
4 | + | |
5 | +// server is not used here. Closure pattern is just for consistency of use with other functions. | |
6 | +module.exports = function (server) { | |
7 | + return function isError (obj) { | |
8 | + const result = validator(obj) | |
9 | + | |
10 | + // exposes error messages provided by is-my-json-valid | |
11 | + isError.errors = validator.errors | |
12 | + | |
13 | + return result | |
14 | + } | |
15 | +} |
errors/sync/positionChoiceError.js | ||
---|---|---|
@@ -1,0 +1,6 @@ | ||
1 | +var { ERROR_POSITION_CHOICE } = require('../../types') | |
2 | +var Error = require('./positionError') | |
3 | + | |
4 | +module.exports = function ({position}) { | |
5 | + return Error({type: ERROR_POSITION_CHOICE, position, message: 'Postion choice was not a valid choice for the poll'}) | |
6 | +} |
errors/sync/positionError.js | ||
---|---|---|
@@ -1,0 +1,5 @@ | ||
1 | +module.exports = function PositionError ({type, position, message}) { | |
2 | + var error = {type, position, message} | |
3 | + | |
4 | + return error | |
5 | +} |
errors/sync/positionLateError.js | ||
---|---|---|
@@ -1,0 +1,6 @@ | ||
1 | +var { ERROR_POSITION_LATE } = require('../../types') | |
2 | +var Error = require('./positionError') | |
3 | + | |
4 | +module.exports = function ({position}) { | |
5 | + return Error({type: ERROR_POSITION_LATE, position, message: 'Postion stated after the poll closed'}) | |
6 | +} |
errors/sync/positionTypeError.js | ||
---|---|---|
@@ -1,0 +1,6 @@ | ||
1 | +var { ERROR_POSITION_TYPE } = require('../../types') | |
2 | +var Error = require('./positionError') | |
3 | + | |
4 | +module.exports = function ({position}) { | |
5 | + return Error({type: ERROR_POSITION_TYPE, position, message: 'Postion stated was the wrong type for this poll'}) | |
6 | +} |
Built with git-ssb-web