UNPKG

@wmfs/j2119

Version:

A general-purpose validator generator that uses RFC2119-style assertions as input.

217 lines (196 loc) 7.29 kB
/* eslint-env mocha */ const chai = require('chai') chai.use(require('dirty-chai')) const expect = chai.expect const roleConstraints = require('../lib/j2119/role_constraints') const allowedFields = require('../lib/j2119/allowed_fields') const lineMatcher = require('../lib/j2119/line_matcher') const roleFinder = require('../lib/j2119/role_finder') const assigner = require('../lib/j2119/assigner') describe('J2119 Assigner', () => { it('should attach a condition to a constraint', () => { const assertion = { role: 'R', modal: 'MUST', field_name: 'foo', excluded: 'an A, a B, or a C' } const roles = ['A', 'B', 'C'] const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('x') roles.forEach(role => matcher.addRole(role)) const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignConstraints(assertion) const retrieved = constraints.getConstraints('R') const c = retrieved[0] const json = { a: 1 } roles.forEach(role => expect(c.applies(json, [role])).to.be.false() ) expect(c.applies(json, ['foo'])).to.be.true() }) it('should handle a "non-zero ... less than" constraint properly', () => { const assertion = { role: 'R', modal: 'MAY', type: 'nonnegative-integer', field_name: 'MaxAttempts', relation: 'less than', target: '99999999' } const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('x') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignConstraints(assertion) const retrieved = constraints.getConstraints('R').map(r => r.toString()) expect(retrieved.length).to.eql(3) expect(retrieved).to.include('<Field MaxAttempts should be of type integer>') expect(retrieved).to.include('<Field MaxAttempts has constraints {"min":0}>') expect(retrieved).to.include('<Field MaxAttempts has constraints {"ceiling":99999999}>') }) it('should assign an only_one_of constraint properly', () => { const assertion = { role: 'R', field_list: '"foo", "bar", and "baz"' } const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('x') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignOnlyOneOf(assertion) const retrieved = constraints.getConstraints('R').map(r => r.toString()) expect(retrieved.length).to.eql(1) expect(retrieved[0]).to.eql('<Node can have one of ["foo","bar","baz"] fields>') }) it('should add a HasFieldConstraint if there\'s a MUST', () => { const assertion = { role: 'R', modal: 'MUST', field_name: 'foo' } const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('x') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignConstraints(assertion) const retrieved = constraints.getConstraints('R').map(r => r.toString()) expect(retrieved.length).to.eql(1) expect(retrieved[0]).to.eql('<Field foo should be present>') }) it('should add a DoesNotHaveFieldConstraint if there\'s a MUST NOT', () => { const assertion = { role: 'R', modal: 'MUST NOT', field_name: 'foo' } const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('x') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignConstraints(assertion) const retrieved = constraints.getConstraints('R').map(r => r.toString()) expect(retrieved.length).to.eql(1) expect(retrieved[0]).to.eql('<Field foo should be absent>') }) it('should manage a complex type constraint ', () => { const assertion = { role: 'R', modal: 'MUST', field_name: 'foo', type: 'nonnegative-float' } const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('x') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignConstraints(assertion) const retrieved = constraints.getConstraints('R').map(r => r.toString()) expect(retrieved.length).to.eql(3) expect(retrieved).to.include('<Field foo should be of type float>') expect(retrieved).to.include('<Field foo has constraints {"min":0}>') expect(retrieved).to.include('<Field foo should be present>') }) it('should record a relational constraint ', () => { const assertion = { role: 'R', modal: 'MUST', field_name: 'foo', type: 'nonnegative-float', relation: 'less than', target: '1000' } const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('x') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignConstraints(assertion) const retrieved = constraints.getConstraints('R').map(r => r.toString()) expect(retrieved.length).to.eql(4) expect(retrieved).to.include('<Field foo should be of type float>') expect(retrieved).to.include('<Field foo has constraints {"min":0}>') expect(retrieved).to.include('<Field foo has constraints {"ceiling":1000}>') expect(retrieved).to.include('<Field foo should be present>') }) it('should record an is_a role', () => { const assertion = { role: 'R', newrole: 'S' } const rf = roleFinder() const constraints = roleConstraints() const matcher = lineMatcher('x') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignRoles(assertion) const json = { a: 3 } const roles = ['R'] rf.findMoreRoles(json, roles) expect(roles).to.eql(['R', 'S']) }) it('should correctly assign a field value role', () => { const assertion = { role: 'R', fieldtomatch: 'f1', valtomatch: '33', newrole: 'S', val_match_present: true } const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('R') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignRoles(assertion) const json = { f1: 33 } const roles = ['R'] rf.findMoreRoles(json, roles) expect(roles).to.eql(['R', 'S']) }) it('should process a child role in an assertion', () => { const assertion = { role: 'R', modal: 'MUST', field_name: 'a', child_type: 'field', child_role: 'bar' } const constraints = roleConstraints() const rf = roleFinder() const matcher = lineMatcher('x') const permittedFields = allowedFields() const cut = assigner(constraints, rf, matcher, permittedFields) cut.assignConstraints(assertion) const roles = ['R'] const fieldRoles = rf.findGrandchildRoles(roles, 'a') expect(fieldRoles).to.eql(['bar']) }) })