rspec-que 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c87929df7a2ab03510e1653ccb1ba7fa9ff111a2
4
+ data.tar.gz: 287d5af413397c3b36ee0f829bdedcef80516680
5
+ SHA512:
6
+ metadata.gz: 1dc9f76fa67c0d436178467558280eb4f8341022519e57a78f37aec92d15e8be246bc0c949205f89e22706d399466fe18cd6cc00dc94a6890cbec88276acb35a
7
+ data.tar.gz: b5d2acb3261a82ed8883d4318c97578fe39f45ae7df048250c24d881578239f816f613044a83f8fa233ab5b7a80e9254aeb8cc14ecfea5d1ea86ad0363549020
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015-2016 GOCARDLESS LTD
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # RSpec Que matchers
2
+
3
+ This gem defines a matcher for checking that Que jobs have been enqueued,
4
+ in the style of [rspec-activejob](https://github.com/gocardless/rspec-activejob).
5
+
6
+ ## Usage
7
+ The matcher expects a block of code, and will expect that code to enqueue a job
8
+ in Que. The matcher can take a class for the job as its arguments. It can also
9
+ expect the job to be queued with arguments via `.with(arg1, arg2)` or at a
10
+ specific time via `.at(time)`.
11
+
12
+ If the matcher does not match, it will display informations about jobs queued
13
+ at the last stage of the matcher which did match. (For instance, if you specify
14
+ a job class, arguments, and a time, the matcher will display information about
15
+ jobs of the right class and arguments but at the wrong time.)
16
+
17
+ ```ruby
18
+ # spec/spec_helper.rb
19
+ require 'rspec/que'
20
+
21
+ RSpec.configure do |config|
22
+ config.include(RSpec::Que)
23
+
24
+ # clean out the queue after each spec
25
+ config.after(:each) do
26
+ RSpec::Que.purge_jobs
27
+ end
28
+ end
29
+
30
+ # spec/controllers/my_controller_spec.rb
31
+ RSpec.describe MyController do
32
+ let(:user) { create(:user) }
33
+ let(:params) { { user_id: user.id } }
34
+ let(:later_time) { DateTime.parse("2038-01-01T01:02:03+00:00").utc }
35
+ subject(:make_request) { described_class.make_request(params) }
36
+
37
+ specify { expect { make_request }.to queue_up(RequestMaker).with(user) }
38
+ specify { expect { make_request }.to queue_up(DelayedRequest).at(later_time) }
39
+ end
40
+ ```
41
+
42
+ ## Development
43
+
44
+ Setup:
45
+ ``` shell
46
+ bundle install
47
+ ```
48
+
49
+ Run tests:
50
+
51
+ ``` shell
52
+ bundle exec rake
53
+
54
+ ```
data/lib/rspec/que.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'rspec/que/queue_up'
2
+
3
+ module RSpec
4
+ module Que
5
+ def queue_up(job_class)
6
+ Matchers::QueueUp.new(job_class)
7
+ end
8
+
9
+ def purge_jobs
10
+ ::Que.execute "DELETE FROM que_jobs"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,168 @@
1
+ require 'rspec/mocks/argument_list_matcher'
2
+ require 'time'
3
+
4
+ module RSpec
5
+ module Que
6
+ module Matchers
7
+ class QueueUp
8
+ include RSpec::Matchers::Composable
9
+
10
+ def initialize(job_class = nil)
11
+ @matchers = [QueuedSomething.new]
12
+ @matchers << QueuedClass.new(job_class) if job_class
13
+ @job_class = job_class
14
+ @stages = []
15
+ end
16
+
17
+ def matches?(block)
18
+ before_jobs = enqueued_jobs.dup
19
+ block.call
20
+
21
+ @matched_jobs = enqueued_jobs - before_jobs
22
+ @matchers.each do |matcher|
23
+ @stages << { matcher: matcher, candidates: @matched_jobs.dup }
24
+ @matched_jobs.delete_if { |job| !matcher.matches?(job) }
25
+ end
26
+ @matched_jobs.any?
27
+ end
28
+
29
+ def with(*args)
30
+ @matchers << QueuedArgs.new(args)
31
+ self
32
+ end
33
+
34
+ def at(the_time)
35
+ matcher = QueuedAt.new(the_time)
36
+ @matchers << matcher
37
+ self
38
+ end
39
+
40
+ def failure_message
41
+ # last stage to have any candidate jobs
42
+ failed_stage = @stages.reject do |s|
43
+ s[:candidates].empty?
44
+ end.last || @stages.first
45
+ failed_matcher = failed_stage[:matcher]
46
+ failed_candidates = failed_stage[:candidates]
47
+ found_instead = failed_matcher.failed_msg(failed_candidates)
48
+
49
+ "expected to enqueue #{job_description}, but found #{found_instead}"
50
+ end
51
+
52
+ def failure_message_when_negated
53
+ format "expected not to enqueue #{job_description}, got %d enqueued: %s",
54
+ @matched_jobs.length,
55
+ @matched_jobs.map { |j| format_job(j) }.join(", ")
56
+ end
57
+
58
+ def supports_block_expectations?
59
+ true
60
+ end
61
+
62
+ def description
63
+ "queues up a #{job_description}"
64
+ end
65
+
66
+ private
67
+
68
+ attr_reader :before_count, :after_count, :job_class, :argument_list_matcher
69
+
70
+ def enqueued_jobs
71
+ ::Que.execute "SELECT * FROM que_jobs"
72
+ end
73
+
74
+ def job_description
75
+ @matchers.map(&:desc).join(" ")
76
+ end
77
+
78
+ def format_job(job)
79
+ "#{job[:job_class]}[" + job[:args].join(", ") + "]"
80
+ end
81
+
82
+ class QueuedSomething
83
+ def matches?(_job)
84
+ true
85
+ end
86
+
87
+ def desc
88
+ "a job"
89
+ end
90
+
91
+ def failed_msg(_last_found)
92
+ "nothing"
93
+ end
94
+ end
95
+
96
+ class QueuedClass
97
+ attr_reader :job_class
98
+ def initialize(job_class)
99
+ @job_class = job_class
100
+ end
101
+
102
+ def matches?(job)
103
+ job[:job_class] == job_class.to_s
104
+ end
105
+
106
+ def desc
107
+ "of class #{job_class}"
108
+ end
109
+
110
+ def failed_msg(candidates)
111
+ classes = candidates.map { |c| c[:job_class] }
112
+ if classes.length == 1
113
+ classes.first
114
+ else
115
+ "#{classes.length} jobs of class [#{classes.join(', ')}]"
116
+ end
117
+ end
118
+ end
119
+
120
+ class QueuedArgs
121
+ def initialize(args)
122
+ @args = args
123
+ @argument_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(*args)
124
+ end
125
+
126
+ def matches?(job)
127
+ @argument_list_matcher.args_match?(*job[:args])
128
+ end
129
+
130
+ def desc
131
+ "with args #{@args}"
132
+ end
133
+
134
+ def failed_msg(candidates)
135
+ if candidates.length == 1
136
+ "job enqueued with #{candidates.first[:args]}"
137
+ else
138
+ "#{candidates.length} jobs with args: " +
139
+ candidates.map { |j| j[:args] }.to_s
140
+ end
141
+ end
142
+ end
143
+
144
+ class QueuedAt
145
+ def initialize(the_time)
146
+ @time = the_time
147
+ end
148
+
149
+ def matches?(job)
150
+ job[:run_at] == @time
151
+ end
152
+
153
+ def desc
154
+ "at #{@time}"
155
+ end
156
+
157
+ def failed_msg(candidates)
158
+ if candidates.length == 1
159
+ "job at #{candidates.first[:run_at]}"
160
+ else
161
+ "jobs at #{candidates.map { |c| c[:run_at] }}"
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,5 @@
1
+ module RSpec
2
+ module Que
3
+ VERSION = '1.0.2'.freeze
4
+ end
5
+ end
data/rspec-que.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ require File.expand_path('../lib/rspec/que/version', __FILE__)
2
+ require 'date'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'rspec-que'
6
+ s.version = RSpec::Que::VERSION
7
+ s.date = Date.today.strftime('%Y-%m-%d')
8
+ s.authors = ['GoCardless Engineering']
9
+ s.email = ['developers@gocardless.com']
10
+ s.summary = 'RSpec matchers to test Que'
11
+ s.description = <<-EOL
12
+ RSpec matchers for Que:
13
+ * expect { method }.to queue_up(MyJob).with(some_arguments)
14
+ EOL
15
+ s.homepage = 'http://github.com/gocardless/rspec-que'
16
+ s.license = 'MIT'
17
+
18
+ s.has_rdoc = false
19
+ s.files = `git ls-files lib README.md LICENSE *.gemspec -z`.split("\x0")
20
+ s.require_paths = %w(lib)
21
+
22
+ s.add_runtime_dependency('rspec-mocks')
23
+
24
+ s.add_development_dependency('rspec')
25
+ s.add_development_dependency('rspec-its')
26
+ s.add_development_dependency('rubocop')
27
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-que
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - GoCardless Engineering
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec-mocks
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-its
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: |2
70
+ RSpec matchers for Que:
71
+ * expect { method }.to queue_up(MyJob).with(some_arguments)
72
+ email:
73
+ - developers@gocardless.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - LICENSE
79
+ - README.md
80
+ - lib/rspec/que.rb
81
+ - lib/rspec/que/queue_up.rb
82
+ - lib/rspec/que/version.rb
83
+ - rspec-que.gemspec
84
+ homepage: http://github.com/gocardless/rspec-que
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.0.14.1
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: RSpec matchers to test Que
108
+ test_files: []