diff --git a/dist/lib/ModelHelpers.js b/dist/lib/ModelHelpers.js index 7b9fa13..80d328a 100644 --- a/dist/lib/ModelHelpers.js +++ b/dist/lib/ModelHelpers.js @@ -1,3 +1,4 @@ +var MongoDB = require('mongodb'); var Skmatc = require('skmatc'); var Omnom_1 = require('./utils/Omnom'); var _ = require('lodash'); @@ -108,7 +109,13 @@ var ModelHelpers = (function () { ModelHelpers.prototype.cloneDocument = function (original) { return _.cloneDeep(original, function (value) { if (Buffer.isBuffer(value)) { - return value.slice(); + return value; + } + if (value instanceof MongoDB.Binary) { + return value; + } + if (value instanceof MongoDB.ObjectID) { + return value; } }); }; diff --git a/dist/lib/ModelHelpers.js.map b/dist/lib/ModelHelpers.js.map index e7af5ad..cfdd160 100644 --- a/dist/lib/ModelHelpers.js.map +++ b/dist/lib/ModelHelpers.js.map @@ -1 +1 @@ -{"version":3,"sources":["lib/ModelHelpers.ts"],"names":["ModelHelpers","ModelHelpers.constructor","ModelHelpers.validate","ModelHelpers.wrapDocument","ModelHelpers.transformToDB","ModelHelpers.transformFromDB","ModelHelpers.convertToDB","ModelHelpers.diff","ModelHelpers.cloneDocument","ModelHelpers.cloneConditions"],"mappings":"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","file":"lib/ModelHelpers.js","sourcesContent":["import MongoDB = require('mongodb');\r\nimport {Model} from './Model';\r\nimport Skmatc = require('skmatc');\r\nimport {Omnom} from './utils/Omnom';\r\nimport _ = require('lodash');\r\nimport Bluebird = require('bluebird');\r\n\r\n/**\r\n * A number of helper methods used commonly within Iridium, they provide a means to transform,\r\n * validate, wrap and diff instances and documents. By keeping these methods in one place we\r\n * help to improve testability and reduce code duplication (mouse abuse) throughout the codebase.\r\n * @internal\r\n */\r\nexport class ModelHelpers {\r\n constructor(public model: Model) {\r\n this._validator = Skmatc.scope(model.schema);\r\n model.validators.forEach(validator => this._validator.register(validator));\r\n }\r\n\r\n private _validator: Skmatc.Skmatc;\r\n\r\n /**\r\n * Validates a document to ensure that it matches the model's ISchema requirements\r\n * @param {any} document The document to validate against the ISchema\r\n * @returns {SkmatcCore.IResult} The result of the validation\r\n */\r\n validate(document: TDocument): Skmatc.Result {\r\n return this._validator.validate(document);\r\n }\r\n\r\n /**\r\n * Wraps the given document in an instance wrapper for use throughout the application\r\n * @param {any} document The document to be wrapped as an instance\r\n * @param {Boolean} isNew Whether the instance originated from the database or was created by the application\r\n * @param {Boolean} isPartial Whether the document supplied contains all information present in the database\r\n * @returns {any} An instance which wraps this document\r\n */\r\n wrapDocument(document: TDocument, isNew?: boolean, isPartial?: boolean): TInstance {\r\n return new this.model.Instance(document, isNew, isPartial);\r\n }\r\n\r\n /**\r\n * Converts the given document to its database form into a form\r\n * using the transforms defined on the model.\r\n * @param {any} document The document to be converted\r\n * @returns {any} The result of having transformed the document.\r\n * @remarks This is only really called from insert/create - as \r\n */\r\n transformToDB(document: T, options: TransformOptions = { properties: true }): T {\r\n if(options.document && this.model.transforms.$document)\r\n document = this.model.transforms.$document.toDB(document, '$document', this.model);\r\n \r\n if(!options.properties) return document;\r\n \r\n for (var property in this.model.transforms)\r\n if(property === '$document') continue;\r\n else if(document.hasOwnProperty(property)) {\r\n document[property] = this.model.transforms[property].toDB(document[property], property, this.model);\r\n }\r\n \r\n return document;\r\n }\r\n \r\n /**\r\n * Converts the given document from its database form using the\r\n * transforms defined on the model.\r\n * @param document The document to be converted.\r\n * @returns The result of having transformed the document.\r\n * @remarks Unlike the transformToDB function - this method only applies\r\n * document level transforms, as property level transforms are applied in\r\n * their relevant instance setters.\r\n */\r\n transformFromDB(document: TDocument, options: TransformOptions = { properties: true }): TDocument {\r\n if(options.document && this.model.transforms.$document)\r\n document = this.model.transforms.$document.fromDB(document, '$document', this.model);\r\n \r\n if(!options.properties) return document;\r\n \r\n for (var property in this.model.transforms)\r\n if(property === '$document') continue;\r\n else if(document.hasOwnProperty(property)) {\r\n document[property] = this.model.transforms[property].fromDB(document[property], property, this.model);\r\n }\r\n \r\n return document;\r\n }\r\n\r\n /**\r\n * Converts the given document to its database form into a form\r\n * using the transforms defined on the model.\r\n * @param document The document to be converted\r\n * @param processProperties Whether or not to process properties in addition\r\n * document level transforms.\r\n * @returns {any} A new document cloned from the original and transformed\r\n */\r\n convertToDB(document: T, options: TransformOptions = { properties: true }): T {\r\n var doc: T = this.cloneDocument(document);\r\n return this.transformToDB(doc, options);\r\n }\r\n\r\n /**\r\n * Performs a diff operation between two documents and creates a MongoDB changes object to represent the differences\r\n * @param {any} original The original document prior to changes being made\r\n * @param {any} modified The document after changes were made\r\n */\r\n diff(original: TDocument, modified: TDocument): any {\r\n var omnom = new Omnom();\r\n omnom.diff(original, modified);\r\n return omnom.changes;\r\n }\r\n \r\n /**\r\n * Clones the given document recursively, taking into account complex types like\r\n * Buffers correctly.\r\n * \r\n * @param {any} The document you wish to clone deeply.\r\n */\r\n cloneDocument(original: T): T {\r\n return _.cloneDeep(original, (value) => {\r\n if(Buffer.isBuffer(value)) {\r\n return (value).slice();\r\n }\r\n });\r\n }\r\n \r\n /**\r\n * Clones the given document recursively, taking into account complex types like\r\n * Buffers correctly. Optimized for working with query documents instead of true\r\n * documents.\r\n * \r\n * @param {any} The document you wish to clone deeply.\r\n */\r\n cloneConditions(original: T): T {\r\n return this.cloneDocument(original);\r\n }\r\n}\r\n\r\nexport interface TransformOptions {\r\n properties?: boolean;\r\n document?: boolean;\r\n}"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["lib/ModelHelpers.ts"],"names":["ModelHelpers","ModelHelpers.constructor","ModelHelpers.validate","ModelHelpers.wrapDocument","ModelHelpers.transformToDB","ModelHelpers.transformFromDB","ModelHelpers.convertToDB","ModelHelpers.diff","ModelHelpers.cloneDocument","ModelHelpers.cloneConditions"],"mappings":"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","file":"lib/ModelHelpers.js","sourcesContent":["import MongoDB = require('mongodb');\r\nimport {Model} from './Model';\r\nimport Skmatc = require('skmatc');\r\nimport {Omnom} from './utils/Omnom';\r\nimport _ = require('lodash');\r\nimport Bluebird = require('bluebird');\r\n\r\n/**\r\n * A number of helper methods used commonly within Iridium, they provide a means to transform,\r\n * validate, wrap and diff instances and documents. By keeping these methods in one place we\r\n * help to improve testability and reduce code duplication (mouse abuse) throughout the codebase.\r\n * @internal\r\n */\r\nexport class ModelHelpers {\r\n constructor(public model: Model) {\r\n this._validator = Skmatc.scope(model.schema);\r\n model.validators.forEach(validator => this._validator.register(validator));\r\n }\r\n\r\n private _validator: Skmatc.Skmatc;\r\n\r\n /**\r\n * Validates a document to ensure that it matches the model's ISchema requirements\r\n * @param {any} document The document to validate against the ISchema\r\n * @returns {SkmatcCore.IResult} The result of the validation\r\n */\r\n validate(document: TDocument): Skmatc.Result {\r\n return this._validator.validate(document);\r\n }\r\n\r\n /**\r\n * Wraps the given document in an instance wrapper for use throughout the application\r\n * @param {any} document The document to be wrapped as an instance\r\n * @param {Boolean} isNew Whether the instance originated from the database or was created by the application\r\n * @param {Boolean} isPartial Whether the document supplied contains all information present in the database\r\n * @returns {any} An instance which wraps this document\r\n */\r\n wrapDocument(document: TDocument, isNew?: boolean, isPartial?: boolean): TInstance {\r\n return new this.model.Instance(document, isNew, isPartial);\r\n }\r\n\r\n /**\r\n * Converts the given document to its database form into a form\r\n * using the transforms defined on the model.\r\n * @param {any} document The document to be converted\r\n * @returns {any} The result of having transformed the document.\r\n * @remarks This is only really called from insert/create - as \r\n */\r\n transformToDB(document: T, options: TransformOptions = { properties: true }): T {\r\n if(options.document && this.model.transforms.$document)\r\n document = this.model.transforms.$document.toDB(document, '$document', this.model);\r\n \r\n if(!options.properties) return document;\r\n \r\n for (var property in this.model.transforms)\r\n if(property === '$document') continue;\r\n else if(document.hasOwnProperty(property)) {\r\n document[property] = this.model.transforms[property].toDB(document[property], property, this.model);\r\n }\r\n \r\n return document;\r\n }\r\n \r\n /**\r\n * Converts the given document from its database form using the\r\n * transforms defined on the model.\r\n * @param document The document to be converted.\r\n * @returns The result of having transformed the document.\r\n * @remarks Unlike the transformToDB function - this method only applies\r\n * document level transforms, as property level transforms are applied in\r\n * their relevant instance setters.\r\n */\r\n transformFromDB(document: TDocument, options: TransformOptions = { properties: true }): TDocument {\r\n if(options.document && this.model.transforms.$document)\r\n document = this.model.transforms.$document.fromDB(document, '$document', this.model);\r\n \r\n if(!options.properties) return document;\r\n \r\n for (var property in this.model.transforms)\r\n if(property === '$document') continue;\r\n else if(document.hasOwnProperty(property)) {\r\n document[property] = this.model.transforms[property].fromDB(document[property], property, this.model);\r\n }\r\n \r\n return document;\r\n }\r\n\r\n /**\r\n * Converts the given document to its database form into a form\r\n * using the transforms defined on the model.\r\n * @param document The document to be converted\r\n * @param processProperties Whether or not to process properties in addition\r\n * document level transforms.\r\n * @returns {any} A new document cloned from the original and transformed\r\n */\r\n convertToDB(document: T, options: TransformOptions = { properties: true }): T {\r\n var doc: T = this.cloneDocument(document);\r\n return this.transformToDB(doc, options);\r\n }\r\n\r\n /**\r\n * Performs a diff operation between two documents and creates a MongoDB changes object to represent the differences\r\n * @param {any} original The original document prior to changes being made\r\n * @param {any} modified The document after changes were made\r\n */\r\n diff(original: TDocument, modified: TDocument): any {\r\n var omnom = new Omnom();\r\n omnom.diff(original, modified);\r\n return omnom.changes;\r\n }\r\n \r\n /**\r\n * Clones the given document recursively, taking into account complex types like\r\n * Buffers correctly.\r\n * \r\n * @param {any} The document you wish to clone deeply.\r\n */\r\n cloneDocument(original: T): T {\r\n return _.cloneDeep(original, (value) => {\r\n if(Buffer.isBuffer(value)) {\r\n return value;\r\n }\r\n \r\n if(value instanceof MongoDB.Binary) {\r\n return value;\r\n }\r\n \r\n if(value instanceof MongoDB.ObjectID) {\r\n return value;\r\n }\r\n });\r\n }\r\n \r\n /**\r\n * Clones the given document recursively, taking into account complex types like\r\n * Buffers correctly. Optimized for working with query documents instead of true\r\n * documents.\r\n * \r\n * @param {any} The document you wish to clone deeply.\r\n */\r\n cloneConditions(original: T): T {\r\n return this.cloneDocument(original);\r\n }\r\n}\r\n\r\nexport interface TransformOptions {\r\n properties?: boolean;\r\n document?: boolean;\r\n}"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/lib/Transforms.js b/dist/lib/Transforms.js index 9582e77..073097e 100644 --- a/dist/lib/Transforms.js +++ b/dist/lib/Transforms.js @@ -1,14 +1,14 @@ var MongoDB = require('mongodb'); exports.DefaultTransforms = { ObjectID: { - fromDB: function (value) { return value && value._bsontype == 'ObjectID' ? new MongoDB.ObjectID(value.id).toHexString() : value; }, + fromDB: function (value) { return value instanceof MongoDB.ObjectID ? value.toHexString() : value; }, toDB: function (value) { return typeof value === 'string' ? new MongoDB.ObjectID(value) : value; } }, Binary: { fromDB: function (value) { if (!value) return null; - if (value._bsontype === "Binary") + if (value instanceof MongoDB.Binary) return value.buffer; return value; }, diff --git a/dist/lib/Transforms.js.map b/dist/lib/Transforms.js.map index 86231e5..215fd9b 100644 --- a/dist/lib/Transforms.js.map +++ b/dist/lib/Transforms.js.map @@ -1 +1 @@ -{"version":3,"sources":["lib/Transforms.ts"],"names":[],"mappings":"AAAA,IAAO,OAAO,WAAW,SAAS,CAAC,CAAC;AAqCvB,yBAAiB,GAAG;IAC/B,QAAQ,EAAuD;QAC/D,MAAM,EAAE,UAAA,KAAK,IAAI,OAAA,KAAK,IAAoB,KAAM,CAAC,SAAS,IAAI,UAAU,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAiB,KAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,EAA/H,CAA+H;QAChJ,IAAI,EAAE,UAAA,KAAK,IAAI,OAAA,OAAO,KAAK,KAAK,QAAQ,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,EAA/D,CAA+D;KAC9E;IACD,MAAM,EAAmD;QACxD,MAAM,EAAE,UAAA,KAAK;YACZ,EAAE,CAAA,CAAC,CAAC,KAAK,CAAC;gBAAC,MAAM,CAAC,IAAI,CAAC;YACvB,EAAE,CAAA,CAAe,KAAM,CAAC,SAAS,KAAK,QAAQ,CAAC;gBAC9C,MAAM,CAAe,KAAM,CAAC,MAAM,CAAC;YAEpC,MAAM,CAAC,KAAK,CAAC;QACd,CAAC;QACD,IAAI,EAAE,UAAA,KAAK;YACV,EAAE,CAAA,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5D,EAAE,CAAA,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC;QACb,CAAC;KACD;CACD,CAAA","file":"lib/Transforms.js","sourcesContent":["import MongoDB = require('mongodb');\r\nimport {Model} from './Model';\r\nimport * as BSON from './BSON'; \r\n\r\nexport interface Transforms {\r\n\t/**\r\n\t * A transform which is applied to the entire document.\r\n\t */\r\n\t$document?: PropertyTransform;\r\n\t[property:string]: PropertyTransform;\r\n}\r\n\r\n/**\r\n * Converts the value of a property to and from its database representation.\r\n */\r\nexport interface PropertyTransform {\r\n\t/**\r\n\t * Converts a property's value from its database representation into one\r\n\t * suitable for the application.\r\n\t * @param value The value stored in the MongoDB database document.\r\n\t * @param property The name of the document property to which this transform is being applied.\r\n\t * @param model The Iridium Model on which this transform is being applied\r\n\t * @returns A derived value which is more useful to the application.\r\n\t */\r\n\tfromDB(value: T, property: string, model: Model): any;\r\n\r\n\t/**\r\n\t * Converts a property's value into a representation more suitable for\r\n\t * the database.\r\n\t * @param value The value used by the application.\r\n\t * @param property The name of the document property to which this transform is being applied.\r\n\t * @param model The Iridium Model on which this transform is being applied\r\n\t * @returns The database optimized representation of the value.\r\n\t */\r\n\ttoDB(value: any, property: string, model: Model): T;\r\n}\r\n\r\nexport const DefaultTransforms = {\r\n \tObjectID: >{\r\n\t\tfromDB: value => value && (value)._bsontype == 'ObjectID' ? new MongoDB.ObjectID((value).id).toHexString() : value,\r\n\t\ttoDB: value => typeof value === 'string' ? new MongoDB.ObjectID(value) : value\r\n\t},\r\n\tBinary: >{\r\n\t\tfromDB: value => {\r\n\t\t\tif(!value) return null;\r\n\t\t\tif((value)._bsontype === \"Binary\")\r\n\t\t\t\treturn (value).buffer;\r\n\t\t\t\r\n\t\t\treturn value;\r\n\t\t},\r\n\t\ttoDB: value => {\r\n\t\t\tif(Buffer.isBuffer(value)) return new MongoDB.Binary(value);\r\n\t\t\tif(Array.isArray(value)) return new MongoDB.Binary(new Buffer(value));\r\n\t\t\treturn null;\r\n\t\t}\r\n\t}\r\n}"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["lib/Transforms.ts"],"names":[],"mappings":"AAAA,IAAO,OAAO,WAAW,SAAS,CAAC,CAAC;AAqCvB,yBAAiB,GAAG;IAC/B,QAAQ,EAAuC;QAC/C,MAAM,EAAE,UAAA,KAAK,IAAI,OAAA,KAAK,YAAY,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,WAAW,EAAE,GAAG,KAAK,EAA/D,CAA+D;QAChF,IAAI,EAAE,UAAA,KAAK,IAAI,OAAA,OAAO,KAAK,KAAK,QAAQ,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,EAA/D,CAA+D;KAC9E;IACD,MAAM,EAAqC;QAC1C,MAAM,EAAE,UAAA,KAAK;YACZ,EAAE,CAAA,CAAC,CAAC,KAAK,CAAC;gBAAC,MAAM,CAAC,IAAI,CAAC;YACvB,EAAE,CAAA,CAAC,KAAK,YAAY,OAAO,CAAC,MAAM,CAAC;gBAAC,MAAM,CAAO,KAAM,CAAC,MAAM,CAAC;YAE/D,MAAM,CAAC,KAAK,CAAC;QACd,CAAC;QACD,IAAI,EAAE,UAAA,KAAK;YACV,EAAE,CAAA,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5D,EAAE,CAAA,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC;QACb,CAAC;KACD;CACD,CAAA","file":"lib/Transforms.js","sourcesContent":["import MongoDB = require('mongodb');\r\nimport {Model} from './Model';\r\nimport * as BSON from './BSON'; \r\n\r\nexport interface Transforms {\r\n\t/**\r\n\t * A transform which is applied to the entire document.\r\n\t */\r\n\t$document?: PropertyTransform;\r\n\t[property:string]: PropertyTransform;\r\n}\r\n\r\n/**\r\n * Converts the value of a property to and from its database representation.\r\n */\r\nexport interface PropertyTransform {\r\n\t/**\r\n\t * Converts a property's value from its database representation into one\r\n\t * suitable for the application.\r\n\t * @param value The value stored in the MongoDB database document.\r\n\t * @param property The name of the document property to which this transform is being applied.\r\n\t * @param model The Iridium Model on which this transform is being applied\r\n\t * @returns A derived value which is more useful to the application.\r\n\t */\r\n\tfromDB(value: T, property: string, model: Model): any;\r\n\r\n\t/**\r\n\t * Converts a property's value into a representation more suitable for\r\n\t * the database.\r\n\t * @param value The value used by the application.\r\n\t * @param property The name of the document property to which this transform is being applied.\r\n\t * @param model The Iridium Model on which this transform is being applied\r\n\t * @returns The database optimized representation of the value.\r\n\t */\r\n\ttoDB(value: any, property: string, model: Model): T;\r\n}\r\n\r\nexport const DefaultTransforms = {\r\n \tObjectID: >{\r\n\t\tfromDB: value => value instanceof MongoDB.ObjectID ? value.toHexString() : value,\r\n\t\ttoDB: value => typeof value === 'string' ? new MongoDB.ObjectID(value) : value\r\n\t},\r\n\tBinary: >{\r\n\t\tfromDB: value => {\r\n\t\t\tif(!value) return null;\r\n\t\t\tif(value instanceof MongoDB.Binary) return (value).buffer;\r\n\t\t\t\r\n\t\t\treturn value;\r\n\t\t},\r\n\t\ttoDB: value => {\r\n\t\t\tif(Buffer.isBuffer(value)) return new MongoDB.Binary(value);\r\n\t\t\tif(Array.isArray(value)) return new MongoDB.Binary(new Buffer(value));\r\n\t\t\treturn null;\r\n\t\t}\r\n\t}\r\n}"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/lib/ModelHelpers.ts b/lib/ModelHelpers.ts index d308b0e..d6be515 100644 --- a/lib/ModelHelpers.ts +++ b/lib/ModelHelpers.ts @@ -118,7 +118,15 @@ export class ModelHelpers { cloneDocument(original: T): T { return _.cloneDeep(original, (value) => { if(Buffer.isBuffer(value)) { - return (value).slice(); + return value; + } + + if(value instanceof MongoDB.Binary) { + return value; + } + + if(value instanceof MongoDB.ObjectID) { + return value; } }); } diff --git a/lib/Transforms.ts b/lib/Transforms.ts index 3d60b7e..79386d1 100644 --- a/lib/Transforms.ts +++ b/lib/Transforms.ts @@ -36,15 +36,14 @@ export interface PropertyTransform { } export const DefaultTransforms = { - ObjectID: >{ - fromDB: value => value && (value)._bsontype == 'ObjectID' ? new MongoDB.ObjectID((value).id).toHexString() : value, + ObjectID: >{ + fromDB: value => value instanceof MongoDB.ObjectID ? value.toHexString() : value, toDB: value => typeof value === 'string' ? new MongoDB.ObjectID(value) : value }, - Binary: >{ + Binary: >{ fromDB: value => { if(!value) return null; - if((value)._bsontype === "Binary") - return (value).buffer; + if(value instanceof MongoDB.Binary) return (value).buffer; return value; }, diff --git a/test/Decorators.ts b/test/Decorators.ts index 6e5ec92..6a06b9e 100644 --- a/test/Decorators.ts +++ b/test/Decorators.ts @@ -122,7 +122,7 @@ describe("Decorators", () => { describe("the ObjectID transform", () => { it("should convert an ObjectID to a string", () => { - chai.expect(Test.transforms['_id'].fromDB({ _bsontype: 'ObjectID', id: 'aaaaaaaaaaaaaaaaaaaaaaaa' }, '_id', null)).to.eql('aaaaaaaaaaaaaaaaaaaaaaaa'); + chai.expect(Test.transforms['_id'].fromDB(Iridium.toObjectID('aaaaaaaaaaaaaaaaaaaaaaaa'), '_id', null)).to.eql('aaaaaaaaaaaaaaaaaaaaaaaa'); }); it("should convert a string to an ObjectID", () => { diff --git a/test/Transforms.ts b/test/Transforms.ts index 568dd26..192ff91 100644 --- a/test/Transforms.ts +++ b/test/Transforms.ts @@ -218,10 +218,7 @@ describe("Transforms", () => { describe("the default Buffer transform", () => { it("should convert a MongoDB BSON Binary object into a buffer", () => { let transform = DefaultTransforms.Binary.fromDB; - let result = transform({ - _bsontype: 'Binary', - buffer: new Buffer('test', 'utf8') - }, '_id', null); + let result = transform(new MongoDB.Binary(new Buffer('test', 'utf8')), '_id', null); chai.expect(result).to.exist; chai.expect(result.toString('utf8')).to.eql('test');