rspec-activejob 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|