forked from ryanb/private_pub
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adding Jasmine tests for private_pub.js
- Loading branch information
Showing
7 changed files
with
304 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |