From d1cd19205808fe8effb2bbc4bc1f3c39ed1fe83a Mon Sep 17 00:00:00 2001
From: Andrii Shumada <eagleeyes91@gmail.com>
Date: Mon, 14 Jul 2014 19:08:22 +0300
Subject: [PATCH] v.1.6.0 Switch validator to 'jsonschema' with new v4 features

---
 package.json                           | 21 +++++----
 source/util/schemaFactory.js           |  4 +-
 test/common.js                         |  1 +
 test/exampleSchemas/index.js           | 31 +++++++++++++
 test/integration/schemaFactory.spec.js | 63 ++++++++++++++++++++++++--
 5 files changed, 104 insertions(+), 16 deletions(-)

diff --git a/package.json b/package.json
index 863e57a..7fa45a2 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "E-conomic",
   "name": "schemagic",
   "description": "JSON validation with schemas, and schema tools",
-  "version": "1.5.8",
+  "version": "1.6.0",
   "repository": {
     "type": "git",
     "url": "https://github.com/e-conomic/schemagic"
@@ -14,24 +14,25 @@
     "npm": ">=1.1.9"
   },
   "dependencies": {
-    "json-schema": "git+ssh://git@github.com/e-conomic/json-schema.git",
-    "underscore": "",
+    "async": "",
+    "jsonschema": "^0.4.0",
+    "lodash": "",
     "moment": "",
     "traverse": "",
-    "async": "",
-    "lodash": ""
+    "underscore": ""
   },
   "scripts": {
     "test": "node ./bin/runTests.js"
   },
   "devDependencies": {
-    "mocha": "",
     "chai": "",
-    "sinon": "",
-    "sinon-chai": "",
-    "jshint": ">=2.3.0",
+    "chai-subset": "^0.1.2",
     "injectr": "",
+    "jshint": ">=2.3.0",
+    "jshint-teamcity-reporter": "",
+    "mocha": "",
     "mocha-teamcity-reporter": "",
-    "jshint-teamcity-reporter": ""
+    "sinon": "",
+    "sinon-chai": ""
   }
 }
diff --git a/source/util/schemaFactory.js b/source/util/schemaFactory.js
index a2237b6..bd6502e 100644
--- a/source/util/schemaFactory.js
+++ b/source/util/schemaFactory.js
@@ -1,4 +1,3 @@
-var jsonSchema = require("json-schema");
 var util = require('util');
 var readOnlyDocumentPrunerFactory = require("./readOnlyDocumentPruner");
 var maxDecimalHandlerFactory = require("./maxDecimalHandler");
@@ -7,6 +6,7 @@ var foreignKeyValidationFactory = require("./foreignKeyValidationFactory");
 var exampleJson = require("./exampleJson");
 var emptyFieldsPrumer = require("./emptyFieldsPrumer");
 var emptyStringsToNullFactory = require("./emptyStringsToNullFactory");
+var _validate = require('jsonschema').validate;
 
 function schemaFactory(rawSchema, foreignKeys) {
 
@@ -35,7 +35,7 @@ function schemaFactory(rawSchema, foreignKeys) {
 			errors = errors.concat(stringFormatValidator(document).errors);
 		}
 
-		errors = errors.concat(jsonSchema._validate(document, rawSchema, options).errors);
+		errors = errors.concat(_validate(document, rawSchema, options).errors);
 		var doForeignKeyValidation = options && options.foreignKey === true;
 		if (errors.length === 0 && doForeignKeyValidation && foreignKeys) {
 			if (!optionalCallback) {
diff --git a/test/common.js b/test/common.js
index 21fc28c..adf3000 100644
--- a/test/common.js
+++ b/test/common.js
@@ -4,3 +4,4 @@ chai.config.includeStack;
 global.chai = chai;
 global.expect = chai.expect;
 chai.use(require('sinon-chai'));
+require('chai-subset').addMethods(chai);
diff --git a/test/exampleSchemas/index.js b/test/exampleSchemas/index.js
index 03d7d31..9c093d6 100644
--- a/test/exampleSchemas/index.js
+++ b/test/exampleSchemas/index.js
@@ -593,5 +593,36 @@ module.exports = {
 				"required":false
 			}
 		}
+	},
+	
+	oneOfSchema: {
+		description: "Simple object with 2 possible subdocuments",
+		required: true,
+		type: "object",
+		properties: {
+			a: {
+				type: "object",
+				oneOf: [
+					{
+						type: 'object',
+						properties: {
+							b: {
+								type: "string",
+								required: true
+							}
+						}
+					}
+					, {
+						type: 'object',
+						properties: {
+							c: {
+								type: "string",
+								required: true
+							}
+						}
+					}
+				]
+			}
+		}
 	}
 };
diff --git a/test/integration/schemaFactory.spec.js b/test/integration/schemaFactory.spec.js
index 6b9ab87..59e97e5 100644
--- a/test/integration/schemaFactory.spec.js
+++ b/test/integration/schemaFactory.spec.js
@@ -115,10 +115,10 @@ describe("/source/util/schemaFactory run on simpleSchema, the returned object",
 		});
 
 		it("will have the correct error", function () {
-			expect(result.errors).to.eql([
+			expect(result.errors).to.containSubset([
 				{
-					"property":"a",
-					"message":"string value found, but a number is required"
+					"property": "instance.a",
+					"message": "is not of a type(s) number"
 				}
 			]
 			);
@@ -256,7 +256,7 @@ describe("/source/util/schemaFactory run on simpleSchema, the returned object",
 		});
 
 		it('should not validate the document', function () {
-			expect(result).to.have.deep.property('errors.0.message', 'Array value found, but a object is required');
+			expect(result).to.have.deep.property('errors.0.message', "is not of a type(s) object");
 		});
 	});
 
@@ -323,4 +323,59 @@ describe("/source/util/schemaFactory run on simpleSchema, the returned object",
 			});
 		});
 	});
+
+	describe('test v4 features', function() {
+		before(function() {
+			schema = schemaFactory(rawSchemas.oneOfSchema);
+		});
+
+		describe('test valid document', function() {
+			var result;
+
+			var document = {
+				a: {b: 'yess'}
+			};
+
+			before(function () {
+				result = schema.validate(document);
+			});
+
+			it('should validate with no erros', function() {
+				expect(result).to.have.property("valid", true);
+			});
+		});
+
+		describe('test 1st invalid document', function() {
+			var result;
+
+			var document = {
+				a: {}
+			};
+
+			before(function () {
+				result = schema.validate(document);
+			});
+
+			it('should validate with no erros', function() {
+				expect(result).to.have.property("valid", false);
+			});
+		});
+
+		describe('test 2nd invalid document', function() {
+			var result;
+
+			var document = {
+				a: {b: 'yess', c: 'de'}
+			};
+
+			before(function () {
+				result = schema.validate(document);
+			});
+
+			it('should validate with no erros', function() {
+				expect(result).to.have.property("valid", false);
+			});
+		});
+
+	});
 });
\ No newline at end of file