ably 0.1.6 → 0.2.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 +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +9 -0
- data/LICENSE.txt +1 -1
- data/README.md +8 -1
- data/Rakefile +10 -0
- data/ably.gemspec +18 -18
- data/lib/ably.rb +6 -5
- data/lib/ably/auth.rb +11 -14
- data/lib/ably/exceptions.rb +18 -15
- data/lib/ably/logger.rb +102 -0
- data/lib/ably/models/error_info.rb +1 -1
- data/lib/ably/models/message.rb +19 -5
- data/lib/ably/models/message_encoders/base.rb +107 -0
- data/lib/ably/models/message_encoders/base64.rb +39 -0
- data/lib/ably/models/message_encoders/cipher.rb +80 -0
- data/lib/ably/models/message_encoders/json.rb +33 -0
- data/lib/ably/models/message_encoders/utf8.rb +33 -0
- data/lib/ably/models/paginated_resource.rb +23 -6
- data/lib/ably/models/presence_message.rb +19 -7
- data/lib/ably/models/protocol_message.rb +5 -4
- data/lib/ably/models/token.rb +2 -2
- data/lib/ably/modules/channels_collection.rb +0 -3
- data/lib/ably/modules/conversions.rb +3 -3
- data/lib/ably/modules/encodeable.rb +68 -0
- data/lib/ably/modules/event_emitter.rb +10 -4
- data/lib/ably/modules/event_machine_helpers.rb +6 -4
- data/lib/ably/modules/http_helpers.rb +7 -2
- data/lib/ably/modules/model_common.rb +2 -0
- data/lib/ably/modules/state_emitter.rb +10 -1
- data/lib/ably/realtime.rb +19 -12
- data/lib/ably/realtime/channel.rb +26 -13
- data/lib/ably/realtime/client.rb +31 -7
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -3
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +13 -4
- data/lib/ably/realtime/connection.rb +152 -46
- data/lib/ably/realtime/connection/connection_manager.rb +168 -0
- data/lib/ably/realtime/connection/connection_state_machine.rb +56 -33
- data/lib/ably/realtime/connection/websocket_transport.rb +56 -29
- data/lib/ably/{models → realtime/models}/nil_channel.rb +1 -1
- data/lib/ably/realtime/presence.rb +38 -13
- data/lib/ably/rest.rb +7 -5
- data/lib/ably/rest/channel.rb +24 -3
- data/lib/ably/rest/client.rb +56 -17
- data/lib/ably/rest/middleware/encoder.rb +49 -0
- data/lib/ably/rest/middleware/exceptions.rb +3 -2
- data/lib/ably/rest/middleware/logger.rb +37 -0
- data/lib/ably/rest/presence.rb +10 -2
- data/lib/ably/util/crypto.rb +57 -29
- data/lib/ably/util/pub_sub.rb +11 -0
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/channel_spec.rb +65 -7
- data/spec/acceptance/realtime/connection_spec.rb +123 -27
- data/spec/acceptance/realtime/message_spec.rb +319 -34
- data/spec/acceptance/realtime/presence_history_spec.rb +58 -0
- data/spec/acceptance/realtime/presence_spec.rb +160 -18
- data/spec/acceptance/rest/auth_spec.rb +93 -49
- data/spec/acceptance/rest/base_spec.rb +10 -10
- data/spec/acceptance/rest/channel_spec.rb +35 -19
- data/spec/acceptance/rest/channels_spec.rb +8 -8
- data/spec/acceptance/rest/message_spec.rb +224 -0
- data/spec/acceptance/rest/presence_spec.rb +159 -23
- data/spec/acceptance/rest/stats_spec.rb +5 -5
- data/spec/acceptance/rest/time_spec.rb +4 -4
- data/spec/integration/rest/auth.rb +1 -1
- data/spec/resources/crypto-data-128.json +56 -0
- data/spec/resources/crypto-data-256.json +56 -0
- data/spec/rspec_config.rb +39 -0
- data/spec/spec_helper.rb +4 -42
- data/spec/support/api_helper.rb +1 -1
- data/spec/support/event_machine_helper.rb +0 -5
- data/spec/support/protocol_msgbus_helper.rb +3 -3
- data/spec/support/test_app.rb +3 -3
- data/spec/unit/logger_spec.rb +135 -0
- data/spec/unit/models/message_encoders/base64_spec.rb +181 -0
- data/spec/unit/models/message_encoders/cipher_spec.rb +260 -0
- data/spec/unit/models/message_encoders/json_spec.rb +135 -0
- data/spec/unit/models/message_encoders/utf8_spec.rb +100 -0
- data/spec/unit/models/message_spec.rb +16 -1
- data/spec/unit/models/paginated_resource_spec.rb +46 -0
- data/spec/unit/models/presence_message_spec.rb +18 -5
- data/spec/unit/models/token_spec.rb +1 -1
- data/spec/unit/modules/event_emitter_spec.rb +24 -10
- data/spec/unit/realtime/channel_spec.rb +3 -3
- data/spec/unit/realtime/channels_spec.rb +1 -1
- data/spec/unit/realtime/client_spec.rb +44 -2
- data/spec/unit/realtime/connection_spec.rb +2 -2
- data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +4 -4
- data/spec/unit/realtime/presence_spec.rb +1 -1
- data/spec/unit/realtime/realtime_spec.rb +3 -3
- data/spec/unit/realtime/websocket_transport_spec.rb +24 -0
- data/spec/unit/rest/channels_spec.rb +1 -1
- data/spec/unit/rest/client_spec.rb +45 -10
- data/spec/unit/util/crypto_spec.rb +82 -0
- data/spec/unit/{modules → util}/pub_sub_spec.rb +13 -1
- metadata +43 -12
- data/spec/acceptance/crypto.rb +0 -63
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'securerandom'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe 'Ably::Rest Stats' do
|
5
5
|
[:json, :msgpack].each do |protocol|
|
6
6
|
context "over #{protocol}" do
|
7
|
-
describe
|
7
|
+
describe 'fetching application stats' do
|
8
8
|
before(:context) do
|
9
9
|
reload_test_app
|
10
10
|
end
|
@@ -40,7 +40,7 @@ describe "REST" do
|
|
40
40
|
|
41
41
|
[:minute, :hour, :day, :month].each do |interval|
|
42
42
|
context "by #{interval}" do
|
43
|
-
it
|
43
|
+
it 'should return all the stats for the application' do
|
44
44
|
stats = @context_client.stats(start: @interval_start * 1000, by: interval.to_s, direction: 'forwards')
|
45
45
|
|
46
46
|
expect(stats.size).to eql(1)
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'securerandom'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe 'Ably::REST time' do
|
5
5
|
[:msgpack, :json].each do |protocol|
|
6
6
|
context "over #{protocol}" do
|
7
7
|
let(:client) do
|
8
8
|
Ably::Rest::Client.new(api_key: api_key, environment: environment, protocol: protocol)
|
9
9
|
end
|
10
10
|
|
11
|
-
describe
|
11
|
+
describe 'fetching the service time' do
|
12
12
|
it "should return the service time as a Time object" do
|
13
13
|
expect(client.time).to be_within(2).of(Time.now)
|
14
14
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Ably::Auth do
|
4
4
|
let(:client) { Ably::Rest::Client.new(key_id: 'id', key_secret: 'secret') }
|
5
5
|
|
6
|
-
it
|
6
|
+
it 'has immutable options' do
|
7
7
|
expect { client.auth.options['key_id'] = 'new_id' }.to raise_error RuntimeError, /can't modify frozen Hash/
|
8
8
|
end
|
9
9
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
{
|
2
|
+
"algorithm": "aes",
|
3
|
+
"mode": "cbc",
|
4
|
+
"keylength": 128,
|
5
|
+
"key": "WUP6u0K7MXI5Zeo0VppPwg==",
|
6
|
+
"iv": "HO4cYSP8LybPYBPZPHQOtg==",
|
7
|
+
"items": [
|
8
|
+
{
|
9
|
+
"encoded": {
|
10
|
+
"name": "example",
|
11
|
+
"data": "The quick brown fox jumped over the lazy dog"
|
12
|
+
},
|
13
|
+
"encrypted": {
|
14
|
+
"name": "example",
|
15
|
+
"data": "HO4cYSP8LybPYBPZPHQOtmHItcxYdSvcNUC6kXVpMn0VFL+9z2/5tJ6WFbR0SBT1xhFRuJ+MeBGTU3yOY9P5ow==",
|
16
|
+
"encoding": "utf-8/cipher+aes-128-cbc/base64"
|
17
|
+
}
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"encoded": {
|
21
|
+
"name": "example",
|
22
|
+
"data": "AAECAwQFBgcICQoLDA0ODw==",
|
23
|
+
"encoding": "base64"
|
24
|
+
},
|
25
|
+
"encrypted": {
|
26
|
+
"name": "example",
|
27
|
+
"data": "HO4cYSP8LybPYBPZPHQOtuB3dfKG08yw7J4qx3kkjxdW0eoZv+nGAp76OKqYQ327",
|
28
|
+
"encoding": "cipher+aes-128-cbc/base64"
|
29
|
+
}
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"encoded": {
|
33
|
+
"name": "example",
|
34
|
+
"data": "{\"example\":{\"json\":\"Object\"}}",
|
35
|
+
"encoding": "json"
|
36
|
+
},
|
37
|
+
"encrypted": {
|
38
|
+
"name": "example",
|
39
|
+
"data": "HO4cYSP8LybPYBPZPHQOtuD53yrD3YV3NBoTEYBh4U0N1QXHbtkfsDfTspKeLQFt",
|
40
|
+
"encoding": "json/utf-8/cipher+aes-128-cbc/base64"
|
41
|
+
}
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"encoded": {
|
45
|
+
"name": "example",
|
46
|
+
"data": "[\"example\",\"json\",\"array\"]",
|
47
|
+
"encoding": "json"
|
48
|
+
},
|
49
|
+
"encrypted": {
|
50
|
+
"name": "example",
|
51
|
+
"data": "HO4cYSP8LybPYBPZPHQOtvmStzmExkdjvrn51J6cmaTZrGl+EsJ61sgxmZ6j6jcA",
|
52
|
+
"encoding": "json/utf-8/cipher+aes-128-cbc/base64"
|
53
|
+
}
|
54
|
+
}
|
55
|
+
]
|
56
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
{
|
2
|
+
"algorithm": "aes",
|
3
|
+
"mode": "cbc",
|
4
|
+
"keylength": 256,
|
5
|
+
"key": "o9qXZoPGDNla50VnRwH7cGqIrpyagTxGsRgimKJbY40=",
|
6
|
+
"iv": "NMDl1Acnel8HVdu1cEWdrw==",
|
7
|
+
"items": [
|
8
|
+
{
|
9
|
+
"encoded": {
|
10
|
+
"name": "example",
|
11
|
+
"data": "The quick brown fox jumped over the lazy dog"
|
12
|
+
},
|
13
|
+
"encrypted": {
|
14
|
+
"name": "example",
|
15
|
+
"data": "NMDl1Acnel8HVdu1cEWdr9CGPYFoBoLgJCzoybbQbnyfwx3UQ8CGuKyP/g56Za/JB3xW6XGkNzrHYvZwad4fvA==",
|
16
|
+
"encoding": "utf-8/cipher+aes-256-cbc/base64"
|
17
|
+
}
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"encoded": {
|
21
|
+
"name": "example",
|
22
|
+
"data": "AAECAwQFBgcICQoLDA0ODw==",
|
23
|
+
"encoding": "base64"
|
24
|
+
},
|
25
|
+
"encrypted": {
|
26
|
+
"name": "example",
|
27
|
+
"data": "NMDl1Acnel8HVdu1cEWdr8UFEi56Ms0zPHszbppM61BC8Yf6ndq+kiCj9xXW97/O",
|
28
|
+
"encoding": "cipher+aes-256-cbc/base64"
|
29
|
+
}
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"encoded": {
|
33
|
+
"name": "example",
|
34
|
+
"data": "{\"example\":{\"json\":\"Object\"}}",
|
35
|
+
"encoding": "json"
|
36
|
+
},
|
37
|
+
"encrypted": {
|
38
|
+
"name": "example",
|
39
|
+
"data": "NMDl1Acnel8HVdu1cEWdr21pS5//hdtQf3QqQzZM/jWAtn09Vh52E6jMdC3mWS98",
|
40
|
+
"encoding": "json/utf-8/cipher+aes-256-cbc/base64"
|
41
|
+
}
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"encoded": {
|
45
|
+
"name": "example",
|
46
|
+
"data": "[\"example\",\"json\",\"array\"]",
|
47
|
+
"encoding": "json"
|
48
|
+
},
|
49
|
+
"encrypted": {
|
50
|
+
"name": "example",
|
51
|
+
"data": "NMDl1Acnel8HVdu1cEWdr4J5sVAFpnXsz0fTtsuwOaTRU+6P5GaWlNjePWwiOZCQ",
|
52
|
+
"encoding": "json/utf-8/cipher+aes-256-cbc/base64"
|
53
|
+
}
|
54
|
+
}
|
55
|
+
]
|
56
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
config.mock_with :rspec do |mocks|
|
13
|
+
# This option should be set when all dependencies are being loaded
|
14
|
+
# before a spec run, as is the case in a typical spec helper. It will
|
15
|
+
# cause any verifying double instantiation for a class that does not
|
16
|
+
# exist to raise, protecting against incorrectly spelt names.
|
17
|
+
mocks.verify_doubled_constant_names = true
|
18
|
+
end
|
19
|
+
|
20
|
+
# Run specs in random order to surface order dependencies. If you find an
|
21
|
+
# order dependency and want to debug it, you can fix the order by providing
|
22
|
+
# the seed, which is printed after each run.
|
23
|
+
# --seed 1234
|
24
|
+
config.order = 'random'
|
25
|
+
|
26
|
+
config.before(:example) do
|
27
|
+
WebMock.disable!
|
28
|
+
end
|
29
|
+
|
30
|
+
config.before(:example, :webmock => true) do
|
31
|
+
allow(TestApp).to receive(:instance).and_return(instance_double('TestApp',
|
32
|
+
app_id: 'app_id',
|
33
|
+
key_id: 'app_id.key_id',
|
34
|
+
api_key: 'app_id.key_id:secret',
|
35
|
+
environment: 'sandbox'
|
36
|
+
))
|
37
|
+
WebMock.enable!
|
38
|
+
end
|
39
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,46 +1,8 @@
|
|
1
|
-
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
-
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
-
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
-
# loaded once.
|
5
|
-
#
|
6
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
-
|
8
1
|
require 'webmock/rspec'
|
9
2
|
|
10
|
-
require
|
11
|
-
|
12
|
-
require "support/api_helper"
|
13
|
-
require "support/event_machine_helper"
|
14
|
-
|
15
|
-
RSpec.configure do |config|
|
16
|
-
config.run_all_when_everything_filtered = true
|
17
|
-
config.filter_run :focus
|
18
|
-
|
19
|
-
config.mock_with :rspec do |mocks|
|
20
|
-
# This option should be set when all dependencies are being loaded
|
21
|
-
# before a spec run, as is the case in a typical spec helper. It will
|
22
|
-
# cause any verifying double instantiation for a class that does not
|
23
|
-
# exist to raise, protecting against incorrectly spelt names.
|
24
|
-
mocks.verify_doubled_constant_names = true
|
25
|
-
end
|
26
|
-
|
27
|
-
# Run specs in random order to surface order dependencies. If you find an
|
28
|
-
# order dependency and want to debug it, you can fix the order by providing
|
29
|
-
# the seed, which is printed after each run.
|
30
|
-
# --seed 1234
|
31
|
-
config.order = 'random'
|
3
|
+
require 'ably'
|
32
4
|
|
33
|
-
|
34
|
-
|
35
|
-
end
|
5
|
+
require 'support/api_helper'
|
6
|
+
require 'support/event_machine_helper'
|
36
7
|
|
37
|
-
|
38
|
-
allow(TestApp).to receive(:instance).and_return(instance_double('TestApp',
|
39
|
-
app_id: 'app_id',
|
40
|
-
key_id: 'app_id.key_id',
|
41
|
-
api_key: 'app_id.key_id:secret',
|
42
|
-
environment: 'sandbox'
|
43
|
-
))
|
44
|
-
WebMock.enable!
|
45
|
-
end
|
46
|
-
end
|
8
|
+
require 'rspec_config'
|
data/spec/support/api_helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
shared_examples 'a protocol message bus' do
|
2
2
|
describe '__protocol_msgbus__ PubSub' do
|
3
|
-
let(:
|
3
|
+
let(:protocol_message) do
|
4
4
|
Ably::Models::ProtocolMessage.new(
|
5
5
|
action: 15,
|
6
6
|
channel: 'channel',
|
@@ -11,8 +11,8 @@ shared_examples 'a protocol message bus' do
|
|
11
11
|
|
12
12
|
specify 'supports valid ProtocolMessage messages' do
|
13
13
|
received = 0
|
14
|
-
msgbus.subscribe(:
|
15
|
-
expect { msgbus.publish(:
|
14
|
+
msgbus.subscribe(:protocol_message) { received += 1 }
|
15
|
+
expect { msgbus.publish(:protocol_message, protocol_message) }.to change { received }.to(1)
|
16
16
|
end
|
17
17
|
|
18
18
|
specify 'fail with unacceptable STATE event names' do
|
data/spec/support/test_app.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'singleton'
|
2
2
|
|
3
3
|
class TestApp
|
4
4
|
APP_SPEC = {
|
@@ -81,8 +81,8 @@ class TestApp
|
|
81
81
|
url = "#{sandbox_client.endpoint}/apps"
|
82
82
|
|
83
83
|
headers = {
|
84
|
-
|
85
|
-
|
84
|
+
'Accept' => 'application/json',
|
85
|
+
'Content-Type' => 'application/json'
|
86
86
|
}
|
87
87
|
|
88
88
|
response = Faraday.post(url, APP_SPEC.to_json, headers)
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ably::Logger do
|
4
|
+
let(:new_client) do
|
5
|
+
instance_double('Ably::Realtime::Client', connection: instance_double('Ably::Realtime::Connection', id: nil))
|
6
|
+
end
|
7
|
+
let(:connected_client) do
|
8
|
+
instance_double('Ably::Realtime::Client', connection: instance_double('Ably::Realtime::Connection', id: '0000'))
|
9
|
+
end
|
10
|
+
let(:rest_client) do
|
11
|
+
instance_double('Ably::Rest::Client')
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { Ably::Logger.new(new_client, Logger::INFO) }
|
15
|
+
|
16
|
+
def uncolorize(string)
|
17
|
+
regex_pattern = /\033\[[0-9]+m(.+?)\033\[0m/m
|
18
|
+
string.gsub(regex_pattern, '\1')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'uses the Ruby Logger by default' do
|
22
|
+
expect(subject.logger).to be_a(Logger)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'delegates to the logger object' do
|
26
|
+
expect(subject.logger).to receive(:warn).with('message')
|
27
|
+
subject.warn 'message'
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'formatter' do
|
31
|
+
context 'when debugging' do
|
32
|
+
it 'uses short time format' do
|
33
|
+
formatted = subject.logger.formatter.call(Logger::DEBUG, Time.now, 'progid', 'unique_message')
|
34
|
+
formatted = uncolorize(formatted)
|
35
|
+
expect(formatted).to match(/^\d+:\d+:\d+.\d{3} DEBUG/)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when info -> fatal' do
|
40
|
+
it 'uses long time format' do
|
41
|
+
formatted = subject.logger.formatter.call(Logger::INFO, Time.now, 'progid', 'unique_message')
|
42
|
+
formatted = uncolorize(formatted)
|
43
|
+
expect(formatted).to match(/^\d+-\d+-\d+ \d+:\d+:\d+.\d{3} INFO/)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with Realtime disconnected client' do
|
48
|
+
subject { Ably::Logger.new(new_client, Logger::INFO) }
|
49
|
+
|
50
|
+
it 'formats logs with an empty client ID' do
|
51
|
+
formatted = subject.logger.formatter.call(Logger::DEBUG, Time.now, 'progid', 'unique_message')
|
52
|
+
formatted = uncolorize(formatted)
|
53
|
+
expect(formatted).to match(/\[ \-\- \]/)
|
54
|
+
expect(formatted).to match(%r{unique_message$})
|
55
|
+
expect(formatted).to match(%r{DEBUG})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with Realtime connected client' do
|
60
|
+
subject { Ably::Logger.new(connected_client, Logger::INFO) }
|
61
|
+
|
62
|
+
it 'formats logs with a client ID' do
|
63
|
+
formatted = subject.logger.formatter.call(Logger::DEBUG, Time.now, 'progid', 'unique_message')
|
64
|
+
formatted = uncolorize(formatted)
|
65
|
+
expect(formatted).to match(/\[0000]/)
|
66
|
+
expect(formatted).to match(%r{unique_message$})
|
67
|
+
expect(formatted).to match(%r{DEBUG})
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with REST client' do
|
72
|
+
subject { Ably::Logger.new(rest_client, Logger::INFO) }
|
73
|
+
|
74
|
+
it 'formats logs without a client ID' do
|
75
|
+
formatted = subject.logger.formatter.call(Logger::FATAL, Time.now, 'progid', 'unique_message')
|
76
|
+
formatted = uncolorize(formatted)
|
77
|
+
expect(formatted).to_not match(/\[.*\]/)
|
78
|
+
expect(formatted).to match(%r{unique_message$})
|
79
|
+
expect(formatted).to match(%r{FATAL})
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'severity argument' do
|
84
|
+
it 'can be an Integer' do
|
85
|
+
formatted = subject.logger.formatter.call(Logger::INFO, Time.now, 'progid', 'unique_message')
|
86
|
+
formatted = uncolorize(formatted)
|
87
|
+
expect(formatted).to match(/^\d+-\d+-\d+ \d+:\d+:\d+.\d{3} INFO/)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'can be a string' do
|
91
|
+
formatted = subject.logger.formatter.call('INFO', Time.now, 'progid', 'unique_message')
|
92
|
+
formatted = uncolorize(formatted)
|
93
|
+
expect(formatted).to match(/^\d+-\d+-\d+ \d+:\d+:\d+.\d{3} INFO/)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'with a custom Logger' do
|
99
|
+
context 'with an invalid interface' do
|
100
|
+
let(:custom_logger_with_bad_interface) do
|
101
|
+
Class.new.new
|
102
|
+
end
|
103
|
+
subject { Ably::Logger.new(new_client, Logger::INFO, custom_logger_with_bad_interface) }
|
104
|
+
|
105
|
+
it 'raises an exception' do
|
106
|
+
expect { subject }.to raise_error ArgumentError, /The custom Logger's interface does not provide the method/
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with a valid interface' do
|
111
|
+
let(:custom_logger) do
|
112
|
+
Class.new do
|
113
|
+
extend Forwardable
|
114
|
+
def initialize
|
115
|
+
@logger = Logger.new(STDOUT)
|
116
|
+
end
|
117
|
+
def_delegators :@logger, :fatal, :error, :warn, :info, :debug, :level, :level=
|
118
|
+
end
|
119
|
+
end
|
120
|
+
let(:custom_logger_object) { custom_logger.new }
|
121
|
+
|
122
|
+
subject { Ably::Logger.new(new_client, Logger::INFO, custom_logger_object) }
|
123
|
+
|
124
|
+
it 'is used' do
|
125
|
+
expect { subject }.to_not raise_error
|
126
|
+
expect(subject.logger.class).to eql(custom_logger)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'delegates log messages to logger' do
|
130
|
+
expect(custom_logger_object).to receive(:fatal).with('message')
|
131
|
+
subject.fatal 'message'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|