Move Change getters/setters to prototype

This commit is contained in:
Patrick Mooney 2015-10-31 09:37:58 -05:00
parent 5b8cbb755b
commit cefd6f484d
2 changed files with 111 additions and 85 deletions

View File

@ -6,95 +6,100 @@ var Attribute = require('./attribute');
var Protocol = require('./protocol'); var Protocol = require('./protocol');
///--- API ///--- API
function Change(options) { function Change(options) {
if (options) { if (options) {
if (typeof (options) !== 'object') assert.object(options);
throw new TypeError('options must be an object'); assert.optionalString(options.operation);
if (options.operation && typeof (options.operation) !== 'string')
throw new TypeError('options.operation must be a string');
} else { } else {
options = {}; options = {};
} }
var self = this;
this._modification = false; this._modification = false;
this.operation = options.operation || options.type || 'add';
this.__defineGetter__('operation', function () { this.modification = options.modification || {};
switch (self._operation) { }
Object.defineProperties(Change.prototype, {
operation: {
get: function getOperation() {
switch (this._operation) {
case 0x00: return 'add'; case 0x00: return 'add';
case 0x01: return 'delete'; case 0x01: return 'delete';
case 0x02: return 'replace'; case 0x02: return 'replace';
default: default:
throw new Error('0x' + self._operation.toString(16) + ' is invalid'); throw new Error('0x' + this._operation.toString(16) + ' is invalid');
} }
}); },
this.__defineSetter__('operation', function (val) { set: function setOperation(val) {
if (typeof (val) !== 'string') assert.string(val);
throw new TypeError('operation must be a string');
switch (val.toLowerCase()) { switch (val.toLowerCase()) {
case 'add': case 'add':
self._operation = 0x00; this._operation = 0x00;
break; break;
case 'delete': case 'delete':
self._operation = 0x01; this._operation = 0x01;
break; break;
case 'replace': case 'replace':
self._operation = 0x02; this._operation = 0x02;
break; break;
default: default:
throw new Error('Invalid operation type: 0x' + val.toString(16)); throw new Error('Invalid operation type: 0x' + val.toString(16));
} }
}); },
this.__defineGetter__('modification', function () { configurable: false
return self._modification; },
}); modification: {
this.__defineSetter__('modification', function (attr) { get: function getModification() {
if (Attribute.isAttribute(attr)) { return this._modification;
self._modification = attr; },
set: function setModification(val) {
if (Attribute.isAttribute(val)) {
this._modification = val;
return; return;
} }
// Does it have an attribute-like structure // Does it have an attribute-like structure
if (Object.keys(attr).length == 2 && if (Object.keys(val).length == 2 &&
typeof (attr.type) === 'string' && typeof (val.type) === 'string' &&
Array.isArray(attr.vals)) { Array.isArray(val.vals)) {
self._modification = new Attribute({ this._modification = new Attribute({
type: attr.type, type: val.type,
vals: attr.vals vals: val.vals
}); });
return; return;
} }
var keys = Object.keys(attr); var keys = Object.keys(val);
if (keys.length > 1) if (keys.length > 1) {
throw new Error('Only one attribute per Change allowed'); throw new Error('Only one attribute per Change allowed');
} else if (keys.length === 0) {
return;
}
keys.forEach(function (k) { var k = keys[0];
console.log(keys);
var _attr = new Attribute({type: k}); var _attr = new Attribute({type: k});
if (Array.isArray(attr[k])) { if (Array.isArray(val[k])) {
attr[k].forEach(function (v) { val[k].forEach(function (v) {
_attr.addValue(v.toString()); _attr.addValue(v.toString());
}); });
} else { } else {
_attr.addValue(attr[k].toString()); _attr.addValue(val[k].toString());
} }
self._modification = _attr; this._modification = _attr;
}); },
}); configurable: false
this.__defineGetter__('json', function () { },
json: {
get: function getJSON() {
return { return {
operation: self.operation, operation: this.operation,
modification: self._modification ? self._modification.json : {} modification: this._modification ? this._modification.json : {}
}; };
}); },
configurable: false
this.operation = options.operation || options.type || 'add'; }
this.modification = options.modification || {}; });
}
module.exports = Change;
Change.isChange = function isChange(change) { Change.isChange = function isChange(change) {
if (!change || typeof (change) !== 'object') { if (!change || typeof (change) !== 'object') {
@ -206,3 +211,8 @@ Change.prototype.toBer = function (ber) {
return ber; return ber;
}; };
///--- Exports
module.exports = Change;

View File

@ -32,7 +32,7 @@ test('new no args', function (t) {
test('new with args', function (t) { test('new with args', function (t) {
var change = new Change({ var change = new Change({
operation: 0x00, operation: 'add',
modification: new Attribute({ modification: new Attribute({
type: 'cn', type: 'cn',
vals: ['foo', 'bar'] vals: ['foo', 'bar']
@ -50,19 +50,35 @@ test('new with args', function (t) {
}); });
test('validate fields', function (t) {
var c = new Change();
t.ok(c);
t.throws(function () {
c.operation = 'bogus';
});
t.throws(function () {
c.modification = {too: 'many', fields: 'here'};
});
c.modification = {
foo: ['bar', 'baz']
};
t.ok(c.modification);
t.end();
});
test('GH-31 (multiple attributes per Change)', function (t) { test('GH-31 (multiple attributes per Change)', function (t) {
try { t.throws(function () {
t.notOk(new Change({ var c = new Change({
operation: 'replace', operation: 'replace',
modification: { modification: {
cn: 'foo', cn: 'foo',
sn: 'bar' sn: 'bar'
} }
}), 'should have thrown'); });
} catch (e) { t.notOk(c);
t.ok(e); });
t.end(); t.end();
}
}); });