rspec-activejob 0.1.0 → 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/.rubocop.yml +33 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +35 -2
- data/lib/rspec/active_job.rb +7 -1
- data/lib/rspec/active_job/{matchers.rb → enqueue_a.rb} +12 -3
- data/lib/rspec/active_job/global_id.rb +47 -0
- data/lib/rspec/active_job/version.rb +1 -1
- data/spec/rspec/active_job/{matchers_spec.rb → enqueue_a_spec.rb} +2 -2
- data/spec/rspec/active_job/global_id_spec.rb +101 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ec1b26448aaa3732cc1239e94ed67be18fdd034
|
4
|
+
data.tar.gz: 53d956546e042ad727cc3d02094c5fb9851c24ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7dbbdb3029c97cb2c71fe0b57d112fece98190849934e26e861e01cb4f2f9a427921fa541cba527589f341f06a1a5629a7a5afd9fddceb7f59d06ec56fabfddf
|
7
|
+
data.tar.gz: ded3be79382e60bf7fa9c590da4f34a0732ff660c51236cba33153aae22da379b3144bcd7a8cf8b4f4193dc24b47e35fca75a920bde1eebdaae8396719a61ee2
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Limit lines to 90 characters.
|
2
|
+
LineLength:
|
3
|
+
Max: 90
|
4
|
+
|
5
|
+
ClassLength:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
# Avoid single-line methods.
|
9
|
+
SingleLineMethods:
|
10
|
+
AllowIfMethodIsEmpty: true
|
11
|
+
|
12
|
+
StringLiterals:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
# Wants you to use the same argument names for every reduce. This seems kinda
|
16
|
+
# naff compared to naming them semantically
|
17
|
+
SingleLineBlockParams:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/SignalException:
|
21
|
+
EnforcedStyle: 'only_raise'
|
22
|
+
|
23
|
+
# Use trailing rather than leading dots on multi-line call chains
|
24
|
+
Style/DotPosition:
|
25
|
+
EnforcedStyle: trailing
|
26
|
+
|
27
|
+
# Whatever
|
28
|
+
Style/Documentation:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
# RSpec argument matchers use ===. Sorry cop.
|
32
|
+
Style/CaseEquality:
|
33
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,15 +1,48 @@
|
|
1
1
|
# RSpec ActiveJob matchers
|
2
2
|
|
3
3
|
```ruby
|
4
|
+
# config/environments/test.rb
|
5
|
+
config.active_job.queue_adapter = :test
|
6
|
+
|
7
|
+
# spec/spec_helper.rb
|
4
8
|
RSpec.configure do |config|
|
5
9
|
config.include(RSpec::ActiveJob)
|
10
|
+
|
11
|
+
# clean out the queue after each spec
|
12
|
+
config.after(:each) do
|
13
|
+
ActiveJob::Base.queue_adapter.enqueued_jobs = []
|
14
|
+
ActiveJob::Base.queue_adapter.performed_jobs = []
|
15
|
+
end
|
6
16
|
end
|
7
17
|
|
18
|
+
# spec/controllers/my_controller_spec.rb
|
8
19
|
RSpec.describe MyController do
|
9
20
|
let(:user) { create(:user) }
|
10
21
|
let(:params) { { user_id: user.id } }
|
11
22
|
subject(:make_request) { described_class.make_request(params) }
|
12
23
|
|
13
|
-
specify { expect { make_request }.to enqueue_a(RequestMaker).with(user) }
|
24
|
+
specify { expect { make_request }.to enqueue_a(RequestMaker).with(global_id(user)) }
|
14
25
|
end
|
15
|
-
```
|
26
|
+
```
|
27
|
+
|
28
|
+
rspec-activejob expects the current queue adapter to expose an array of `enqueued_jobs`, like the included
|
29
|
+
test adapter. The test adapter included in ActiveJob 4.2.0 does not fully serialize its arguments, so you
|
30
|
+
will not need to use the GlobalID matcher until ActiveJob 4.2.1. See rails/rails#18266 for the improved
|
31
|
+
test adapter.
|
32
|
+
|
33
|
+
This gem defines two matchers:
|
34
|
+
|
35
|
+
* `enqueue_a`: for a block or proc, expects that to enqueue an job to the ActiveJob test adapter. Optionally
|
36
|
+
takes the job class as its argument, and can be modified with a `.with(*args)` call to expect specific arguments.
|
37
|
+
This will use the same argument list matcher as rspec-mocks' `receive(:message).with(*args)` matcher.
|
38
|
+
|
39
|
+
* `global_id(model_or_class)`: an argument matcher, matching ActiveJob-serialized versions of model classes or
|
40
|
+
specific models (or any other class which implements `to_global_id`). If you pass a model class, it will match
|
41
|
+
the serialized version of any instance of that model; if you pass an instance, it will expect the serialized
|
42
|
+
version of that specific instance.
|
43
|
+
|
44
|
+
|
45
|
+
With the `global_id` matcher it's important to note that it's specific to ActiveJob-serialized GlobalIDs.
|
46
|
+
ActiveJob serializes them as a hash like `{ '_aj_global_id' => 'gid://my-app/MyModel/ID123' }`, to avoid
|
47
|
+
clashes with plain strings which accidentally match the GlobalID syntax. This matcher will not work with
|
48
|
+
other usages of GlobalID.
|
data/lib/rspec/active_job.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
require 'rspec/active_job/
|
1
|
+
require 'rspec/active_job/enqueue_a'
|
2
|
+
require 'rspec/active_job/global_id'
|
3
|
+
|
2
4
|
module RSpec
|
3
5
|
module ActiveJob
|
4
6
|
def enqueue_a(job_class)
|
5
7
|
Matchers::EnqueueA.new(job_class)
|
6
8
|
end
|
9
|
+
|
10
|
+
def global_id(expected)
|
11
|
+
Matchers::GlobalID.new(expected)
|
12
|
+
end
|
7
13
|
end
|
8
14
|
end
|
@@ -27,10 +27,12 @@ module RSpec
|
|
27
27
|
end
|
28
28
|
|
29
29
|
unless enqueued_correct_class?
|
30
|
-
return "expected to enqueue a #{job_class},
|
30
|
+
return "expected to enqueue a #{job_class}, " \
|
31
|
+
"enqueued a #{enqueued_jobs.last[:job]}"
|
31
32
|
end
|
32
33
|
|
33
|
-
"expected to enqueue a #{job_class} with
|
34
|
+
"expected to enqueue a #{job_class} with " \
|
35
|
+
"#{argument_list_matcher.expected_args}, but enqueued with " \
|
34
36
|
"#{new_jobs_with_correct_class.first[:args]}"
|
35
37
|
end
|
36
38
|
|
@@ -38,6 +40,12 @@ module RSpec
|
|
38
40
|
true
|
39
41
|
end
|
40
42
|
|
43
|
+
def description
|
44
|
+
return "enqueue a job" unless job_class
|
45
|
+
return "enqueue a #{job_class.name}" unless argument_list_matcher
|
46
|
+
"enqueue a #{job_class.name} with #{argument_list_matcher.expected_args}"
|
47
|
+
end
|
48
|
+
|
41
49
|
private
|
42
50
|
|
43
51
|
attr_reader :before_count, :after_count, :job_class, :argument_list_matcher
|
@@ -65,7 +73,8 @@ module RSpec
|
|
65
73
|
end
|
66
74
|
|
67
75
|
def new_jobs_with_correct_class_and_args
|
68
|
-
new_jobs_with_correct_class.
|
76
|
+
new_jobs_with_correct_class.
|
77
|
+
select { |job| argument_list_matcher.args_match?(*job[:args]) }
|
69
78
|
end
|
70
79
|
|
71
80
|
def enqueued_jobs
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'global_id'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module ActiveJob
|
5
|
+
module Matchers
|
6
|
+
class GlobalID
|
7
|
+
def initialize(expected)
|
8
|
+
unless valid_expected?(expected)
|
9
|
+
raise "expected argument must implement to_global_id"
|
10
|
+
end
|
11
|
+
|
12
|
+
@expected = expected
|
13
|
+
end
|
14
|
+
|
15
|
+
def ===(other)
|
16
|
+
other.is_a?(Hash) &&
|
17
|
+
other.keys == ['_aj_globalid'] &&
|
18
|
+
global_id_matches?(other['_aj_globalid'])
|
19
|
+
end
|
20
|
+
|
21
|
+
def description
|
22
|
+
"serialized global ID of #{@expected}" unless @expected.is_a?(Class)
|
23
|
+
"serialized global ID of #{@expected.name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def valid_expected?(expected)
|
29
|
+
return expected.instance_method(:to_global_id) if expected.is_a?(Class)
|
30
|
+
expected.respond_to?(:to_global_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def global_id_matches?(other)
|
34
|
+
parsed = ::GlobalID.parse(other)
|
35
|
+
return false unless parsed
|
36
|
+
return correct_class?(parsed) if @expected.is_a?(Class)
|
37
|
+
other == @expected.to_global_id.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def correct_class?(other)
|
41
|
+
other.app == ::GlobalID.app &&
|
42
|
+
other.model_class == @expected
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -41,7 +41,7 @@ RSpec.describe RSpec::ActiveJob::Matchers::EnqueueA do
|
|
41
41
|
|
42
42
|
context "when it enqueues two jobs" do
|
43
43
|
let(:proc) do
|
44
|
-
-> { enqueued_jobs << { job: AJob, args: []} << { job: BJob, args: [] } }
|
44
|
+
-> { enqueued_jobs << { job: AJob, args: [] } << { job: BJob, args: [] } }
|
45
45
|
end
|
46
46
|
|
47
47
|
it { is_expected.to be(true) }
|
@@ -70,4 +70,4 @@ RSpec.describe RSpec::ActiveJob::Matchers::EnqueueA do
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
73
|
-
end
|
73
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RSpec::ActiveJob::Matchers::GlobalID do
|
4
|
+
class MyModel
|
5
|
+
def to_global_id
|
6
|
+
"gid://my-app/MyModel/ID123"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:instance) { described_class.new(expected) }
|
11
|
+
subject(:matches?) { instance === actual }
|
12
|
+
|
13
|
+
before { GlobalID.app = 'my-app' }
|
14
|
+
|
15
|
+
context "expecting a class" do
|
16
|
+
let(:expected) { MyModel }
|
17
|
+
|
18
|
+
context "serialized model" do
|
19
|
+
let(:actual) { { '_aj_globalid' => 'gid://my-app/MyModel/ID123' } }
|
20
|
+
it { is_expected.to be(true) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "actual model" do
|
24
|
+
let(:actual) { MyModel.new }
|
25
|
+
it { is_expected.to be(false) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "model class" do
|
29
|
+
let(:actual) { MyModel }
|
30
|
+
it { is_expected.to be(false) }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "hash with extra stuff" do
|
34
|
+
let(:actual) do
|
35
|
+
{ '_aj_globalid' => 'gid://my-app/MyModel/ID123', 'other' => 'stuff' }
|
36
|
+
end
|
37
|
+
it { is_expected.to be(false) }
|
38
|
+
end
|
39
|
+
|
40
|
+
context "invalid GlobalID" do
|
41
|
+
let(:actual) { { '_aj_globalid' => 'not://a/global/id' } }
|
42
|
+
it { is_expected.to be(false) }
|
43
|
+
end
|
44
|
+
|
45
|
+
context "nil" do
|
46
|
+
let(:actual) { nil }
|
47
|
+
it { is_expected.to be(false) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "expecting a specific instance" do
|
52
|
+
let(:expected) { MyModel.new }
|
53
|
+
|
54
|
+
context "serialized instance" do
|
55
|
+
let(:actual) { { '_aj_globalid' => 'gid://my-app/MyModel/ID123' } }
|
56
|
+
it { is_expected.to be(true) }
|
57
|
+
end
|
58
|
+
|
59
|
+
context "model class" do
|
60
|
+
let(:actual) { MyModel }
|
61
|
+
it { is_expected.to be(false) }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "instance itself" do
|
65
|
+
let(:actual) { expected }
|
66
|
+
it { is_expected.to be(false) }
|
67
|
+
end
|
68
|
+
|
69
|
+
context "hash with extra stuff" do
|
70
|
+
let(:actual) do
|
71
|
+
{ '_aj_globalid' => 'gid://my-app/MyModel/ID123', 'other' => 'stuff' }
|
72
|
+
end
|
73
|
+
it { is_expected.to be(false) }
|
74
|
+
end
|
75
|
+
|
76
|
+
context "mismatching app" do
|
77
|
+
let(:actual) { { '_aj_globalid' => 'gid://other-app/MyModel/ID123' } }
|
78
|
+
it { is_expected.to be(false) }
|
79
|
+
end
|
80
|
+
|
81
|
+
context "mismatching model" do
|
82
|
+
let(:actual) { { '_aj_globalid' => 'gid://my-app/OtherModel/ID123' } }
|
83
|
+
it { is_expected.to be(false) }
|
84
|
+
end
|
85
|
+
|
86
|
+
context "mismatching ID" do
|
87
|
+
let(:actual) { { '_aj_globalid' => 'gid://my-app/MyModel/ID456' } }
|
88
|
+
it { is_expected.to be(false) }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "expecting a non-gid instance" do
|
93
|
+
let(:expected) { Object.new }
|
94
|
+
specify { expect { matches? }.to raise_error }
|
95
|
+
end
|
96
|
+
|
97
|
+
context "expecting a non-gid class" do
|
98
|
+
let(:expected) { Object }
|
99
|
+
specify { expect { matches? }.to raise_error }
|
100
|
+
end
|
101
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-activejob
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Isaac Seymour
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -76,14 +76,18 @@ extensions: []
|
|
76
76
|
extra_rdoc_files: []
|
77
77
|
files:
|
78
78
|
- .gitignore
|
79
|
+
- .rubocop.yml
|
80
|
+
- CHANGELOG.md
|
79
81
|
- Gemfile
|
80
82
|
- Gemfile.lock
|
81
83
|
- README.md
|
82
84
|
- lib/rspec/active_job.rb
|
83
|
-
- lib/rspec/active_job/
|
85
|
+
- lib/rspec/active_job/enqueue_a.rb
|
86
|
+
- lib/rspec/active_job/global_id.rb
|
84
87
|
- lib/rspec/active_job/version.rb
|
85
88
|
- rspec-activejob.gemspec
|
86
|
-
- spec/rspec/active_job/
|
89
|
+
- spec/rspec/active_job/enqueue_a_spec.rb
|
90
|
+
- spec/rspec/active_job/global_id_spec.rb
|
87
91
|
- spec/spec_helper.rb
|
88
92
|
homepage: http://github.com/gocardless/rspec-activejob
|
89
93
|
licenses:
|