Permalink
Browse files

Added JEFRi Divine JSON 0.1

  • Loading branch information...
1 parent 3d25f5c commit 38423f2c7d55770c6fae8ee2711f795c736fe250 @DavidSouther committed Apr 28, 2012
Showing with 152 additions and 1 deletion.
  1. +15 −1 js/core/test/context.js
  2. +4 −0 js/divine/build.sh
  3. +63 −0 js/divine/json.coffee
  4. +22 −0 js/divine/test/json.html
  5. +48 −0 js/divine/test/json.js
View
@@ -1,6 +1,20 @@
$(document).ready(function(){
-module("Entity Context");
+var testDone = (function(){
+ var tests = 3;
+ return function(){
+ test--;
+ if(test <= 0){
+
+ }
+ };
+});
+
+module("Entity Context", {
+ teardown: function(){
+ testDone();
+ }
+});
test("Unit Testing Environment", function () {
expect(1);
View
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+rm json.js
+coffee -p json.coffee >| json.js
View
@@ -0,0 +1,63 @@
+define = define || (module, required, fn) ->
+ # Utility to add a value to an object at a certain point in its tree.
+ path = (obj, path, val) ->
+ path = path.split('.')
+ field = path.pop()
+ piece = obj
+ for part in path
+ piece = piece[part] ?= {}
+ piece[field] = val
+
+ path(window, module, fn(_))
+
+define "JEFRi.Divine.JSON", ["Underscore"], (_) ->
+ # Given an object with keys, either attach keys as properties of the entities,
+ # or as a new entity and relationship
+ divineObject = (key, object, context) ->
+ entity = {name: key, key: '', properties: [], attributes: [], methods: []}
+ for field of object
+ property = {name: field, atributes:{}}
+ if _.isNumber(object[field])
+ property.type = "int"
+ else
+ property.type = "string"
+ entity.properties.push(property)
+ context.entities.push(entity)
+ context
+
+ # Simple counter.
+ next = (=>
+ i=0
+ => ++i
+ )()
+
+ # Has to verify two objects are similar. In this case, they're similar if they
+ # have the same keys.
+ hashObject = (object) ->
+ h = ""
+ keys = (->
+ for key of object
+ h += key)()
+ keys.join('');
+
+ # Verify that each thing in an array is similar
+ divineArray = (arr, context) ->
+ hash = hashObject(arr[0])
+ for obj in arr
+ if hash isnt hashObject(obj)
+ throw { object: arr[i], hash: hash, pos: i, message: "Object at #{i} does not match hash."}
+ divineObject("Field_" + next(), arr[0], context)
+
+ # Divine the structure of a JSON data source.
+ (json) ->
+ if _.isString(json)
+ json = window.JSON.parse(json)
+
+ sampleContext = {meta: {}, entities: []}
+
+ if _.isArray(json)
+ divineArray(json, sampleContext)
+ else if _.isObject(json)
+ for field of json
+ divineObject(field, json[field], sampleContext)
+ sampleContext
View
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="http://code.jquery.com/jquery-latest.js"></script>
+ <link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
+ <script type="text/javascript" src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
+ <script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
+ <script>JEFRi = {Divine:{}};</script>
+ <script type="text/javascript" src="../../core/uuid.js"></script>
+ <script type="text/javascript" src="../../core/EntityContext.js"></script>
+ <script type="text/javascript" src="../json.js"></script>
+ <script type="text/javascript" src="./json.js"></script>
+</head>
+<body>
+ <h1 id="qunit-header">JEFRi QUnit</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"></ol>
+ <div id="qunit-fixture"></div>
+</body>
+</html>
View
@@ -0,0 +1,48 @@
+$(document).ready(function(){
+
+var sample1 = '{"meta":{}, "entities":[{ "name": "User", "key": "user_id", "properties": [{ "name": "user_id", "type": "int", "attributes": {"primary": "true"}}, { "name": "name", "type": "string", "attributes": {}}, { "name": "address", "type": "string", "attributes": {"unique": "true"}}], "relationships": [{ "name": "authinfo", "type": "has_a", "to": {"type": "Authinfo", "property": "user_id", "vname": "user"}, "from": {"type": "User", "property": "user_id", "vname": "user"}}], "attributes": {"vname": "users", "svname": "user"}}, { "name": "Authinfo", "key": "authinfo_id", "properties": [{ "name": "authinfo_id", "type": "int", "attributes": {"primary": "true"}}, { "name": "user_id", "type": "int", "attributes": {}}, { "name": "username", "type": "string", "attributes": {"length": "45"}}, { "name": "password", "type": "string", "attributes": {"length": "45"}}, { "name": "activated", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "banned", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "ban_reason", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "new_password_key", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "new_password_requested", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "new_email", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "new_email_key", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "last_ip", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "last_login", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "created", "type": "string", "attributes": {"nullable": "true", "length": "45"}}, { "name": "modified", "type": "string", "attributes": {"nullable": "true", "length": "45"}}], "relationships": [{ "name": "user", "type": "has_a", "to": {"type": "User", "property": "user_id", "vname": "user"}, "from": {"type": "Authinfo", "property": "user_id", "vname": "user"}}], "attributes": {"vname": "authinfo", "svname": "authinfo"}}]}';
+
+var sample2 = '[{"hostname":"Plato","ip":"192.168.0.1","mac":"00:01"},{"hostname":"Kant","ip":"192.168.0.2","mac":"00:02"}]';
+
+module("Entity Context");
+
+test("Unit Testing Environment", function () {
+ expect(1);
+ ok( !isLocal, "Unit tests shouldn't be run from file://, especially in Chrome. If you must test from file:// with Chrome, run it with the --allow-file-access-from-files flag!" );
+});
+
+test("Basic requirements", function() {
+ expect(1);
+ ok( JEFRi.Divine.JSON, "JSON Parser is missing." );
+});
+
+test("Divine flat JSON", function(){
+ var context = JEFRi.Divine.JSON(sample2);
+ ok(context, "Loaded context.");
+ ok(context.meta, "Context has meta.");
+ ok(context.entities, "Context has entities.");
+ ok(context.entities.length === 1, "Found 1 entity");
+ var entity = context.entities[0];
+ ok(entity.name, "Entity got a name.");
+ ok(entity.properties.length === 3, "Entity has 3 properties.");
+ var property = entity.properties[0];
+ ok(property.name, "Property got a name.");
+ console.log(context, window.JSON.stringify(context));
+ var runtime = new JEFRi.EntityContext(null, {debug: {context:context}});
+ ok(runtime, "Successfully started with the generated context.");
+ ok(runtime._context.entities.Field_1.properties.hostname, "Runtime found context.");
+});
+
+test("Divine EntityContext Context", function() {
+ var context = JEFRi.Divine.JSON(sample1);
+ ok(context, "Loaded context.");
+ ok(context.entities, "Context has entities.");
+ ok(context.meta, "Context has meta.");
+ var meta = false;
+ for(var i=0; i<context.entities.length; i++){
+ meta = meta || context.entities[i].name === "meta";
+ }
+ ok(meta, "Expected meta as an entity of a context.");
+});
+
+});

0 comments on commit 38423f2

Please sign in to comment.