Permalink
Browse files

adding Jasmine tests for private_pub.js

  • Loading branch information...
1 parent e194743 commit ef03ef3669f9f8305f5f709fd3491e5727a68873 @ryanb ryanb committed Apr 27, 2011
View
@@ -1,10 +1,12 @@
require 'rubygems'
require 'rake'
require 'rspec/core/rake_task'
+require 'jasmine'
+load 'jasmine/tasks/jasmine.rake'
desc "Run RSpec"
RSpec::Core::RakeTask.new do |t|
t.verbose = false
end
-task :default => :spec
+task :default => [:spec, "jasmine:ci"]
@@ -1,63 +1,72 @@
-PrivatePub = {
- connecting: false,
- faye_client: null,
- faye_callbacks: [],
- subscriptions: {},
- subscription_callbacks: {},
+function buildPrivatePub(doc) {
+ var self = {
+ connecting: false,
+ fayeClient: null,
+ fayeCallbacks: [],
+ subscriptions: {},
+ subscriptionCallbacks: {},
- faye: function(callback) {
- if (PrivatePub.faye_client) {
- callback(PrivatePub.faye_client);
- } else {
- PrivatePub.faye_callbacks.push(callback);
- if (PrivatePub.subscriptions.server && !PrivatePub.connecting) {
- PrivatePub.connecting = true;
- var script = document.createElement("script");
- script.type = "text/javascript";
- script.src = PrivatePub.subscriptions.server + ".js";
- script.onload = function() {
- PrivatePub.faye_client = new Faye.Client(PrivatePub.subscriptions.server);
- PrivatePub.faye_client.addExtension(PrivatePub.faye_extension);
- for (var i=0; i < PrivatePub.faye_callbacks.length; i++) {
- PrivatePub.faye_callbacks[i](PrivatePub.faye_client);
- };
+ faye: function(callback) {
+ if (self.fayeClient) {
+ callback(self.fayeClient);
+ } else {
+ self.fayeCallbacks.push(callback);
+ if (self.subscriptions.server && !self.connecting) {
+ self.connecting = true;
+ var script = doc.createElement("script");
+ script.type = "text/javascript";
+ script.src = self.subscriptions.server + ".js";
+ script.onload = self.connectToFaye;
+ doc.documentElement.appendChild(script);
}
- document.documentElement.appendChild(script);
}
- }
- },
+ },
- faye_extension: {
- outgoing: function(message, callback) {
- if (message.channel == "/meta/subscribe") {
- // Attach the signature and timestamp to subscription messages
- var subscription = PrivatePub.subscriptions[message.subscription];
- if (!message.ext) message.ext = {};
- message.ext.private_pub_signature = subscription.signature;
- message.ext.private_pub_timestamp = subscription.timestamp;
- }
- callback(message);
- }
- },
+ connectToFaye: function() {
+ self.fayeClient = new Faye.Client(self.subscriptions.server);
+ self.fayeClient.addExtension(self.fayeExtension);
+ for (var i=0; i < self.fayeCallbacks.length; i++) {
+ self.fayeCallbacks[i](self.fayeClient);
+ };
+ },
- sign: function(options) {
- if (!PrivatePub.subscriptions.server) {
- PrivatePub.subscriptions.server = options.server;
- }
- PrivatePub.subscriptions[options.channel] = options;
- PrivatePub.faye(function(faye) {
- faye.subscribe(options.channel, function(message) {
- if (message.eval) {
- eval(message.eval);
- }
- if (callback = PrivatePub.subscription_callbacks[options.channel]) {
- callback(message.data, message.channel);
+ fayeExtension: {
+ outgoing: function(message, callback) {
+ if (message.channel == "/meta/subscribe") {
+ // Attach the signature and timestamp to subscription messages
+ var subscription = self.subscriptions[message.subscription];
+ if (!message.ext) message.ext = {};
+ message.ext.private_pub_signature = subscription.signature;
+ message.ext.private_pub_timestamp = subscription.timestamp;
}
+ callback(message);
+ }
+ },
+
+ sign: function(options) {
+ if (!self.subscriptions.server) {
+ self.subscriptions.server = options.server;
+ }
+ self.subscriptions[options.channel] = options;
+ self.faye(function(faye) {
+ faye.subscribe(options.channel, self.handleResponse);
});
- });
- },
+ },
+
+ handleResponse: function(message) {
+ if (message.eval) {
+ eval(message.eval);
+ }
+ if (callback = self.subscriptionCallbacks[message.channel]) {
+ callback(message.data, message.channel);
+ }
+ },
+
+ subscribe: function(channel, callback) {
+ self.subscriptionCallbacks[channel] = callback;
+ }
+ };
+ return self;
+}
- subscribe: function(channel, callback) {
- PrivatePub.subscription_callbacks[channel] = callback;
- }
-};
+var PrivatePub = buildPrivatePub(document);
View
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
s.require_path = "lib"
s.add_development_dependency 'rspec', '~> 2.1.0'
+ s.add_development_dependency 'jasmine'
s.rubyforge_project = s.name
s.required_rubygems_version = ">= 1.3.4"
@@ -0,0 +1,108 @@
+describe("PrivatePub", function() {
+ var pub, doc;
+ beforeEach(function() {
+ Faye = {}; // To simulate global Faye object
+ doc = {};
+ pub = buildPrivatePub(doc);
+ });
+
+ it("adds a subscription callback", function() {
+ pub.subscribe("hello", "callback");
+ expect(pub.subscriptionCallbacks["hello"]).toEqual("callback");
+ });
+
+ it("has a fayeExtension which adds matching subscription signature and timestamp to outgoing message", function() {
+ var called = false;
+ var message = {channel: "/meta/subscribe", subscription: "hello"}
+ pub.subscriptions["hello"] = {signature: "abcd", timestamp: "1234"}
+ pub.fayeExtension.outgoing(message, function(message) {
+ expect(message.ext.private_pub_signature).toEqual("abcd");
+ expect(message.ext.private_pub_timestamp).toEqual("1234");
+ called = true;
+ });
+ expect(called).toBeTruthy();
+ });
+
+ it("evaluates javascript in message response", function() {
+ pub.handleResponse({eval: 'self.subscriptions.foo = "bar"'});
+ expect(pub.subscriptions.foo).toEqual("bar");
+ });
+
+ it("triggers callback matching message channel in response", function() {
+ var called = false;
+ pub.subscribe("test", function(data, channel) {
+ expect(data).toEqual("abcd");
+ expect(channel).toEqual("test");
+ called = true;
+ });
+ pub.handleResponse({channel: "test", data: "abcd"});
+ expect(called).toBeTruthy();
+ });
+
+ it("adds a faye subscription with response handler when signing", function() {
+ var faye = {subscribe: jasmine.createSpy()};
+ spyOn(pub, 'faye').andCallFake(function(callback) {
+ callback(faye);
+ });
+ var options = {server: "server", channel: "somechannel"};
+ pub.sign(options);
+ expect(faye.subscribe).toHaveBeenCalledWith("somechannel", pub.handleResponse);
+ expect(pub.subscriptions.server).toEqual("server");
+ expect(pub.subscriptions.somechannel).toEqual(options);
+ });
+
+ it("adds a faye subscription with response handler when signing", function() {
+ var faye = {subscribe: jasmine.createSpy()};
+ spyOn(pub, 'faye').andCallFake(function(callback) {
+ callback(faye);
+ });
+ var options = {server: "server", channel: "somechannel"};
+ pub.sign(options);
+ expect(faye.subscribe).toHaveBeenCalledWith("somechannel", pub.handleResponse);
+ expect(pub.subscriptions.server).toEqual("server");
+ expect(pub.subscriptions.somechannel).toEqual(options);
+ });
+
+ it("triggers faye callback function immediately when fayeClient is available", function() {
+ var called = false;
+ pub.fayeClient = "faye";
+ pub.faye(function(faye) {
+ expect(faye).toEqual("faye");
+ called = true;
+ });
+ expect(called).toBeTruthy();
+ });
+
+ it("adds fayeCallback when client and server aren't available", function() {
+ pub.faye("callback");
+ expect(pub.fayeCallbacks[0]).toEqual("callback");
+ });
+
+ it("adds a script tag loading faye js when the server is present", function() {
+ script = {};
+ doc.createElement = function() { return script; };
+ doc.documentElement = {appendChild: jasmine.createSpy()};
+ pub.subscriptions.server = "path/to/faye";
+ pub.faye("callback");
+ expect(pub.fayeCallbacks[0]).toEqual("callback");
+ expect(script.type).toEqual("text/javascript");
+ expect(script.src).toEqual("path/to/faye.js");
+ expect(script.onload).toEqual(pub.connectToFaye);
+ expect(doc.documentElement.appendChild).toHaveBeenCalledWith(script);
+ });
+
+ it("connects to faye server, adds extension, and executes callbacks", function() {
+ callback = jasmine.createSpy();
+ client = {addExtension: jasmine.createSpy()};
+ Faye.Client = function(server) {
+ expect(server).toEqual("server")
+ return client;
+ };
+ pub.subscriptions.server = "server";
+ pub.fayeCallbacks.push(callback);
+ pub.connectToFaye();
+ expect(pub.fayeClient).toEqual(client);
+ expect(client.addExtension).toHaveBeenCalledWith(pub.fayeExtension);
+ expect(callback).toHaveBeenCalledWith(client);
+ });
+});
@@ -0,0 +1,73 @@
+# src_files
+#
+# Return an array of filepaths relative to src_dir to include before jasmine specs.
+# Default: []
+#
+# EXAMPLE:
+#
+# src_files:
+# - lib/source1.js
+# - lib/source2.js
+# - dist/**/*.js
+#
+src_files:
+ - lib/generators/private_pub/templates/private_pub.js
+
+# stylesheets
+#
+# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
+# Default: []
+#
+# EXAMPLE:
+#
+# stylesheets:
+# - css/style.css
+# - stylesheets/*.css
+#
+stylesheets:
+
+# helpers
+#
+# Return an array of filepaths relative to spec_dir to include before jasmine specs.
+# Default: ["helpers/**/*.js"]
+#
+# EXAMPLE:
+#
+# helpers:
+# - helpers/**/*.js
+#
+helpers:
+
+# spec_files
+#
+# Return an array of filepaths relative to spec_dir to include.
+# Default: ["**/*[sS]pec.js"]
+#
+# EXAMPLE:
+#
+# spec_files:
+# - **/*[sS]pec.js
+#
+spec_files:
+
+# src_dir
+#
+# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
+# Default: project root
+#
+# EXAMPLE:
+#
+# src_dir: public
+#
+src_dir:
+
+# spec_dir
+#
+# Spec directory path. Your spec_files must be returned relative to this path.
+# Default: spec/javascripts
+#
+# EXAMPLE:
+#
+# spec_dir: spec/javascripts
+#
+spec_dir:
@@ -0,0 +1,23 @@
+module Jasmine
+ class Config
+
+ # Add your overrides or custom config code here
+
+ end
+end
+
+
+# Note - this is necessary for rspec2, which has removed the backtrace
+module Jasmine
+ class SpecBuilder
+ def declare_spec(parent, spec)
+ me = self
+ example_name = spec["name"]
+ @spec_ids << spec["id"]
+ backtrace = @example_locations[parent.description + " " + example_name]
+ parent.it example_name, {} do
+ me.report_spec(spec["id"])
+ end
+ end
+ end
+end
@@ -0,0 +1,32 @@
+$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
+
+require 'rubygems'
+require 'jasmine'
+jasmine_config_overrides = File.expand_path(File.join(File.dirname(__FILE__), 'jasmine_config.rb'))
+require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
+if Jasmine::rspec2?
+ require 'rspec'
+else
+ require 'spec'
+end
+
+jasmine_config = Jasmine::Config.new
+spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
+
+should_stop = false
+
+if Jasmine::rspec2?
+ RSpec.configuration.after(:suite) do
+ spec_builder.stop if should_stop
+ end
+else
+ Spec::Runner.configure do |config|
+ config.after(:suite) do
+ spec_builder.stop if should_stop
+ end
+ end
+end
+
+spec_builder.start
+should_stop = true
+spec_builder.declare_suites

0 comments on commit ef03ef3

Please sign in to comment.