Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gmoeck committed Apr 19, 2011
0 parents commit b332c6f
Show file tree
Hide file tree
Showing 31 changed files with 1,287 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
tmp
16 changes: 16 additions & 0 deletions Buildfile
@@ -0,0 +1,16 @@
require File.expand_path('../frameworks/jasmine-sproutcore/builders/jasmine_builder', __FILE__)

config :all, :required => 'sproutcore'

# CORE FRAMEWORKS
config :foundation, :required => [:sproutcore]

# WRAPPER FRAMEWORKS
config :fictum, :required => [:foundation]

namespace :build do
desc "builds a jasmine unit test"
build_task :test do
Jasmine::Builder::Test.build ENTRY, DST_PATH
end
end
34 changes: 34 additions & 0 deletions Readme.markdown
@@ -0,0 +1,34 @@
#Fictum
- [http://github.com/gmoeck/fictum](http://github.com/gmoeck/fictum)


##Description:
Fictum is designed to make it easier to test your sproutcore applications in pure javascript by providing an intuitive interface to create a fake server to respond to your application's request.

##Installation

To setup fictum to work in your SproutCore project, we need to add the framework to your application.

$ cd <your sproutcore project's root directory>
$ mkdir frameworks # if you don't already have a frameworks folder
$ cd frameworks
$ git clone git://github.com/gmoeck/fictum.git

##Usage
At this point, the easiest way to see how fictum can be used is to look at it's
integration tests. These can be seen within
[foundation/tests/integration](https://github.com/gmoeck/fictum/tree/master/frameworks/foundation/tests/integration).

##Running the tests
First start your server running.

$ cd <your sproutcore project's root directory>
$ sc-server

###Integration Tests
http://localhost:4020/static/foundation/en/current/tests/integration.html

###Unit Tests
http://localhost:4020/static/foundation/en/current/tests/unit.html


1 change: 1 addition & 0 deletions frameworks/foundation/core.js
@@ -0,0 +1 @@
//Blank file
75 changes: 75 additions & 0 deletions frameworks/foundation/debug/base.js
@@ -0,0 +1,75 @@
Fictum = {
setup: function() {
this.server = Fictum.Server.create();
if(this.originalSendFunction === undefined)
this.startInterceptingRequests();
},

teardown: function() {
if(this.originalSendFunction !== undefined)
this.stopInterceptingRequests();
this.server.destroy();
this.server = undefined;
},

isARegisteredUrl: function(url) {
this._ensureServerIsSetup();
return this.server.isARegisteredUrl(url);
},

registerUrl: function(url, response) {
this._ensureServerIsSetup();
this.server.registerUrl(url, response);
},

responseFor: function(url) {
this._ensureServerIsSetup();
return this.server.responseFor(url);
},

addResourceType: function(type, defaultAttributes) {
this._ensureServerIsSetup();
this.server.addResourceType(type, defaultAttributes);
},

addResource: function(type, attributes) {
this._ensureServerIsSetup();
this.server.addResource(type, attributes);
},

startInterceptingRequests: function() {
if(Fictum.originalSendFunction != undefined)
throw new Error('ERROR: Already intercepting requests');
Fictum.originalSendFunction = SC.Request.prototype.send;

SC.Request.reopen({
send: function(original, context) {
if(Fictum.isARegisteredUrl(this.get('address'))) {
var response = Fictum.responseFor(this.get('address'));
response.set('request', this);
setTimeout(function() {
response.set('status', 200);
response.notify();
}, 1);
return response;
} else {
return original(context);
}
}.enhance()
});
},

stopInterceptingRequests: function() {
if(Fictum.originalSendFunction === undefined)
throw new Error('ERROR: Not currently intercepting requests');
SC.Request.reopen({
send: Fictum.originalSendFunction
});
Fictum.originalSendFunction = undefined;
},

_ensureServerIsSetup: function() {
if(this.server === undefined)
throw new Error('ERROR: Server has not yet been setup');
}
};
5 changes: 5 additions & 0 deletions frameworks/foundation/debug/resource.js
@@ -0,0 +1,5 @@
sc_require('debug/fake_server/base');

Fictum.FakeResource = SC.Object.extend({
});

31 changes: 31 additions & 0 deletions frameworks/foundation/debug/resource_store.js
@@ -0,0 +1,31 @@
sc_require('debug/fake_server/resource_type');

Fictum.ResourceStore = SC.Object.extend({
resourceTypes: [],

addResourceType: function(type, defaultAttributes) {
this.get('resourceTypes').push(Fictum.ResourceType.create({ type: type, defaultAttributes: defaultAttributes }));
},

addResource: function(type, attributes) {
var resourceType = this._resourceTypeFor(type);
if(resourceType == null)
throw new Error('ERROR: The type requested is not registered in the resource store');
resourceType.addResource(attributes);
},

allOfType: function(type) {
var resourceType = this._resourceTypeFor(type);
if(! resourceType)
throw new Error('ERROR: The type requested is not registered in the resource store');
return this._resourceTypeFor(type).all();
},

empty: function() {
this.set('resourceTypes', []);
},

_resourceTypeFor: function(type) {
return this.get('resourceTypes').find(function(resourceType) { return resourceType.ofType(type) })
}
});
27 changes: 27 additions & 0 deletions frameworks/foundation/debug/resource_type.js
@@ -0,0 +1,27 @@
sc_require('debug/fake-server/resource');

Fictum.ResourceType = SC.Object.extend({
resources: [],

ofType: function(type) {
return this.get('type') === type;
},

all: function() {
return this.get('resources');
},

addResource: function(attributes) {
var newResource = this._attributeHashFor(attributes);
this.get('resources').push(newResource);
return newResource;
},

_attributeHashFor: function(attributes) {
var defaultAttributes = this.get('defaultAttributes');
for( var key in attributes) {
defaultAttributes[key] = attributes[key];
}
return defaultAttributes;
}
});
@@ -0,0 +1,8 @@
sc_require('debug/fake_server/base');
sc_require('debug/utils/json');

Fictum.DynamicResponse = SC.Object.extend({
value: function(store) {
return JSON.stringify(this.get('response')(store));
}
});
7 changes: 7 additions & 0 deletions frameworks/foundation/debug/response_types/static_response.js
@@ -0,0 +1,7 @@
sc_require('debug/fake_server/base');

Fictum.StaticResponse = SC.Object.extend({
value: function() {
return this.get('response');
}
});
32 changes: 32 additions & 0 deletions frameworks/foundation/debug/server.js
@@ -0,0 +1,32 @@
sc_require('debug/fake_server/base');
sc_require('debug/fake_server/url_stub_collection');
sc_require('debug/fake_server/resource_store');

Fictum.Server = SC.Object.extend({
init: function() {
sc_super();
this.set('urlStubs', Fictum.UrlStubCollection.create());
this.set('resourceStore', Fictum.ResourceStore.create());
return this;
},

isARegisteredUrl: function(url) {
return this.get('urlStubs').hasUrl(url);
},

registerUrl: function(url, stubValue) {
this.get('urlStubs').addUrl(url, stubValue);
},

responseFor: function(url) {
return this.get('urlStubs').responseFor(url, this.get('resourceStore'));
},

addResource: function(type, attributes) {
this.get('resourceStore').addResource(type, attributes);
},

addResourceType: function(type, defaultAttributes) {
this.get('resourceStore').addResourceType(type, defaultAttributes);
}
});
38 changes: 38 additions & 0 deletions frameworks/foundation/debug/url_stub.js
@@ -0,0 +1,38 @@
sc_require('debug/fake_server/response_types/dynamic_response');
sc_require('debug/fake_server/response_types/static_response');
sc_require('debug/fake_server/url_types/string_url');
sc_require('debug/fake_server/url_types/regular_expression_url');

Fictum.UrlStub = SC.Object.extend({
init: function(attributes) {
sc_super();

this._setupUrl();
this._setupResponse();
},

matchesUrl: function(url) {
return this.get('url').matches(url);
},

getResponse: function(store) {
return SC.Response.create({body: this.get('response').value(store)});
},

_setupUrl: function() {
var url = this.get('url');
if(SC.typeOf(url) == 'string')
this.set('url', Fictum.StringUrl.create({url: url}));
else
this.set('url', Fictum.RegularExpressionUrl.create({url: url}));
},

_setupResponse: function() {
var response = this.get('response');
if(SC.typeOf(response) == 'function')
this.set('response', Fictum.DynamicResponse.create({response: response}));
else
this.set('response', Fictum.StaticResponse.create({response: response}));
}
});

26 changes: 26 additions & 0 deletions frameworks/foundation/debug/url_stub_collection.js
@@ -0,0 +1,26 @@
sc_require('debug/fake_server/url_stub');

Fictum.UrlStubCollection = SC.Object.extend({
urls: [],

hasUrl: function(url) {
return this._findUrlStubByUrl(url) !== null;
},

addUrl: function(url, stubValue) {
this.get('urls').push(Fictum.UrlStub.create({url: url, response: stubValue}));
},

responseFor: function(url, resourceStore) {
var urlStub = this._findUrlStubByUrl(url);
return urlStub === null ? undefined : urlStub.getResponse(resourceStore);
},

empty: function() {
this.set('urls', []);
},

_findUrlStubByUrl: function(url) {
return this.get('urls').find(function(stub) { return stub.matchesUrl(url) })
},
});
8 changes: 8 additions & 0 deletions frameworks/foundation/debug/url_types/base.js
@@ -0,0 +1,8 @@
sc_require('debug/fake_server/base');

Fictum.Url = SC.Object.extend({
matches: function(url) {
throw new Error('ERROR: Did not implement matches');
}
});

@@ -0,0 +1,7 @@
sc_require('debug/fake_server/url_types/base');

Fictum.RegularExpressionUrl = Fictum.Url.extend({
matches: function(url) {
return url.match(this.get('url')) !== null;
}
});
7 changes: 7 additions & 0 deletions frameworks/foundation/debug/url_types/string_url.js
@@ -0,0 +1,7 @@
sc_require('debug/fake_server/url_types/base');

Fictum.StringUrl = Fictum.Url.extend({
matches: function(url) {
return this.get('url') == url;
}
});
19 changes: 19 additions & 0 deletions frameworks/foundation/debug/utils/json.js
@@ -0,0 +1,19 @@
JSON.stringify = JSON.stringify || function (obj) {
var t = typeof (obj);
if (t != "object" || obj === null) {
// simple data type
if (t == "string") obj = '"'+obj+'"';
return String(obj);
}
else {
// recurse array or object
var n, v, json = [], arr = (obj && obj.constructor == Array);
for (n in obj) {
v = obj[n]; t = typeof(v);
if (t == "string") v = '"'+v+'"';
else if (t == "object" && v !== null) v = JSON.stringify(v);
json.push((arr ? "" : '"' + n + '":') + String(v));
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
}
};

0 comments on commit b332c6f

Please sign in to comment.