edmond-danthes 2.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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +84 -0
- data/Gemfile +16 -0
- data/Guardfile +7 -0
- data/LICENSE +22 -0
- data/README.md +156 -0
- data/Rakefile +31 -0
- data/app/assets/javascripts/danthes.js.coffee +174 -0
- data/defaults.reek +11 -0
- data/edmond-danthes.gemspec +30 -0
- data/lib/danthes.rb +123 -0
- data/lib/danthes/engine.rb +16 -0
- data/lib/danthes/faye_extension.rb +40 -0
- data/lib/danthes/version.rb +3 -0
- data/lib/danthes/view_helpers.rb +22 -0
- data/lib/generators/danthes/install_generator.rb +13 -0
- data/lib/generators/danthes/redis_install_generator.rb +17 -0
- data/lib/generators/danthes_generator.rb +24 -0
- data/lib/generators/templates/danthes.ru +15 -0
- data/lib/generators/templates/danthes.yml +16 -0
- data/lib/generators/templates/danthes_redis.yml +14 -0
- data/spec/coffeescripts/danthesSpec.js.coffee +211 -0
- data/spec/danthes/faye_extension_spec.rb +67 -0
- data/spec/danthes/view_helpers_spec.rb +26 -0
- data/spec/danthes_spec.rb +193 -0
- data/spec/fake_app/rails_app.rb +18 -0
- data/spec/fixtures/danthes.yml +10 -0
- data/spec/fixtures/danthes_redis.yml +6 -0
- data/spec/fixtures/danthes_with_erb.yml +10 -0
- data/spec/javascripts/support/jasmine.yml +9 -0
- data/spec/javascripts/support/jasmine_helper.rb +11 -0
- data/spec/spec_helper.rb +29 -0
- metadata +274 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Danthes::FayeExtension do
|
|
4
|
+
before(:each) do
|
|
5
|
+
Danthes.startup
|
|
6
|
+
@faye = Danthes::FayeExtension.new
|
|
7
|
+
@message = { 'channel' => '/meta/subscribe', 'ext' => {} }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'adds an error on an incoming subscription with a bad signature' do
|
|
11
|
+
@message['subscription'] = 'hello'
|
|
12
|
+
@message['ext']['danthes_signature'] = 'bad'
|
|
13
|
+
@message['ext']['danthes_timestamp'] = '123'
|
|
14
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
15
|
+
expect(message['error']).to eq('Incorrect signature.')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'has no error when the signature matches the subscription' do
|
|
19
|
+
sub = Danthes.subscription(channel: 'hello')
|
|
20
|
+
@message['subscription'] = sub[:channel]
|
|
21
|
+
@message['ext']['danthes_signature'] = sub[:signature]
|
|
22
|
+
@message['ext']['danthes_timestamp'] = sub[:timestamp]
|
|
23
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
24
|
+
expect(message['error']).to be_nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'has an error when signature just expired' do
|
|
28
|
+
Danthes.config[:signature_expiration] = 1
|
|
29
|
+
sub = Danthes.subscription(timestamp: 123, channel: 'hello')
|
|
30
|
+
@message['subscription'] = sub[:channel]
|
|
31
|
+
@message['ext']['danthes_signature'] = sub[:signature]
|
|
32
|
+
@message['ext']['danthes_timestamp'] = sub[:timestamp]
|
|
33
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
34
|
+
expect(message['error']).to eq('Signature has expired.')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'has an error when trying to publish to a custom channel with a bad token' do
|
|
38
|
+
Danthes.config[:secret_token] = 'good'
|
|
39
|
+
@message['channel'] = '/custom/channel'
|
|
40
|
+
@message['ext']['danthes_token'] = 'bad'
|
|
41
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
42
|
+
expect(message['error']).to eq('Incorrect token.')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'raises an exception when attempting to call a custom channel without a secret_token set' do
|
|
46
|
+
@message['channel'] = '/custom/channel'
|
|
47
|
+
@message['ext']['danthes_token'] = 'bad'
|
|
48
|
+
expect do
|
|
49
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
50
|
+
end.to raise_error('No secret_token config set, ensure danthes.yml is loaded properly.')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'has no error on other meta calls' do
|
|
54
|
+
@message['channel'] = '/meta/connect'
|
|
55
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
56
|
+
expect(message['error']).to be_nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should not let message carry the private pub token after server's validation" do
|
|
60
|
+
Danthes.config[:secret_token] = 'good'
|
|
61
|
+
@message['channel'] = '/custom/channel'
|
|
62
|
+
@message['ext']['danthes_token'] = Danthes.config[:secret_token]
|
|
63
|
+
message = @faye.incoming(@message, ->(m) { m })
|
|
64
|
+
expect(message['ext']['danthes_token']).to be_nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'danthes/view_helpers'
|
|
3
|
+
|
|
4
|
+
module Danthes
|
|
5
|
+
describe ViewHelpers do
|
|
6
|
+
|
|
7
|
+
let(:klass) do
|
|
8
|
+
Class.new do
|
|
9
|
+
include ActionView::Helpers::TagHelper
|
|
10
|
+
include ActionView::Context
|
|
11
|
+
include ViewHelpers
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe '#subscribe_to' do
|
|
16
|
+
it "generates javascript tag by default" do
|
|
17
|
+
expect(klass.new.subscribe_to('hello')).to match /\A<script.*<\/script>\z/
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "removes javascript tag when *include_js_tag* is set to false" do
|
|
21
|
+
expect(klass.new.subscribe_to('hello', include_js_tag: false)).to match /\Aif \(typeof Danthes \!= 'undefined'\) { Danthes.sign\(.*\) }\z/
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Danthes do
|
|
4
|
+
before(:each) do
|
|
5
|
+
Danthes.startup
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
let(:config) { Danthes.config }
|
|
9
|
+
|
|
10
|
+
it 'defaults server to nil' do
|
|
11
|
+
expect(config[:server]).to be_nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'defaults signature_expiration to nil' do
|
|
15
|
+
expect(config[:signature_expiration]).to be_nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'defaults subscription timestamp to current time in milliseconds' do
|
|
19
|
+
time = Time.now
|
|
20
|
+
allow(Time).to receive(:now).and_return(time)
|
|
21
|
+
expect(Danthes.subscription[:timestamp]).to eq((time.to_f * 1000).round)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'loads a simple configuration file via load_config' do
|
|
25
|
+
Danthes.env = 'production'
|
|
26
|
+
Danthes.load_config('spec/fixtures/danthes.yml')
|
|
27
|
+
expect(config[:server]).to eq('http://example.com/faye')
|
|
28
|
+
expect(config[:secret_token]).to eq('PRODUCTION_SECRET_TOKEN')
|
|
29
|
+
expect(config[:signature_expiration]).to eq(600)
|
|
30
|
+
expect(config[:adapter]).to eq('thin')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'loads configuration file with erb via load_config' do
|
|
34
|
+
ENV['DANTHES_SERVER'] = 'http://example.com'
|
|
35
|
+
Danthes.env = 'production'
|
|
36
|
+
Danthes.load_config('spec/fixtures/danthes_with_erb.yml')
|
|
37
|
+
expect(config[:server]).to eq('http://example.com')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'when redis config exists' do
|
|
41
|
+
before do
|
|
42
|
+
Danthes.env = 'production'
|
|
43
|
+
Danthes.load_config('spec/fixtures/danthes.yml')
|
|
44
|
+
Danthes.load_redis_config('spec/fixtures/danthes_redis.yml')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'passes redis config to faye engine options' do
|
|
48
|
+
expect(config[:engine][:type]).to eq Faye::Redis
|
|
49
|
+
expect(config[:engine][:host]).to eq 'redis_host'
|
|
50
|
+
expect(config[:engine][:port]).to eq 'redis_port'
|
|
51
|
+
expect(config[:engine][:password]).to eq 'redis_password'
|
|
52
|
+
expect(config[:engine][:database]).to eq 'redis_database'
|
|
53
|
+
expect(config[:engine][:namespace]).to eq '/namespace'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'should pass redis config and default options to faye' do
|
|
57
|
+
expect(Faye::RackAdapter).to receive(:new) do |options|
|
|
58
|
+
expect(options[:engine]).to eq Danthes.config[:engine]
|
|
59
|
+
expect(options[:mount]).to eq '/faye'
|
|
60
|
+
end
|
|
61
|
+
Danthes.faye_app
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'when redis config does not exist' do
|
|
66
|
+
it 'should not have :engine inside of config hash' do
|
|
67
|
+
expect(config).not_to include :engine
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'should have mount point' do
|
|
71
|
+
expect(config[:mount]).to eq '/faye'
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'raises an exception if an invalid environment is passed to load_config' do
|
|
76
|
+
expect do
|
|
77
|
+
Danthes.load_config('spec/fixtures/danthes.yml', 'foo')
|
|
78
|
+
end.to raise_error ArgumentError
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'includes channel, server, and custom time in subscription' do
|
|
82
|
+
Danthes.config[:server] = 'server'
|
|
83
|
+
Danthes.config[:mount] = '/faye'
|
|
84
|
+
subscription = Danthes.subscription(timestamp: 123, channel: 'hello')
|
|
85
|
+
expect(subscription[:timestamp]).to eq(123)
|
|
86
|
+
expect(subscription[:channel]).to eq('hello')
|
|
87
|
+
expect(subscription[:server]).to eq('server/faye')
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'returns full server url from server and mount configs' do
|
|
91
|
+
Danthes.config[:server] = 'server.com'
|
|
92
|
+
Danthes.config[:mount] = '/faye'
|
|
93
|
+
expect(Danthes.server_url).to eq('server.com/faye')
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'does a sha1 digest of channel, timestamp, and secret token' do
|
|
97
|
+
Danthes.config[:secret_token] = 'token'
|
|
98
|
+
subscription = Danthes.subscription(timestamp: 123, channel: 'channel')
|
|
99
|
+
expect(subscription[:signature]).to eq(Digest::SHA1.hexdigest('tokenchannel123'))
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'formats a message hash given a channel and a string for eval' do
|
|
103
|
+
Danthes.config[:secret_token] = 'token'
|
|
104
|
+
expect(Danthes.message('chan', 'foo')).to eq(
|
|
105
|
+
ext: { danthes_token: 'token' },
|
|
106
|
+
channel: 'chan',
|
|
107
|
+
data: {
|
|
108
|
+
channel: 'chan',
|
|
109
|
+
eval: 'foo'
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'formats a message hash given a channel and a hash' do
|
|
115
|
+
Danthes.config[:secret_token] = 'token'
|
|
116
|
+
expect(Danthes.message('chan', foo: 'bar')).to eq(
|
|
117
|
+
ext: { danthes_token: 'token' },
|
|
118
|
+
channel: 'chan',
|
|
119
|
+
data: {
|
|
120
|
+
channel: 'chan',
|
|
121
|
+
data: { foo: 'bar' }
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'publish message as json to server using Net::HTTP' do
|
|
127
|
+
Danthes.config[:server] = 'http://localhost'
|
|
128
|
+
Danthes.config[:mount] = '/faye/path'
|
|
129
|
+
message = 'foo'
|
|
130
|
+
faye = stub_request(:post, 'http://localhost/faye/path').
|
|
131
|
+
with(body: { 'message' => "\"foo\"" },
|
|
132
|
+
headers: { 'Accept' => '*/*', 'Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Ruby' }).
|
|
133
|
+
to_return(status: 200, body: '', headers: {})
|
|
134
|
+
Danthes.publish_message(message)
|
|
135
|
+
expect(faye).to have_been_made.once
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'it should use HTTPS if the server URL says so' do
|
|
139
|
+
Danthes.config[:server] = 'https://localhost'
|
|
140
|
+
Danthes.config[:mount] = '/faye/path'
|
|
141
|
+
http = double(:http).as_null_object
|
|
142
|
+
|
|
143
|
+
expect(Net::HTTP).to receive(:new).and_return(http)
|
|
144
|
+
expect(http).to receive(:use_ssl=).with(true)
|
|
145
|
+
|
|
146
|
+
Danthes.publish_message('foo')
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'it should not use HTTPS if the server URL says not to' do
|
|
150
|
+
Danthes.config[:server] = 'http://localhost'
|
|
151
|
+
http = double(:http).as_null_object
|
|
152
|
+
|
|
153
|
+
expect(Net::HTTP).to receive(:new).and_return(http)
|
|
154
|
+
expect(http).to receive(:use_ssl=).with(false)
|
|
155
|
+
|
|
156
|
+
Danthes.publish_message('foo')
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it 'raises an exception if no server is specified when calling publish_message' do
|
|
160
|
+
expect do
|
|
161
|
+
Danthes.publish_message('foo')
|
|
162
|
+
end.to raise_error(Danthes::Error)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it 'publish_to passes message to publish_message call' do
|
|
166
|
+
expect(Danthes).to receive(:message).with('chan', 'foo').and_return('message')
|
|
167
|
+
expect(Danthes).to receive(:publish_message).with('message').and_return(:result)
|
|
168
|
+
expect(Danthes.publish_to('chan', 'foo')).to eq(:result)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'has a Faye rack app instance' do
|
|
172
|
+
Danthes.env = 'production'
|
|
173
|
+
Danthes.load_config('spec/fixtures/danthes.yml')
|
|
174
|
+
expect(Danthes.faye_app).to be_kind_of(Faye::RackAdapter)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it 'says signature has expired when time passed in is greater than expiration' do
|
|
178
|
+
Danthes.config[:signature_expiration] = 30 * 60
|
|
179
|
+
time = Danthes.subscription[:timestamp] - 31 * 60 * 1000
|
|
180
|
+
expect(Danthes.signature_expired?(time)).to be_truthy
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'says signature has not expired when time passed in is less than expiration' do
|
|
184
|
+
Danthes.config[:signature_expiration] = 30 * 60
|
|
185
|
+
time = Danthes.subscription[:timestamp] - 29 * 60 * 1000
|
|
186
|
+
expect(Danthes.signature_expired?(time)).to be_falsy
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it 'says signature has not expired when expiration is nil' do
|
|
190
|
+
Danthes.config[:signature_expiration] = nil
|
|
191
|
+
expect(Danthes.signature_expired?(0)).to be_falsy
|
|
192
|
+
end
|
|
193
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
ENV['RAILS_ENV'] ||= 'test'
|
|
2
|
+
|
|
3
|
+
require 'action_controller/railtie'
|
|
4
|
+
require 'danthes'
|
|
5
|
+
|
|
6
|
+
module RailsApp
|
|
7
|
+
class Application < Rails::Application
|
|
8
|
+
config.active_support.deprecation = :log
|
|
9
|
+
config.cache_classes = true
|
|
10
|
+
config.eager_load = false
|
|
11
|
+
config.root = __dir__
|
|
12
|
+
config.secret_token = 'x'*100
|
|
13
|
+
config.session_store :cookie_store, key: '_myapp_session'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
Rails.backtrace_cleaner.remove_silencers!
|
|
18
|
+
RailsApp::Application.initialize!
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
development:
|
|
2
|
+
adapter: thin
|
|
3
|
+
server: http://dev.local:9292/faye
|
|
4
|
+
secret_token: DEVELOPMENT_SECRET_TOKEN
|
|
5
|
+
signature_expiration: 600
|
|
6
|
+
production:
|
|
7
|
+
adapter: thin
|
|
8
|
+
server: http://example.com/faye
|
|
9
|
+
secret_token: PRODUCTION_SECRET_TOKEN
|
|
10
|
+
signature_expiration: 600
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
development:
|
|
2
|
+
adapter: thin
|
|
3
|
+
server: http://dev.local:9292/faye
|
|
4
|
+
secret_token: DEVELOPMENT_SECRET_TOKEN
|
|
5
|
+
signature_expiration: 600
|
|
6
|
+
production:
|
|
7
|
+
adapter: thin
|
|
8
|
+
server: <%= ENV['DANTHES_SERVER'] %>
|
|
9
|
+
secret_token: PRODUCTION_SECRET_TOKEN
|
|
10
|
+
signature_expiration: 600
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Use this file to set/override Jasmine configuration options
|
|
2
|
+
# You can remove it if you don't need it.
|
|
3
|
+
# This file is loaded *after* jasmine.yml is interpreted.
|
|
4
|
+
#
|
|
5
|
+
# Example: using a different boot file.
|
|
6
|
+
Jasmine.configure do |config|
|
|
7
|
+
config.ci_port = 8888
|
|
8
|
+
# config.boot_dir = '/absolute/path/to/boot_dir'
|
|
9
|
+
# config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] }
|
|
10
|
+
end
|
|
11
|
+
#
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
require 'simplecov'
|
|
4
|
+
require 'coveralls'
|
|
5
|
+
|
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
|
7
|
+
SimpleCov::Formatter::HTMLFormatter,
|
|
8
|
+
Coveralls::SimpleCov::Formatter
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
SimpleCov.start do
|
|
12
|
+
add_filter 'spec'
|
|
13
|
+
minimum_coverage(76)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Bundler.require(:default)
|
|
17
|
+
require 'faye'
|
|
18
|
+
require 'faye/redis'
|
|
19
|
+
require 'webmock/rspec'
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
require 'rails'
|
|
23
|
+
rescue LoadError
|
|
24
|
+
else
|
|
25
|
+
require 'fake_app/rails_app'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
RSpec.configure do |_config|
|
|
29
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: edmond-danthes
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 2.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alexander Simonov
|
|
8
|
+
- Dmitry Zuev
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2020-06-12 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: faye
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - ">="
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: 1.0.1
|
|
21
|
+
type: :runtime
|
|
22
|
+
prerelease: false
|
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: 1.0.1
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: faye-redis
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - ">="
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '0'
|
|
35
|
+
type: :runtime
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '0'
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: yajl-ruby
|
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: 1.2.0
|
|
49
|
+
type: :runtime
|
|
50
|
+
prerelease: false
|
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: 1.2.0
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: rake
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
- !ruby/object:Gem::Dependency
|
|
71
|
+
name: guard
|
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
type: :development
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - ">="
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '0'
|
|
84
|
+
- !ruby/object:Gem::Dependency
|
|
85
|
+
name: guard-coffeescript
|
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '0'
|
|
91
|
+
type: :development
|
|
92
|
+
prerelease: false
|
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
94
|
+
requirements:
|
|
95
|
+
- - ">="
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: '0'
|
|
98
|
+
- !ruby/object:Gem::Dependency
|
|
99
|
+
name: jasmine
|
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - ">="
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: 2.0.0
|
|
105
|
+
type: :development
|
|
106
|
+
prerelease: false
|
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
108
|
+
requirements:
|
|
109
|
+
- - ">="
|
|
110
|
+
- !ruby/object:Gem::Version
|
|
111
|
+
version: 2.0.0
|
|
112
|
+
- !ruby/object:Gem::Dependency
|
|
113
|
+
name: rspec
|
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
|
115
|
+
requirements:
|
|
116
|
+
- - ">="
|
|
117
|
+
- !ruby/object:Gem::Version
|
|
118
|
+
version: 3.0.0
|
|
119
|
+
type: :development
|
|
120
|
+
prerelease: false
|
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
122
|
+
requirements:
|
|
123
|
+
- - ">="
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: 3.0.0
|
|
126
|
+
- !ruby/object:Gem::Dependency
|
|
127
|
+
name: rspec-mocks
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
129
|
+
requirements:
|
|
130
|
+
- - ">="
|
|
131
|
+
- !ruby/object:Gem::Version
|
|
132
|
+
version: 3.0.0
|
|
133
|
+
type: :development
|
|
134
|
+
prerelease: false
|
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - ">="
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: 3.0.0
|
|
140
|
+
- !ruby/object:Gem::Dependency
|
|
141
|
+
name: webmock
|
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
|
143
|
+
requirements:
|
|
144
|
+
- - ">="
|
|
145
|
+
- !ruby/object:Gem::Version
|
|
146
|
+
version: '0'
|
|
147
|
+
type: :development
|
|
148
|
+
prerelease: false
|
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
150
|
+
requirements:
|
|
151
|
+
- - ">="
|
|
152
|
+
- !ruby/object:Gem::Version
|
|
153
|
+
version: '0'
|
|
154
|
+
- !ruby/object:Gem::Dependency
|
|
155
|
+
name: coveralls
|
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
|
157
|
+
requirements:
|
|
158
|
+
- - ">="
|
|
159
|
+
- !ruby/object:Gem::Version
|
|
160
|
+
version: '0'
|
|
161
|
+
type: :development
|
|
162
|
+
prerelease: false
|
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
164
|
+
requirements:
|
|
165
|
+
- - ">="
|
|
166
|
+
- !ruby/object:Gem::Version
|
|
167
|
+
version: '0'
|
|
168
|
+
- !ruby/object:Gem::Dependency
|
|
169
|
+
name: therubyracer
|
|
170
|
+
requirement: !ruby/object:Gem::Requirement
|
|
171
|
+
requirements:
|
|
172
|
+
- - ">="
|
|
173
|
+
- !ruby/object:Gem::Version
|
|
174
|
+
version: '0'
|
|
175
|
+
type: :development
|
|
176
|
+
prerelease: false
|
|
177
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
178
|
+
requirements:
|
|
179
|
+
- - ">="
|
|
180
|
+
- !ruby/object:Gem::Version
|
|
181
|
+
version: '0'
|
|
182
|
+
- !ruby/object:Gem::Dependency
|
|
183
|
+
name: rails
|
|
184
|
+
requirement: !ruby/object:Gem::Requirement
|
|
185
|
+
requirements:
|
|
186
|
+
- - ">="
|
|
187
|
+
- !ruby/object:Gem::Version
|
|
188
|
+
version: '0'
|
|
189
|
+
type: :development
|
|
190
|
+
prerelease: false
|
|
191
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
192
|
+
requirements:
|
|
193
|
+
- - ">="
|
|
194
|
+
- !ruby/object:Gem::Version
|
|
195
|
+
version: '0'
|
|
196
|
+
description: Private pub/sub messaging in Rails through Faye. More Faye features supported.
|
|
197
|
+
Based on PrivatePub.
|
|
198
|
+
email:
|
|
199
|
+
- alex@simonov.me
|
|
200
|
+
- mail@dmitryzuev.com
|
|
201
|
+
executables: []
|
|
202
|
+
extensions: []
|
|
203
|
+
extra_rdoc_files: []
|
|
204
|
+
files:
|
|
205
|
+
- ".gitignore"
|
|
206
|
+
- ".rspec"
|
|
207
|
+
- ".rubocop.yml"
|
|
208
|
+
- ".travis.yml"
|
|
209
|
+
- CHANGELOG.md
|
|
210
|
+
- Gemfile
|
|
211
|
+
- Guardfile
|
|
212
|
+
- LICENSE
|
|
213
|
+
- README.md
|
|
214
|
+
- Rakefile
|
|
215
|
+
- app/assets/javascripts/danthes.js.coffee
|
|
216
|
+
- defaults.reek
|
|
217
|
+
- edmond-danthes.gemspec
|
|
218
|
+
- lib/danthes.rb
|
|
219
|
+
- lib/danthes/engine.rb
|
|
220
|
+
- lib/danthes/faye_extension.rb
|
|
221
|
+
- lib/danthes/version.rb
|
|
222
|
+
- lib/danthes/view_helpers.rb
|
|
223
|
+
- lib/generators/danthes/install_generator.rb
|
|
224
|
+
- lib/generators/danthes/redis_install_generator.rb
|
|
225
|
+
- lib/generators/danthes_generator.rb
|
|
226
|
+
- lib/generators/templates/danthes.ru
|
|
227
|
+
- lib/generators/templates/danthes.yml
|
|
228
|
+
- lib/generators/templates/danthes_redis.yml
|
|
229
|
+
- spec/coffeescripts/danthesSpec.js.coffee
|
|
230
|
+
- spec/danthes/faye_extension_spec.rb
|
|
231
|
+
- spec/danthes/view_helpers_spec.rb
|
|
232
|
+
- spec/danthes_spec.rb
|
|
233
|
+
- spec/fake_app/rails_app.rb
|
|
234
|
+
- spec/fixtures/danthes.yml
|
|
235
|
+
- spec/fixtures/danthes_redis.yml
|
|
236
|
+
- spec/fixtures/danthes_with_erb.yml
|
|
237
|
+
- spec/javascripts/support/jasmine.yml
|
|
238
|
+
- spec/javascripts/support/jasmine_helper.rb
|
|
239
|
+
- spec/spec_helper.rb
|
|
240
|
+
homepage: https://github.com/dmitryzuev/edmond-danthes
|
|
241
|
+
licenses: []
|
|
242
|
+
metadata: {}
|
|
243
|
+
post_install_message:
|
|
244
|
+
rdoc_options: []
|
|
245
|
+
require_paths:
|
|
246
|
+
- lib
|
|
247
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
248
|
+
requirements:
|
|
249
|
+
- - ">="
|
|
250
|
+
- !ruby/object:Gem::Version
|
|
251
|
+
version: '0'
|
|
252
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
253
|
+
requirements:
|
|
254
|
+
- - ">="
|
|
255
|
+
- !ruby/object:Gem::Version
|
|
256
|
+
version: '0'
|
|
257
|
+
requirements: []
|
|
258
|
+
rubyforge_project:
|
|
259
|
+
rubygems_version: 2.7.7
|
|
260
|
+
signing_key:
|
|
261
|
+
specification_version: 4
|
|
262
|
+
summary: Private pub/sub messaging through Faye.
|
|
263
|
+
test_files:
|
|
264
|
+
- spec/coffeescripts/danthesSpec.js.coffee
|
|
265
|
+
- spec/danthes/faye_extension_spec.rb
|
|
266
|
+
- spec/danthes/view_helpers_spec.rb
|
|
267
|
+
- spec/danthes_spec.rb
|
|
268
|
+
- spec/fake_app/rails_app.rb
|
|
269
|
+
- spec/fixtures/danthes.yml
|
|
270
|
+
- spec/fixtures/danthes_redis.yml
|
|
271
|
+
- spec/fixtures/danthes_with_erb.yml
|
|
272
|
+
- spec/javascripts/support/jasmine.yml
|
|
273
|
+
- spec/javascripts/support/jasmine_helper.rb
|
|
274
|
+
- spec/spec_helper.rb
|