From a56a7b963acc31e22a47d6e6ee9bbd40abf52831 Mon Sep 17 00:00:00 2001 From: "Michael H. Arieli" Date: Fri, 9 Sep 2016 06:39:36 -0700 Subject: [PATCH] Add TrinaryType --- src/enum/type-name.js | 2 + src/type/trinary-type.js | 73 +++++++++++++++++++++++++++++++++ tests/type/trinary-type-test.js | 73 +++++++++++++++++++++++++++++++++ tests/type/type-test.js | 2 - 4 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 src/type/trinary-type.js create mode 100644 tests/type/trinary-type-test.js diff --git a/src/enum/type-name.js b/src/enum/type-name.js index 7633b08..962fff4 100644 --- a/src/enum/type-name.js +++ b/src/enum/type-name.js @@ -35,6 +35,7 @@ import SystemUtils from 'gdbots/common/util/system-utils'; * @method static TypeName TIME_UUID() * @method static TypeName TIMESTAMP() * @method static TypeName TINY_INT() + * @method static TypeName TRINARY() * @method static TypeName UUID() */ export default class TypeName extends SystemUtils.mixinClass(Enum) {} @@ -71,5 +72,6 @@ TypeName.initEnum({ TIME_UUID: 'time-uuid', TIMESTAMP: 'timestamp', TINY_INT: 'tiny-int', + TRINARY: 'trinary', UUID: 'uuid' }); diff --git a/src/type/trinary-type.js b/src/type/trinary-type.js new file mode 100644 index 0000000..7a9c9fd --- /dev/null +++ b/src/type/trinary-type.js @@ -0,0 +1,73 @@ +'use strict'; + +import SystemUtils from 'gdbots/common/util/system-utils'; +import AbstractIntType from 'gdbots/pbj/type/abstract-int-type'; + +/** + * @link https://en.wikipedia.org/wiki/Three-valued_logic + * 0 = unknown + * 1 = true + * 2 = false + */ +export default class TrinaryType extends SystemUtils.mixinClass(AbstractIntType) +{ + /** + * {@inheritdoc} + */ + guard(value, field) { + if ([0, 1, 2].indexOf(value) === -1) { + throw new Error('Field [' + field.getName() + '] value [' + value + '] is not a valid. Must be 0, 1, or 2.'); + } + } + + /** + * {@inheritdoc} + */ + encode(value, field, codec = null) { + let tmp = parseInt(value); + return isNaN(tmp) || !isFinite(tmp) ? 0 : tmp; + } + + /** + * {@inheritdoc} + */ + decode(value, field, codec = null) { + let tmp = parseInt(value); + return isNaN(tmp) || !isFinite(tmp) ? 0 : tmp; + } + + /** + * {@inheritdoc} + */ + getDefault() { + return 0; + } + + /** + * {@inheritdoc} + */ + isNumeric() { + return true; + } + + /** + * {@inheritdoc} + */ + getMin() { + return 0; + } + + /** + * {@inheritdoc} + */ + getMax() { + return 2; + } + + /** + * {@inheritdoc} + */ + allowedInSet() { + return false; + } +} diff --git a/tests/type/trinary-type-test.js b/tests/type/trinary-type-test.js new file mode 100644 index 0000000..cc661f4 --- /dev/null +++ b/tests/type/trinary-type-test.js @@ -0,0 +1,73 @@ +'use strict'; + +import TrinaryType from 'gdbots/pbj/type/trinary-type'; +import FieldBuilder from 'gdbots/pbj/field-builder'; + +describe('trinary-type-test', function() { + it('validate encoding', function(done) { + let field = FieldBuilder.create('trinary_unknown', TrinaryType.create()).build(); + let type = field.getType(); + + type.encode(0, field).should.eql(0); + type.encode(1, field).should.eql(1); + type.encode(2, field).should.eql(2); + + done(); + }); + + it('validate decoding', function(done) { + let field = FieldBuilder.create('trinary_unknown', TrinaryType.create()).build(); + let type = field.getType(); + + type.decode(null, field).should.eql(0); + type.decode(0, field).should.eql(0); + type.decode(1, field).should.eql(1); + type.decode(2, field).should.eql(2); + + type.decode('0', field).should.eql(0); + type.decode('1', field).should.eql(1); + type.decode('2', field).should.eql(2); + + done(); + }); + + it('validate values', function(done) { + let field = FieldBuilder.create('trinary_unknown', TrinaryType.create()).build(); + let type = field.getType(); + + type.guard(0, field); + type.guard(1, field); + type.guard(2, field); + + done(); + }); + + it('invalid values validation', function(done) { + let field = FieldBuilder.create('trinary_unknown', TrinaryType.create()).build(); + let type = field.getType(); + let thrown = false; + + let invalid = [ + 'a', + [], + 3, + -1, + false, + true, + ]; + + invalid.forEach(function(val) { + try { + type.guard(val, field); + } catch (e) { + thrown = true; + } + + if (false === thrown) { + console.log('TrinaryType field accepted invalid value [' + val + '].'); + } + }); + + done(); + }); +}); diff --git a/tests/type/type-test.js b/tests/type/type-test.js index e1910aa..4b249d1 100644 --- a/tests/type/type-test.js +++ b/tests/type/type-test.js @@ -50,8 +50,6 @@ describe('type-test', function() { thrown = true; } - thrown.should.eql(true); - if (false === thrown) { console.log('[' + TypeName.name + '] accepted more than [' + field.getType().getMaxBytes() + '] bytes.'); }