cottontail 0.1.5 → 2.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Cottontail::Consumer::Collection do
4
+ let(:collection) { described_class.new }
5
+
6
+ context 'find for single entity' do
7
+ it 'returns correctly for :exchange, :queue, :route' do
8
+ entity = push_entity('a', 'b', 'c')
9
+
10
+ expect(collection.find(delivery_info_stub('a', 'b', 'c'))).to eq(entity)
11
+ expect(collection.find(delivery_info_stub('a', 'b', 'x'))).to be_nil
12
+ expect(collection.find(delivery_info_stub('a', 'x', 'x'))).to be_nil
13
+ expect(collection.find(delivery_info_stub('x', 'x', 'x'))).to be_nil
14
+ end
15
+
16
+ it 'returns correctly for :exchange, :queue, nil' do
17
+ entity = push_entity('a', 'b', nil)
18
+
19
+ expect(collection.find(delivery_info_stub('a', 'b', 'c'))).to eq(entity)
20
+ expect(collection.find(delivery_info_stub('a', 'b', 'x'))).to eq(entity)
21
+ expect(collection.find(delivery_info_stub('a', 'x', 'x'))).to be_nil
22
+ expect(collection.find(delivery_info_stub('x', 'x', 'x'))).to be_nil
23
+ end
24
+
25
+ it 'returns correctly for :exchange, nil, nil' do
26
+ entity = push_entity('a', nil, nil)
27
+
28
+ expect(collection.find(delivery_info_stub('a', 'b', 'c'))).to eq(entity)
29
+ expect(collection.find(delivery_info_stub('a', 'b', 'x'))).to eq(entity)
30
+ expect(collection.find(delivery_info_stub('a', 'x', 'x'))).to eq(entity)
31
+ expect(collection.find(delivery_info_stub('x', 'x', 'x'))).to be_nil
32
+ end
33
+
34
+ it 'returns correctly for nil, nil, nil' do
35
+ entity = push_entity(nil, nil, nil)
36
+
37
+ expect(collection.find(delivery_info_stub('a', 'b', 'c'))).to eq(entity)
38
+ expect(collection.find(delivery_info_stub('a', 'b', 'x'))).to eq(entity)
39
+ expect(collection.find(delivery_info_stub('a', 'x', 'x'))).to eq(entity)
40
+ expect(collection.find(delivery_info_stub('x', 'x', 'x'))).to eq(entity)
41
+ end
42
+ end
43
+
44
+ context 'find for multiple entities' do
45
+ let!(:nnn) { push_entity(nil, nil, nil) }
46
+ let!(:ann) { push_entity('a', nil, nil) }
47
+ let!(:abn) { push_entity('a', 'b', nil) }
48
+ let!(:abc) { push_entity('a', 'b', 'c') }
49
+
50
+ it 'returns correctly for :exchange, :queue, :route' do
51
+ expect(collection.find(delivery_info_stub('a', 'b', 'c'))).to eq(abc)
52
+ expect(collection.find(delivery_info_stub('a', 'b', 'x'))).to eq(abn)
53
+ expect(collection.find(delivery_info_stub('a', 'x', 'x'))).to eq(ann)
54
+ expect(collection.find(delivery_info_stub('x', 'x', 'x'))).to eq(nnn)
55
+ end
56
+ end
57
+
58
+ context 'find for multiple entities (mixed)' do
59
+ let!(:ann) { push_entity('a', nil, nil) }
60
+ let!(:nan) { push_entity(nil, 'a', nil) }
61
+ let!(:nna) { push_entity(nil, nil, 'a') }
62
+
63
+ it 'returns correctly for :exchange, :queue, :route' do
64
+ expect(collection.find(delivery_info_stub('a', 'x', 'x'))).to eq(ann)
65
+ expect(collection.find(delivery_info_stub('x', 'a', 'x'))).to eq(nan)
66
+ expect(collection.find(delivery_info_stub('x', 'x', 'a'))).to eq(nna)
67
+ expect(collection.find(delivery_info_stub('x', 'x', 'x'))).to eq(nil)
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def push_entity(exchange = nil, queue = nil, route = nil)
74
+ entity = Cottontail::Consumer::Entity.new(
75
+ exchange: exchange,
76
+ queue: queue,
77
+ route: route
78
+ )
79
+ collection.push(entity)
80
+ entity
81
+ end
82
+
83
+ def delivery_info_stub(exchange = '', queue = '', route = '')
84
+ JSON.parse(
85
+ {
86
+ exchange: exchange,
87
+ consumer: {
88
+ queue: { name: queue }
89
+ },
90
+ routing_key: route
91
+ }.to_json,
92
+ object_class: OpenStruct
93
+ )
94
+ end
95
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.shared_examples_for 'a matching property' do
4
+ it 'returns correctly for String' do
5
+ entity = described_class.new(subject => 'a')
6
+
7
+ expect(entity.matches?(subject, 'a')).to eq(true)
8
+ expect(entity.matches?(subject, 'x')).to eq(false)
9
+ expect(entity.matches?(subject, nil)).to eq(false)
10
+ expect(entity.matches?(subject, :any)).to eq(false)
11
+ end
12
+
13
+ it 'returns correctly for nil' do
14
+ entity = described_class.new(subject => nil)
15
+
16
+ expect(entity.matches?(subject, 'a')).to eq(true)
17
+ expect(entity.matches?(subject, 'x')).to eq(true)
18
+ expect(entity.matches?(subject, nil)).to eq(true)
19
+ expect(entity.matches?(subject, :any)).to eq(true)
20
+ end
21
+
22
+ it 'returns correctly for blank' do
23
+ entity = described_class.new(subject => '')
24
+
25
+ expect(entity.matches?(subject, 'a')).to eq(false)
26
+ expect(entity.matches?(subject, 'x')).to eq(false)
27
+ expect(entity.matches?(subject, nil)).to eq(false)
28
+ expect(entity.matches?(subject, :any)).to eq(false)
29
+ end
30
+
31
+ it 'returns correctly for :any' do
32
+ entity = described_class.new(subject => :any)
33
+
34
+ expect(entity.matches?(subject, 'a')).to eq(true)
35
+ expect(entity.matches?(subject, 'x')).to eq(true)
36
+ expect(entity.matches?(subject, nil)).to eq(true)
37
+ expect(entity.matches?(subject, :any)).to eq(true)
38
+ end
39
+ end
40
+
41
+ RSpec.describe Cottontail::Consumer::Entity do
42
+ context 'comparison' do
43
+ let(:entity) { described_class.new }
44
+
45
+ it 'is equal' do
46
+ other = described_class.new
47
+
48
+ expect(entity < other).to eq(false)
49
+ expect(entity == other).to eq(true)
50
+ expect(entity > other).to eq(false)
51
+ end
52
+
53
+ it 'is greater (exchange)' do
54
+ other = described_class.new(exchange: 'exchange')
55
+
56
+ expect(entity < other).to eq(false)
57
+ expect(entity == other).to eq(false)
58
+ expect(entity > other).to eq(true)
59
+ end
60
+
61
+ it 'is greater (queue)' do
62
+ other = described_class.new(queue: 'queue')
63
+
64
+ expect(entity < other).to eq(false)
65
+ expect(entity == other).to eq(false)
66
+ expect(entity > other).to eq(true)
67
+ end
68
+
69
+ it 'is greater (route)' do
70
+ other = described_class.new(route: 'route')
71
+
72
+ expect(entity < other).to eq(false)
73
+ expect(entity == other).to eq(false)
74
+ expect(entity > other).to eq(true)
75
+ end
76
+ end
77
+
78
+ context 'comparison (more complex)' do
79
+ let(:aaa) { described_class.new(exchange: 'a', queue: 'a', route: 'a') }
80
+ let(:bbb) { described_class.new(exchange: 'b', queue: 'b', route: 'b') }
81
+ let(:bab) { described_class.new(exchange: 'b', queue: 'a', route: 'b') }
82
+ let(:bba) { described_class.new(exchange: 'b', queue: 'b', route: 'a') }
83
+
84
+ let(:entities) { [bbb, bba, bab, aaa] }
85
+ let(:sorted_entities) { [aaa, bab, bba, bbb] }
86
+
87
+ it 'sorts correctly' do
88
+ expect(entities.sort).to eq(sorted_entities)
89
+ end
90
+ end
91
+
92
+ context 'comparison with nil' do
93
+ let(:nnn) { described_class.new(exchange: nil, queue: nil, route: nil) }
94
+ let(:ann) { described_class.new(exchange: 'a', queue: nil, route: nil) }
95
+ let(:aan) { described_class.new(exchange: 'a', queue: 'a', route: nil) }
96
+ let(:aaa) { described_class.new(exchange: 'a', queue: 'a', route: 'a') }
97
+
98
+ let(:entities) { [nnn, ann, aan, aaa] }
99
+ let(:sorted_entities) { [aaa, aan, ann, nnn] }
100
+
101
+ it 'sorts correctly' do
102
+ expect(entities.sort).to eq(sorted_entities)
103
+ end
104
+ end
105
+
106
+ context 'matching for :exchange' do
107
+ subject { :exchange }
108
+ it_behaves_like 'a matching property'
109
+ end
110
+
111
+ context 'matching for :queue' do
112
+ subject { :queue }
113
+ it_behaves_like 'a matching property'
114
+ end
115
+
116
+ context 'matching for :queue' do
117
+ subject { :route }
118
+ it_behaves_like 'a matching property'
119
+ end
120
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'A Cottontail::Consumer instance' do
4
+ pending 'RabbitMQ not running' unless rabbitmq_running?
5
+
6
+ let(:rand) { SecureRandom.uuid }
7
+ let(:topic) { "cottontail-test-#{rand}" }
8
+ let(:queue) { "cottontail-test-#{rand}" }
9
+ let(:payload) { 'hello world' }
10
+
11
+ let :consumer do
12
+ CottontailTestConsumer.new(topic, queue)
13
+ end
14
+ let(:consumable) { consumer.consumable }
15
+
16
+ let :publisher do
17
+ session = Bunny.new
18
+ session.start
19
+ session
20
+ end
21
+
22
+ before do
23
+ # start consumer
24
+ consumer.start(false)
25
+
26
+ # publish message
27
+ channel = publisher.create_channel
28
+ channel.topic(topic)
29
+ .publish(payload, routing_key: 'cottontail-spec')
30
+ end
31
+
32
+ after do
33
+ publisher.stop
34
+ consumer.stop
35
+ end
36
+
37
+ it 'consumes the message' do
38
+ 5.times { sleep 0.1 if consumable.payload.nil? }
39
+ expect(consumable.payload).to eq(payload)
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ $LOAD_PATH.unshift File.expand_path('..', __FILE__)
2
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
+
4
+ require 'cottontail'
5
+
6
+ require 'json'
7
+ require 'byebug'
8
+ require 'securerandom'
9
+ require 'rspec/core'
10
+ require 'rspec/expectations'
11
+
12
+ Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }
13
+
14
+ RSpec.configure do |config|
15
+ config.expect_with :rspec do |expectations|
16
+ # This option will default to `true` in RSpec 4. It makes the `description`
17
+ # and `failure_message` of custom matchers include text for helper methods
18
+ # defined using `chain`, e.g.:
19
+ # be_bigger_than(2).and_smaller_than(4).description
20
+ # # => "be bigger than 2 and smaller than 4"
21
+ # ...rather than:
22
+ # # => "be bigger than 2"
23
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
24
+ end
25
+
26
+ # Limits the available syntax to the non-monkey patched syntax that is
27
+ # recommended. For more details, see:
28
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
29
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
30
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
31
+ config.disable_monkey_patching!
32
+
33
+ # Print the 5 slowest examples and example groups at the end of the spec run,
34
+ # to help surface which specs are running particularly slow.
35
+ config.profile_examples = 5
36
+
37
+ # Run specs in random order to surface order dependencies. If you find an
38
+ # order dependency and want to debug it, you can fix the order by providing
39
+ # the seed, which is printed after each run.
40
+ # --seed 1234
41
+ config.order = :random
42
+ end
@@ -0,0 +1,16 @@
1
+ begin
2
+ require 'coveralls'
3
+ require 'simplecov'
4
+
5
+ $stdout.puts 'Running coverage...'
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
+ end
14
+ rescue LoadError
15
+ $stderr.puts 'Not running coverage'
16
+ end
@@ -0,0 +1,14 @@
1
+ # check if RabbitMQ is running
2
+ def rabbitmq_running?
3
+ session = Bunny.new(ENV['RABBITMQ_URL'])
4
+
5
+ begin
6
+ session.start
7
+
8
+ return true
9
+ rescue Bunny::TCPConnectionFailedForAllHosts
10
+ return false
11
+ ensure
12
+ session.stop
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ class CottontailTestConsumer
2
+ include Cottontail::Consumer
3
+
4
+ set :logger, -> { Yell.new(:null) } # no logging
5
+ attr_accessor :consumable
6
+
7
+ def initialize(topic = 'cottontail-test-topic', queue = 'cottontail-test-queue')
8
+ super()
9
+
10
+ @consumable = OpenStruct.new
11
+ @topic = topic
12
+ @queue = queue
13
+ end
14
+
15
+ session do |worker, session|
16
+ channel = session.create_channel
17
+
18
+ exchange = channel.topic(@topic)
19
+ queue = channel.queue(@queue, :auto_delete => true, :durable => false)
20
+ .bind(exchange, routing_key: '#')
21
+
22
+ worker.subscribe(queue, exclusive: true)
23
+ end
24
+
25
+ consume do |delivery_info, properties, payload|
26
+ consumable.delivery_info = delivery_info
27
+ consumable.properties = properties
28
+ consumable.payload = payload
29
+ end
30
+ end
31
+
32
+
metadata CHANGED
@@ -1,72 +1,131 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: cottontail
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.1.5
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0.pre.1
6
5
  platform: ruby
7
- authors:
8
- - Rudolf Schmidt
6
+ authors:
7
+ - Rudolf Schmidt
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
-
13
- date: 2012-03-19 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: bunny
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
19
- none: false
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
24
- type: :runtime
25
- version_requirements: *id001
26
- description: Convenience wrapper around the AMQP Bunny gem to better handle routing_key specific messages
11
+ date: 2015-11-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bunny
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: yell
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '2'
34
+ - - "<="
35
+ - !ruby/object:Gem::Version
36
+ version: '3'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '2'
44
+ - - "<="
45
+ - !ruby/object:Gem::Version
46
+ version: '3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: activesupport
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '3'
54
+ - - "<="
55
+ - !ruby/object:Gem::Version
56
+ version: '4'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '3'
64
+ - - "<="
65
+ - !ruby/object:Gem::Version
66
+ version: '4'
67
+ description: Convenience wrapper around the AMQP Bunny gem to better handle routing_key
68
+ specific messages
27
69
  email:
28
70
  executables: []
29
-
30
71
  extensions: []
31
-
32
72
  extra_rdoc_files: []
33
-
34
- files:
35
- - .gitignore
36
- - Gemfile
37
- - LICENSE.txt
38
- - README.md
39
- - Rakefile
40
- - cottontail.gemspec
41
- - lib/cottontail.rb
42
- - lib/cottontail/version.rb
73
+ files:
74
+ - ".gitignore"
75
+ - ".rubocop.yml"
76
+ - ".travis.yml"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - cottontail.gemspec
82
+ - lib/cottontail.rb
83
+ - lib/cottontail/configurable.rb
84
+ - lib/cottontail/consumer.rb
85
+ - lib/cottontail/consumer/collection.rb
86
+ - lib/cottontail/consumer/entity.rb
87
+ - lib/cottontail/consumer/launcher.rb
88
+ - lib/cottontail/consumer/session.rb
89
+ - lib/cottontail/version.rb
90
+ - spec/cottontail/configurable_spec.rb
91
+ - spec/cottontail/consumer/collection_spec.rb
92
+ - spec/cottontail/consumer/entity_spec.rb
93
+ - spec/integration/consumer_simple_spec.rb
94
+ - spec/spec_helper.rb
95
+ - spec/support/coverage.rb
96
+ - spec/support/rabbitmq.rb
97
+ - spec/support/test_consumer.rb
43
98
  homepage: http://github.com/rudionrails/cottontail
44
- licenses: []
45
-
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
46
102
  post_install_message:
47
103
  rdoc_options: []
48
-
49
- require_paths:
50
- - lib
51
- required_ruby_version: !ruby/object:Gem::Requirement
52
- none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: "0"
57
- required_rubygems_version: !ruby/object:Gem::Requirement
58
- none: false
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: "0"
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">"
114
+ - !ruby/object:Gem::Version
115
+ version: 1.3.1
63
116
  requirements: []
64
-
65
117
  rubyforge_project: cottontail
66
- rubygems_version: 1.8.9
118
+ rubygems_version: 2.4.5.1
67
119
  signing_key:
68
- specification_version: 3
120
+ specification_version: 4
69
121
  summary: Sinatra inspired wrapper around the AMQP Bunny gem
70
- test_files: []
71
-
122
+ test_files:
123
+ - spec/cottontail/configurable_spec.rb
124
+ - spec/cottontail/consumer/collection_spec.rb
125
+ - spec/cottontail/consumer/entity_spec.rb
126
+ - spec/integration/consumer_simple_spec.rb
127
+ - spec/spec_helper.rb
128
+ - spec/support/coverage.rb
129
+ - spec/support/rabbitmq.rb
130
+ - spec/support/test_consumer.rb
72
131
  has_rdoc: