puller 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +4 -0
- data/README.md +85 -15
- data/Rakefile +13 -0
- data/app/assets/javascripts/puller.js +72 -0
- data/lib/generators/puller/install_generator.rb +16 -0
- data/lib/generators/puller/templates/.gitkeep +0 -0
- data/lib/puller/engine.rb +19 -0
- data/lib/puller/version.rb +1 -1
- data/lib/puller/view_helpers.rb +18 -0
- data/lib/puller.rb +30 -1
- data/puller.gemspec +6 -0
- data/spec/javascripts/puller_spec.js +109 -0
- data/spec/javascripts/support/jasmine.yml +74 -0
- data/spec/javascripts/support/jasmine_config.rb +24 -0
- data/spec/javascripts/support/jasmine_runner.rb +33 -0
- data/spec/puller_spec.rb +8 -0
- data/spec/spec_helper.rb +9 -0
- metadata +61 -2
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,29 +1,99 @@
|
|
1
1
|
# Puller
|
2
2
|
|
3
|
-
|
3
|
+
Puller is a Ruby gem for use with Rails to publish and subscribe to messages through [Pusher](http://pusher.com/). It allows you to easily provide real-time updates through an open socket without tying up a Rails process.
|
4
4
|
|
5
|
-
|
5
|
+
Its code and API design is heavily inspired by Ryan Bates' [PrivatePub](http://github.com/ryanb/private_pub).
|
6
6
|
|
7
|
-
Add this line to your application's Gemfile:
|
8
7
|
|
9
|
-
|
8
|
+
## Setup
|
10
9
|
|
11
|
-
|
10
|
+
Add the gem to the Gemfile of your Rails application and run the `bundle` command to install it.
|
12
11
|
|
13
|
-
|
12
|
+
```ruby
|
13
|
+
gem "puller"
|
14
|
+
```
|
14
15
|
|
15
|
-
Or install it yourself as:
|
16
16
|
|
17
|
-
|
17
|
+
**In Rails 3.1** add the JavaScript file to your application.js file manifest.
|
18
|
+
|
19
|
+
```javascript
|
20
|
+
//= require puller
|
21
|
+
```
|
22
|
+
|
23
|
+
|
24
|
+
**In Rails 3.0** run the generator to create the initial files
|
25
|
+
|
26
|
+
```
|
27
|
+
rails g puller:install
|
28
|
+
```
|
29
|
+
|
30
|
+
and add the generated puller.js file to your layout.
|
31
|
+
|
32
|
+
```rhtml
|
33
|
+
<%= javascript_include_tag "puller" %>
|
34
|
+
```
|
35
|
+
|
36
|
+
|
37
|
+
It's not necessary to include pusher.js since that will be handled automatically for you.
|
38
|
+
|
39
|
+
Configure your Pusher credentials in an initializer file.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
Pusher.app_id = 'my_pusher_app_id'
|
43
|
+
Pusher.key = 'my_pusher_api_key'
|
44
|
+
Pusher.secret = 'my_pusher_secret'
|
45
|
+
```
|
46
|
+
|
47
|
+
Note: You can skip this step if you are on Heroku and have activated the Pusher addon for your app.
|
48
|
+
|
18
49
|
|
19
50
|
## Usage
|
20
51
|
|
21
|
-
|
52
|
+
Use the `subscribe_to` helper method on any page to subscribe to a channel/event.
|
53
|
+
|
54
|
+
```rhtml
|
55
|
+
<%= subscribe_to "new-message" %>
|
56
|
+
```
|
57
|
+
|
58
|
+
The above method subscribes to the "new-message" event in the default channel. The default channel name is
|
59
|
+
the parameterized form of your Rails' application name. To use a different channel, prepend your custom
|
60
|
+
channel name to the argument followed by a colon:
|
61
|
+
|
62
|
+
```rhtml
|
63
|
+
<%= subscribe_to "my-channel:new-message" %>
|
64
|
+
```
|
65
|
+
|
66
|
+
Use the `publish_to` helper method to send JavaScript to that channel/event. This is usually done in a JavaScript AJAX template (such as a create.js.erb file).
|
67
|
+
|
68
|
+
```rhtml
|
69
|
+
<% publish_to "new-message" do %>
|
70
|
+
$("#chat").append("<%= j render(@message) %>");
|
71
|
+
<% end %>
|
72
|
+
```
|
73
|
+
|
74
|
+
This JavaScript will be immediately evaluated on all clients who have subscribed to that channel. In this example they will see the new chat message appear in real-time without reloading the browser.
|
75
|
+
|
76
|
+
|
77
|
+
## Alternative Usage
|
78
|
+
|
79
|
+
If you prefer to work through JSON instead of `.js.erb` templates, you can pass a hash to `publish_to` instead of a block and it will be converted `to_json` behind the scenes. This can be done anywhere (such as the controller).
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
Puller.publish_to "new-message", :chat_message => "Hello, world!"
|
83
|
+
```
|
84
|
+
|
85
|
+
And then handle this through JavaScript on the client side.
|
86
|
+
|
87
|
+
```javascript
|
88
|
+
Puller.subscribe("new-message", function(data, channel) {
|
89
|
+
$("#chat").append(data.chat_message);
|
90
|
+
});
|
91
|
+
```
|
92
|
+
|
93
|
+
The Ruby `subscribe_to` helper call is still necessary with this approach to grant the user access to the channel. The JavaScript is just a callback for any custom behavior.
|
94
|
+
|
95
|
+
|
96
|
+
## Development & Feedback
|
22
97
|
|
23
|
-
|
98
|
+
Questions or comments? Please use the [issue tracker](https://github.com/natekross/puller/issues). Tests can be run with `bundle` and `rake` commands.
|
24
99
|
|
25
|
-
1. Fork it
|
26
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
-
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
data/Rakefile
CHANGED
@@ -1,3 +1,16 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
require "bundler/gem_tasks"
|
3
3
|
|
4
|
+
require "rubygems"
|
5
|
+
require "rake"
|
6
|
+
require "rspec/core/rake_task"
|
7
|
+
require "jasmine"
|
8
|
+
load "jasmine/tasks/jasmine.rake"
|
9
|
+
|
10
|
+
desc "Run RSpec"
|
11
|
+
RSpec::Core::RakeTask.new do |t|
|
12
|
+
t.verbose = false
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => [:spec, "jasmine:ci"]
|
16
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
function buildPuller(doc) {
|
2
|
+
var self = {
|
3
|
+
connecting: false,
|
4
|
+
pusher: null,
|
5
|
+
initCallbacks: [],
|
6
|
+
subscriptions: {},
|
7
|
+
subscriptionCallbacks: {},
|
8
|
+
channels: {},
|
9
|
+
|
10
|
+
fetchPusher: function(callback) {
|
11
|
+
if (self.pusher) {
|
12
|
+
callback(self.pusher);
|
13
|
+
} else {
|
14
|
+
self.initCallbacks.push(callback);
|
15
|
+
|
16
|
+
if (self.subscriptions.apiKey && !self.connecting) {
|
17
|
+
self.connecting = true;
|
18
|
+
|
19
|
+
var script = doc.createElement("script");
|
20
|
+
script.type = "text/javascript";
|
21
|
+
script.src = "http://js.pusher.com/1.11/pusher.min.js";
|
22
|
+
script.onload = self.connectToPusher;
|
23
|
+
|
24
|
+
doc.documentElement.appendChild(script);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
},
|
28
|
+
|
29
|
+
connectToPusher: function() {
|
30
|
+
self.pusher = new Pusher(self.subscriptions.apiKey);
|
31
|
+
|
32
|
+
for (var i = 0, ii = self.initCallbacks.length; i < ii; i++) {
|
33
|
+
self.initCallbacks[i](self.pusher);
|
34
|
+
};
|
35
|
+
},
|
36
|
+
|
37
|
+
sign: function(options) {
|
38
|
+
if (!self.subscriptions.apiKey) {
|
39
|
+
self.subscriptions.apiKey = options.apiKey;
|
40
|
+
}
|
41
|
+
|
42
|
+
self.subscriptions[options.channel + ":" + options.event] = options;
|
43
|
+
|
44
|
+
self.fetchPusher(function(pusher) {
|
45
|
+
if (!self.channels[options.channel]) {
|
46
|
+
self.channels[options.channel] = pusher.subscribe(options.channel);
|
47
|
+
}
|
48
|
+
|
49
|
+
self.channels[options.channel].bind(options.event, self.handleResponse);
|
50
|
+
});
|
51
|
+
},
|
52
|
+
|
53
|
+
handleResponse: function(message) {
|
54
|
+
if (message.eval) {
|
55
|
+
eval(message.eval);
|
56
|
+
}
|
57
|
+
|
58
|
+
if (callback = self.subscriptionCallbacks[message.channel + ":" + message.event]) {
|
59
|
+
callback(message.data, message.channel, message.event);
|
60
|
+
}
|
61
|
+
},
|
62
|
+
|
63
|
+
subscribe: function(channel_event, callback) {
|
64
|
+
self.subscriptionCallbacks[channel_event] = callback;
|
65
|
+
}
|
66
|
+
};
|
67
|
+
|
68
|
+
return self;
|
69
|
+
}
|
70
|
+
|
71
|
+
var Puller = buildPuller(document);
|
72
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Puller
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
def self.source_root
|
5
|
+
File.dirname(__FILE__) + "/templates"
|
6
|
+
end
|
7
|
+
|
8
|
+
def copy_files
|
9
|
+
if ::Rails.version < "3.1"
|
10
|
+
copy_file "../../../../app/assets/javascripts/puller.js", "public/javascripts/puller.js"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "puller/view_helpers"
|
2
|
+
|
3
|
+
module Puller
|
4
|
+
class Engine < Rails::Engine
|
5
|
+
# Adds the ViewHelpers into ActionView::Base and sets
|
6
|
+
# Pusher's logger to Rails' logger.
|
7
|
+
initializer "puller.init" do
|
8
|
+
ActionView::Base.send :include, ViewHelpers
|
9
|
+
Pusher.logger = Rails.logger
|
10
|
+
|
11
|
+
Puller.default_channel = begin
|
12
|
+
app_name = Rails.application.class.name
|
13
|
+
app_name = app_name.split('::').first
|
14
|
+
app_name.parameterize
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
data/lib/puller/version.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Puller
|
2
|
+
module ViewHelpers
|
3
|
+
def publish_to(channel_event, data = nil, &block)
|
4
|
+
Puller.publish_to channel_event, data || capture(&block)
|
5
|
+
end
|
6
|
+
|
7
|
+
def subscribe_to(channel_event)
|
8
|
+
channel, event = Puller.channel_and_event_for(channel_event)
|
9
|
+
|
10
|
+
options = { :channel => channel, :event => event, :apiKey => Pusher.key }
|
11
|
+
|
12
|
+
content_tag "script", :type => "text/javascript" do
|
13
|
+
raw "Puller.sign(#{options.to_json});"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
data/lib/puller.rb
CHANGED
@@ -1,6 +1,35 @@
|
|
1
|
+
require "pusher"
|
2
|
+
|
1
3
|
require "puller/version"
|
4
|
+
require "puller/engine" if defined? Rails
|
2
5
|
|
3
6
|
module Puller
|
4
|
-
|
7
|
+
class << self
|
8
|
+
attr_writer :default_channel
|
9
|
+
|
10
|
+
def default_channel
|
11
|
+
@default_channel ||= "default"
|
12
|
+
end
|
13
|
+
|
14
|
+
def publish_to(channel_event, data)
|
15
|
+
channel, event = channel_and_event_for(channel_event)
|
16
|
+
|
17
|
+
message = { :channel => channel, :event => event }
|
18
|
+
message[data.kind_of?(String) ? :eval : :data] = data
|
19
|
+
|
20
|
+
Pusher[channel].trigger event, message
|
21
|
+
end
|
22
|
+
|
23
|
+
def channel_and_event_for(text)
|
24
|
+
channel, event = text.split(':', 1)
|
25
|
+
|
26
|
+
if event.nil?
|
27
|
+
event = channel
|
28
|
+
channel = default_channel
|
29
|
+
end
|
30
|
+
|
31
|
+
[channel, event]
|
32
|
+
end
|
33
|
+
end
|
5
34
|
end
|
6
35
|
|
data/puller.gemspec
CHANGED
@@ -17,5 +17,11 @@ Gem::Specification.new do |gem|
|
|
17
17
|
|
18
18
|
gem.rubyforge_project = gem.name
|
19
19
|
gem.required_rubygems_version = ">= 1.3.4"
|
20
|
+
|
21
|
+
gem.add_dependency "pusher", "~> 0.8.5"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rake"
|
24
|
+
gem.add_development_dependency "rspec", "~> 2.8.0"
|
25
|
+
gem.add_development_dependency "jasmine", ">= 1.1.1"
|
20
26
|
end
|
21
27
|
|
@@ -0,0 +1,109 @@
|
|
1
|
+
describe("Puller", function() {
|
2
|
+
var puller, doc;
|
3
|
+
|
4
|
+
beforeEach(function() {
|
5
|
+
Pusher = {}; // To simulate global Pusher object
|
6
|
+
doc = {};
|
7
|
+
puller = buildPuller(doc);
|
8
|
+
});
|
9
|
+
|
10
|
+
it("adds a subscription callback", function() {
|
11
|
+
puller.subscribe("hello", "callback");
|
12
|
+
expect(puller.subscriptionCallbacks["hello"]).toEqual("callback");
|
13
|
+
});
|
14
|
+
|
15
|
+
it("evaluates javascript in message response", function() {
|
16
|
+
puller.handleResponse({eval: 'self.subscriptions.foo = "bar"'});
|
17
|
+
expect(puller.subscriptions.foo).toEqual("bar");
|
18
|
+
});
|
19
|
+
|
20
|
+
it("triggers callback matching message channel in response", function() {
|
21
|
+
var called = false;
|
22
|
+
puller.subscribe("chan:test", function(data, channel, event) {
|
23
|
+
expect(data).toEqual("abcd");
|
24
|
+
expect(channel).toEqual("chan");
|
25
|
+
expect(event).toEqual("test");
|
26
|
+
called = true;
|
27
|
+
});
|
28
|
+
puller.handleResponse({channel: "chan", event: "test", data: "abcd"});
|
29
|
+
expect(called).toBeTruthy();
|
30
|
+
});
|
31
|
+
|
32
|
+
it("adds a pusher subscription with response handler when signing", function() {
|
33
|
+
var subscribeCalled = false,
|
34
|
+
bindCalled = false,
|
35
|
+
channel = {
|
36
|
+
bind: function(event, callback) {
|
37
|
+
expect(event).toEqual("someevent");
|
38
|
+
expect(callback).toEqual(puller.handleResponse);
|
39
|
+
bindCalled = true;
|
40
|
+
}
|
41
|
+
},
|
42
|
+
pusher = {
|
43
|
+
subscribe: function(channelName) {
|
44
|
+
expect(channelName).toEqual("somechannel");
|
45
|
+
subscribeCalled = true;
|
46
|
+
|
47
|
+
return channel;
|
48
|
+
}
|
49
|
+
};
|
50
|
+
|
51
|
+
spyOn(puller, 'fetchPusher').andCallFake(function(callback) {
|
52
|
+
callback(pusher);
|
53
|
+
});
|
54
|
+
|
55
|
+
var options = {apiKey: "someapikey", channel: "somechannel", event: "someevent"};
|
56
|
+
puller.sign(options);
|
57
|
+
|
58
|
+
expect(puller.subscriptions.apiKey).toEqual("someapikey");
|
59
|
+
expect(puller.subscriptions["somechannel:someevent"]).toEqual(options);
|
60
|
+
|
61
|
+
expect(subscribeCalled).toBeTruthy();
|
62
|
+
expect(bindCalled).toBeTruthy();
|
63
|
+
|
64
|
+
expect(puller.channels["somechannel"]).toEqual(channel);
|
65
|
+
});
|
66
|
+
|
67
|
+
it("triggers pusher callback function immediately when pusher is available", function() {
|
68
|
+
var called = false;
|
69
|
+
puller.pusher = "pusher";
|
70
|
+
puller.fetchPusher(function(pusher) {
|
71
|
+
expect(pusher).toEqual("pusher");
|
72
|
+
called = true;
|
73
|
+
});
|
74
|
+
expect(called).toBeTruthy();
|
75
|
+
});
|
76
|
+
|
77
|
+
it("adds initCallback when client and server aren't available", function() {
|
78
|
+
puller.fetchPusher("callback");
|
79
|
+
expect(puller.initCallbacks[0]).toEqual("callback");
|
80
|
+
});
|
81
|
+
|
82
|
+
it("adds a script tag loading pusher js when the server is present", function() {
|
83
|
+
script = {};
|
84
|
+
doc.createElement = function() { return script; };
|
85
|
+
doc.documentElement = {appendChild: jasmine.createSpy()};
|
86
|
+
puller.subscriptions.apiKey = "someapikey";
|
87
|
+
puller.fetchPusher("callback");
|
88
|
+
expect(puller.initCallbacks[0]).toEqual("callback");
|
89
|
+
expect(script.type).toEqual("text/javascript");
|
90
|
+
expect(script.src).toEqual("http://js.pusher.com/1.11/pusher.min.js");
|
91
|
+
expect(script.onload).toEqual(puller.connectToPusher);
|
92
|
+
expect(doc.documentElement.appendChild).toHaveBeenCalledWith(script);
|
93
|
+
});
|
94
|
+
|
95
|
+
it("connects to pusher server and executes callbacks", function() {
|
96
|
+
callback = jasmine.createSpy();
|
97
|
+
client = { foo: "bar" };
|
98
|
+
Pusher = function(key) {
|
99
|
+
expect(key).toEqual("key")
|
100
|
+
return client;
|
101
|
+
};
|
102
|
+
puller.subscriptions.apiKey = "key";
|
103
|
+
puller.initCallbacks.push(callback);
|
104
|
+
puller.connectToPusher();
|
105
|
+
expect(puller.pusher).toEqual(client);
|
106
|
+
expect(callback).toHaveBeenCalledWith(client);
|
107
|
+
});
|
108
|
+
});
|
109
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# src_files
|
2
|
+
#
|
3
|
+
# Return an array of filepaths relative to src_dir to include before jasmine specs.
|
4
|
+
# Default: []
|
5
|
+
#
|
6
|
+
# EXAMPLE:
|
7
|
+
#
|
8
|
+
# src_files:
|
9
|
+
# - lib/source1.js
|
10
|
+
# - lib/source2.js
|
11
|
+
# - dist/**/*.js
|
12
|
+
#
|
13
|
+
src_files:
|
14
|
+
- app/assets/javascripts/puller.js
|
15
|
+
|
16
|
+
# stylesheets
|
17
|
+
#
|
18
|
+
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
|
19
|
+
# Default: []
|
20
|
+
#
|
21
|
+
# EXAMPLE:
|
22
|
+
#
|
23
|
+
# stylesheets:
|
24
|
+
# - css/style.css
|
25
|
+
# - stylesheets/*.css
|
26
|
+
#
|
27
|
+
stylesheets:
|
28
|
+
|
29
|
+
# helpers
|
30
|
+
#
|
31
|
+
# Return an array of filepaths relative to spec_dir to include before jasmine specs.
|
32
|
+
# Default: ["helpers/**/*.js"]
|
33
|
+
#
|
34
|
+
# EXAMPLE:
|
35
|
+
#
|
36
|
+
# helpers:
|
37
|
+
# - helpers/**/*.js
|
38
|
+
#
|
39
|
+
helpers:
|
40
|
+
|
41
|
+
# spec_files
|
42
|
+
#
|
43
|
+
# Return an array of filepaths relative to spec_dir to include.
|
44
|
+
# Default: ["**/*[sS]pec.js"]
|
45
|
+
#
|
46
|
+
# EXAMPLE:
|
47
|
+
#
|
48
|
+
# spec_files:
|
49
|
+
# - **/*[sS]pec.js
|
50
|
+
#
|
51
|
+
spec_files:
|
52
|
+
|
53
|
+
# src_dir
|
54
|
+
#
|
55
|
+
# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
|
56
|
+
# Default: project root
|
57
|
+
#
|
58
|
+
# EXAMPLE:
|
59
|
+
#
|
60
|
+
# src_dir: public
|
61
|
+
#
|
62
|
+
src_dir:
|
63
|
+
|
64
|
+
# spec_dir
|
65
|
+
#
|
66
|
+
# Spec directory path. Your spec_files must be returned relative to this path.
|
67
|
+
# Default: spec/javascripts
|
68
|
+
#
|
69
|
+
# EXAMPLE:
|
70
|
+
#
|
71
|
+
# spec_dir: spec/javascripts
|
72
|
+
#
|
73
|
+
spec_dir:
|
74
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class Config
|
3
|
+
|
4
|
+
# Add your overrides or custom config code here
|
5
|
+
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
# Note - this is necessary for rspec2, which has removed the backtrace
|
11
|
+
module Jasmine
|
12
|
+
class SpecBuilder
|
13
|
+
def declare_spec(parent, spec)
|
14
|
+
me = self
|
15
|
+
example_name = spec["name"]
|
16
|
+
@spec_ids << spec["id"]
|
17
|
+
backtrace = @example_locations[parent.description + " " + example_name]
|
18
|
+
parent.it example_name, {} do
|
19
|
+
me.report_spec(spec["id"])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'jasmine'
|
5
|
+
jasmine_config_overrides = File.expand_path(File.join(File.dirname(__FILE__), 'jasmine_config.rb'))
|
6
|
+
require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
|
7
|
+
if Jasmine::Dependencies.rspec2?
|
8
|
+
require 'rspec'
|
9
|
+
else
|
10
|
+
require 'spec'
|
11
|
+
end
|
12
|
+
|
13
|
+
jasmine_config = Jasmine::Config.new
|
14
|
+
spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
|
15
|
+
|
16
|
+
should_stop = false
|
17
|
+
|
18
|
+
if Jasmine::Dependencies.rspec2?
|
19
|
+
RSpec.configuration.after(:suite) do
|
20
|
+
spec_builder.stop if should_stop
|
21
|
+
end
|
22
|
+
else
|
23
|
+
Spec::Runner.configure do |config|
|
24
|
+
config.after(:suite) do
|
25
|
+
spec_builder.stop if should_stop
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
spec_builder.start
|
31
|
+
should_stop = true
|
32
|
+
spec_builder.declare_suites
|
33
|
+
|
data/spec/puller_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,51 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
date: 2012-01-19 00:00:00.000000000Z
|
13
|
-
dependencies:
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: pusher
|
16
|
+
requirement: &25369220 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.8.5
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *25369220
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &25368580 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *25368580
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &25367700 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.8.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *25367700
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: jasmine
|
49
|
+
requirement: &25365580 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.1.1
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *25365580
|
14
58
|
description: -- gem description --
|
15
59
|
email: natekross@gmail.com
|
16
60
|
executables: []
|
@@ -18,13 +62,25 @@ extensions: []
|
|
18
62
|
extra_rdoc_files: []
|
19
63
|
files:
|
20
64
|
- .gitignore
|
65
|
+
- CHANGELOG.md
|
21
66
|
- Gemfile
|
22
67
|
- LICENSE
|
23
68
|
- README.md
|
24
69
|
- Rakefile
|
70
|
+
- app/assets/javascripts/puller.js
|
71
|
+
- lib/generators/puller/install_generator.rb
|
72
|
+
- lib/generators/puller/templates/.gitkeep
|
25
73
|
- lib/puller.rb
|
74
|
+
- lib/puller/engine.rb
|
26
75
|
- lib/puller/version.rb
|
76
|
+
- lib/puller/view_helpers.rb
|
27
77
|
- puller.gemspec
|
78
|
+
- spec/javascripts/puller_spec.js
|
79
|
+
- spec/javascripts/support/jasmine.yml
|
80
|
+
- spec/javascripts/support/jasmine_config.rb
|
81
|
+
- spec/javascripts/support/jasmine_runner.rb
|
82
|
+
- spec/puller_spec.rb
|
83
|
+
- spec/spec_helper.rb
|
28
84
|
homepage: http://github.com/natekross/puller
|
29
85
|
licenses: []
|
30
86
|
post_install_message:
|
@@ -37,6 +93,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
37
93
|
- - ! '>='
|
38
94
|
- !ruby/object:Gem::Version
|
39
95
|
version: '0'
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
hash: 3142173162834286048
|
40
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
100
|
none: false
|
42
101
|
requirements:
|