fixturama 0.0.7 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +100 -0
- data/README.md +71 -3
- data/lib/fixturama.rb +49 -20
- data/lib/fixturama/changes.rb +72 -0
- data/lib/fixturama/changes/base.rb +28 -0
- data/lib/fixturama/changes/chain.rb +64 -0
- data/lib/fixturama/changes/chain/actions.rb +31 -0
- data/lib/fixturama/changes/chain/arguments.rb +59 -0
- data/lib/fixturama/changes/chain/raise_action.rb +43 -0
- data/lib/fixturama/changes/chain/return_action.rb +33 -0
- data/lib/fixturama/changes/const.rb +30 -0
- data/lib/fixturama/changes/env.rb +35 -0
- data/lib/fixturama/changes/request.rb +91 -0
- data/lib/fixturama/changes/request/response.rb +62 -0
- data/lib/fixturama/changes/request/responses.rb +22 -0
- data/lib/fixturama/changes/seed.rb +39 -0
- data/lib/fixturama/config.rb +5 -0
- data/lib/fixturama/fixture_error.rb +31 -0
- data/lib/fixturama/loader.rb +1 -0
- data/lib/fixturama/loader/context.rb +1 -0
- data/lib/fixturama/loader/value.rb +1 -0
- data/lib/fixturama/version.rb +4 -0
- metadata +80 -50
- data/.gitignore +0 -12
- data/.rspec +0 -2
- data/.rubocop.yml +0 -22
- data/.travis.yml +0 -23
- data/Gemfile +0 -9
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -6
- data/fixturama.gemspec +0 -23
- data/lib/fixturama/seed.rb +0 -15
- data/lib/fixturama/stubs.rb +0 -57
- data/lib/fixturama/stubs/chain.rb +0 -89
- data/lib/fixturama/stubs/chain/actions.rb +0 -39
- data/lib/fixturama/stubs/chain/actions/raise.rb +0 -21
- data/lib/fixturama/stubs/chain/actions/return.rb +0 -23
- data/lib/fixturama/stubs/chain/arguments.rb +0 -86
- data/lib/fixturama/stubs/const.rb +0 -42
- data/lib/fixturama/utils.rb +0 -39
- data/spec/fixturama/load_fixture/_spec.rb +0 -53
- data/spec/fixturama/load_fixture/data.json +0 -5
- data/spec/fixturama/load_fixture/data.yaml +0 -3
- data/spec/fixturama/load_fixture/data.yml +0 -3
- data/spec/fixturama/seed_fixture/_spec.rb +0 -33
- data/spec/fixturama/seed_fixture/seed.yml +0 -16
- data/spec/fixturama/stub_fixture/_spec.rb +0 -96
- data/spec/fixturama/stub_fixture/stub.yml +0 -60
- data/spec/spec_helper.rb +0 -26
@@ -1,89 +0,0 @@
|
|
1
|
-
module Fixturama
|
2
|
-
#
|
3
|
-
# Stubbed chain of messages
|
4
|
-
#
|
5
|
-
class Stubs::Chain
|
6
|
-
require_relative "chain/actions"
|
7
|
-
require_relative "chain/arguments"
|
8
|
-
|
9
|
-
attr_reader :receiver, :messages
|
10
|
-
|
11
|
-
#
|
12
|
-
# Human-readable representation of the chain
|
13
|
-
# @return [String]
|
14
|
-
#
|
15
|
-
def to_s
|
16
|
-
"#{receiver}.#{messages.join(".")}"
|
17
|
-
end
|
18
|
-
alias to_str to_s
|
19
|
-
|
20
|
-
#
|
21
|
-
# Register new action for some arguments
|
22
|
-
#
|
23
|
-
# @option [Array<#to_s>, #to_s] :arguments The specific arguments
|
24
|
-
# @option (see Fixturama::Stubs::Arguments#add_action)
|
25
|
-
# @return [self]
|
26
|
-
#
|
27
|
-
def update!(actions:, arguments: nil, **)
|
28
|
-
Utils.array(arguments).tap do |args|
|
29
|
-
stub = find_by(args)
|
30
|
-
unless stub
|
31
|
-
stub = Stubs::Chain::Arguments.new(self, args)
|
32
|
-
stubs << stub
|
33
|
-
end
|
34
|
-
stub.add!(*actions)
|
35
|
-
stubs.sort_by! { |stub| -stub.arguments.count }
|
36
|
-
end
|
37
|
-
|
38
|
-
self
|
39
|
-
end
|
40
|
-
|
41
|
-
#
|
42
|
-
# Apply the stub to RSpec example
|
43
|
-
#
|
44
|
-
def apply!(example)
|
45
|
-
reset!
|
46
|
-
|
47
|
-
call_action = example.send(:receive_message_chain, *messages) do |*args|
|
48
|
-
call! args
|
49
|
-
end
|
50
|
-
|
51
|
-
example.send(:allow, receiver).to call_action
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def initialize(**options)
|
57
|
-
@receiver = Utils.constantize options[:class] if options.key?(:class)
|
58
|
-
@receiver ||= Object.send :eval, options[:object] if options.key?(:object)
|
59
|
-
raise SyntaxError, "Undefined receiver of messages" unless receiver
|
60
|
-
|
61
|
-
@messages = Utils.symbolize_array options[:chain]
|
62
|
-
return if messages.any?
|
63
|
-
|
64
|
-
raise SyntaxError, <<~MESSAGE.squish
|
65
|
-
Undefined message chain for stubbing #{receiver}.
|
66
|
-
Use option `chain` to define it.
|
67
|
-
MESSAGE
|
68
|
-
end
|
69
|
-
|
70
|
-
def stubs
|
71
|
-
@stubs ||= []
|
72
|
-
end
|
73
|
-
|
74
|
-
def find_by(arguments)
|
75
|
-
stubs.find { |stub| stub.arguments == arguments }
|
76
|
-
end
|
77
|
-
|
78
|
-
def reset!
|
79
|
-
tap { stubs.each(&:reset!) }
|
80
|
-
end
|
81
|
-
|
82
|
-
def call!(actual_arguments)
|
83
|
-
stub = stubs.find { |item| item.applicable_to?(actual_arguments) }
|
84
|
-
raise "Unexpected arguments #{actual_arguments}" unless stub
|
85
|
-
|
86
|
-
stub.call_next!
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module Fixturama
|
2
|
-
#
|
3
|
-
# Factory to provide a specific action from options
|
4
|
-
#
|
5
|
-
module Stubs::Chain::Actions
|
6
|
-
extend self
|
7
|
-
|
8
|
-
require_relative "actions/raise"
|
9
|
-
require_relative "actions/return"
|
10
|
-
|
11
|
-
#
|
12
|
-
# Builds an action
|
13
|
-
# @option [#to_s] :raise
|
14
|
-
# @option [Object] :return
|
15
|
-
# @option [true] :call_original
|
16
|
-
# @return [#call] a callable action
|
17
|
-
#
|
18
|
-
def build(stub, **options)
|
19
|
-
check!(stub, options)
|
20
|
-
key, value = options.to_a.first
|
21
|
-
TYPES[key].new(stub, value)
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def check!(stub, options)
|
27
|
-
keys = options.keys & TYPES.keys
|
28
|
-
return if keys.count == 1
|
29
|
-
|
30
|
-
raise SyntaxError, <<~MESSAGE.squish
|
31
|
-
Invalid settings for stubbing message chain #{stub}: #{options}.
|
32
|
-
The action MUST have one and only one of the keys:
|
33
|
-
`#{TYPES.keys.join('`, `')}`.
|
34
|
-
MESSAGE
|
35
|
-
end
|
36
|
-
|
37
|
-
TYPES = { raise: Raise, return: Return }.freeze
|
38
|
-
end
|
39
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
class Fixturama::Stubs::Chain::Actions::Raise
|
2
|
-
def call
|
3
|
-
raise @exception
|
4
|
-
end
|
5
|
-
|
6
|
-
#
|
7
|
-
# Human-readable representation of the expectation
|
8
|
-
# @return [String]
|
9
|
-
#
|
10
|
-
def to_s
|
11
|
-
"#{@stub} # raise #{@exception}"
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def initialize(stub, name)
|
17
|
-
@stub = stub
|
18
|
-
name = name.to_s
|
19
|
-
@exception = name == "true" ? StandardError : Kernel.const_get(name)
|
20
|
-
end
|
21
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
class Fixturama::Stubs::Chain::Actions::Return
|
2
|
-
attr_reader :stub, :call
|
3
|
-
|
4
|
-
#
|
5
|
-
# Human-readable representation of the expectation
|
6
|
-
# @return [String]
|
7
|
-
#
|
8
|
-
def to_s
|
9
|
-
"#{@stub} # => #{call}"
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def initialize(stub, output)
|
15
|
-
@stub = stub
|
16
|
-
@call = \
|
17
|
-
begin # in ruby 2.3.0 Fixnum#dup is defined, but raises TypeError
|
18
|
-
output.respond_to?(:dup) ? output.dup : output
|
19
|
-
rescue TypeError
|
20
|
-
output
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
module Fixturama
|
2
|
-
#
|
3
|
-
# Collection of arguments for a stub with a list of actions to be called
|
4
|
-
#
|
5
|
-
class Stubs::Chain::Arguments
|
6
|
-
attr_reader :chain, :arguments
|
7
|
-
|
8
|
-
#
|
9
|
-
# Register new action for these set of arguments
|
10
|
-
# @option [#to_i] :repeat (1)
|
11
|
-
# How much the action should be repeated during the consecutive calls
|
12
|
-
# @return [self] itself
|
13
|
-
#
|
14
|
-
def add!(*actions)
|
15
|
-
actions.each do |settings|
|
16
|
-
settings = Utils.symbolize_hash(settings)
|
17
|
-
repeat = [0, settings.fetch(:repeat, 1).to_i].max
|
18
|
-
repeat.times { list << Stubs::Chain::Actions.build(self, settings) }
|
19
|
-
end
|
20
|
-
|
21
|
-
self
|
22
|
-
end
|
23
|
-
|
24
|
-
#
|
25
|
-
# Whether the current stub is applicable to actual arguments
|
26
|
-
# @param [Array<Object>] actual_arguments
|
27
|
-
# @return [Boolean]
|
28
|
-
#
|
29
|
-
def applicable_to?(actual_arguments)
|
30
|
-
last_index = actual_arguments.count
|
31
|
-
@arguments.zip(actual_arguments)
|
32
|
-
.each.with_index(1)
|
33
|
-
.reduce(true) do |obj, ((expected, actual), index)|
|
34
|
-
obj && (
|
35
|
-
expected == actual ||
|
36
|
-
index == last_index &&
|
37
|
-
Fixturama::Utils.matched_hash_args?(actual, expected)
|
38
|
-
)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
#
|
43
|
-
# Reset the counter of calls
|
44
|
-
# @return [self] itself
|
45
|
-
#
|
46
|
-
def reset!
|
47
|
-
@counter = 0
|
48
|
-
self
|
49
|
-
end
|
50
|
-
|
51
|
-
#
|
52
|
-
# Calls the next action for these set of agruments
|
53
|
-
# @return [Object]
|
54
|
-
# @raise [StandardError]
|
55
|
-
#
|
56
|
-
def call_next!
|
57
|
-
list.fetch(counter) { list.last }.call.tap { @counter += 1 }
|
58
|
-
end
|
59
|
-
|
60
|
-
#
|
61
|
-
# Human-readable representation of arguments
|
62
|
-
# @return [String]
|
63
|
-
#
|
64
|
-
def to_s
|
65
|
-
args = [*arguments.map(&:to_s), "*"].join(", ")
|
66
|
-
"#{chain}(#{args})"
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
# @param [Fixturama::Stubs::Chain] chain Back reference
|
72
|
-
# @param [Array<Object>] list Definition of arguments
|
73
|
-
def initialize(chain, list)
|
74
|
-
@chain = chain
|
75
|
-
@arguments = Utils.array(list)
|
76
|
-
end
|
77
|
-
|
78
|
-
def counter
|
79
|
-
@counter ||= 0
|
80
|
-
end
|
81
|
-
|
82
|
-
def list
|
83
|
-
@list ||= []
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Fixturama
|
2
|
-
#
|
3
|
-
# Definition for stubbing a constant
|
4
|
-
#
|
5
|
-
class Stubs::Const
|
6
|
-
attr_reader :const, :value
|
7
|
-
|
8
|
-
#
|
9
|
-
# Human-readable representation of the chain
|
10
|
-
# @return [String]
|
11
|
-
#
|
12
|
-
def to_s
|
13
|
-
const.to_s
|
14
|
-
end
|
15
|
-
alias to_str to_s
|
16
|
-
|
17
|
-
#
|
18
|
-
# Overload the definition for the constant
|
19
|
-
# @option [Object] value
|
20
|
-
# @return [self]
|
21
|
-
#
|
22
|
-
def update!(value:, **)
|
23
|
-
@value = value
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
#
|
28
|
-
# Apply the stub to RSpec example
|
29
|
-
# @return [self]
|
30
|
-
#
|
31
|
-
def apply!(example)
|
32
|
-
example.send(:stub_const, const, value)
|
33
|
-
self
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def initialize(const:, **)
|
39
|
-
@const = const.to_s
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/lib/fixturama/utils.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
module Fixturama
|
2
|
-
module Utils
|
3
|
-
module_function
|
4
|
-
|
5
|
-
def symbolize(item)
|
6
|
-
item.to_s.to_sym
|
7
|
-
end
|
8
|
-
|
9
|
-
def symbolize_hash(data)
|
10
|
-
Hash(data).transform_keys { |key| symbolize(key)}
|
11
|
-
end
|
12
|
-
|
13
|
-
def symbolize_array(data)
|
14
|
-
Array(data).map { |item| symbolize(item) }
|
15
|
-
end
|
16
|
-
|
17
|
-
def constantize(item)
|
18
|
-
Kernel.const_get(item.to_s)
|
19
|
-
end
|
20
|
-
|
21
|
-
def clone(item)
|
22
|
-
item.respond_to?(:dup) ? item.dup : item
|
23
|
-
end
|
24
|
-
|
25
|
-
def array(list)
|
26
|
-
case list
|
27
|
-
when NilClass then []
|
28
|
-
when Array then list
|
29
|
-
else [list]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def matched_hash_args?(actual, expected)
|
34
|
-
return unless actual.is_a?(Hash) && expected.is_a?(Hash)
|
35
|
-
|
36
|
-
expected.all? { |key, val| actual[key] == val }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
RSpec.describe "load_fixture" do
|
2
|
-
let(:expected) { { "foo" => { "bar" => 42 } } }
|
3
|
-
|
4
|
-
context "YAML" do
|
5
|
-
subject { load_fixture("#{__dir__}/data.yaml", id: 42) }
|
6
|
-
|
7
|
-
it { is_expected.to eq expected }
|
8
|
-
end
|
9
|
-
|
10
|
-
context "YML" do
|
11
|
-
subject { load_fixture("#{__dir__}/data.yml", id: 42) }
|
12
|
-
|
13
|
-
it { is_expected.to eq expected }
|
14
|
-
end
|
15
|
-
|
16
|
-
context "YAML with ruby object" do
|
17
|
-
subject { load_fixture("#{__dir__}/data.yaml", id: foobar) }
|
18
|
-
|
19
|
-
before { class Test::Foobar; end }
|
20
|
-
|
21
|
-
let(:foobar) { Test::Foobar.new }
|
22
|
-
let(:expected) { { "foo" => { "bar" => foobar } } }
|
23
|
-
|
24
|
-
it { is_expected.to eq expected }
|
25
|
-
end
|
26
|
-
|
27
|
-
context "JSON" do
|
28
|
-
subject { load_fixture("#{__dir__}/data.json", id: 42) }
|
29
|
-
|
30
|
-
it { is_expected.to eq expected }
|
31
|
-
end
|
32
|
-
|
33
|
-
context "JSON with ruby object" do
|
34
|
-
subject { load_fixture("#{__dir__}/data.json", id: foobar) }
|
35
|
-
|
36
|
-
before { class Test::Foobar; end }
|
37
|
-
|
38
|
-
let(:foobar) { Test::Foobar.new }
|
39
|
-
let(:expected) { { "foo" => { "bar" => foobar } } }
|
40
|
-
|
41
|
-
it { is_expected.to eq expected }
|
42
|
-
end
|
43
|
-
|
44
|
-
context "with RSpec argument matchers" do
|
45
|
-
subject { load_fixture("#{__dir__}/data.yaml", id: kind_of(Numeric)) }
|
46
|
-
|
47
|
-
it "loads the matcher", aggregate_failures: true do
|
48
|
-
expect("foo" => { "bar" => 42 }).to include subject
|
49
|
-
expect("foo" => { "bar" => 99 }).to include subject
|
50
|
-
expect("foo" => { "bar" => :a }).not_to include subject
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
RSpec.describe "seed_fixture" do
|
2
|
-
subject { seed_fixture "#{__dir__}/seed.yml" }
|
3
|
-
|
4
|
-
before do
|
5
|
-
FactoryBot.define do
|
6
|
-
factory :foo, class: Hash do
|
7
|
-
transient do
|
8
|
-
bar { 0 }
|
9
|
-
baz { 0 }
|
10
|
-
qux { 0 }
|
11
|
-
end
|
12
|
-
|
13
|
-
trait :bar do
|
14
|
-
bar { 99 }
|
15
|
-
end
|
16
|
-
|
17
|
-
trait :baz do
|
18
|
-
baz { 77 }
|
19
|
-
end
|
20
|
-
|
21
|
-
skip_create
|
22
|
-
initialize_with { { bar: bar, baz: baz, qux: qux } }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
it "runs the factory", aggregate_failures: true do
|
28
|
-
expect(FactoryBot).to receive(:create_list).with(:foo, 1, :baz, qux: 42)
|
29
|
-
expect(FactoryBot).to receive(:create_list).with(:foo, 3, :bar, {})
|
30
|
-
|
31
|
-
subject
|
32
|
-
end
|
33
|
-
end
|