fixturama 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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/README.md +32 -4
  4. data/fixturama.gemspec +1 -1
  5. data/lib/fixturama.rb +48 -20
  6. data/lib/fixturama/changes.rb +71 -0
  7. data/lib/fixturama/changes/base.rb +28 -0
  8. data/lib/fixturama/changes/chain.rb +64 -0
  9. data/lib/fixturama/changes/chain/actions.rb +31 -0
  10. data/lib/fixturama/changes/chain/arguments.rb +59 -0
  11. data/lib/fixturama/changes/chain/raise_action.rb +35 -0
  12. data/lib/fixturama/changes/chain/return_action.rb +33 -0
  13. data/lib/fixturama/changes/const.rb +30 -0
  14. data/lib/fixturama/changes/request.rb +91 -0
  15. data/lib/fixturama/changes/request/response.rb +62 -0
  16. data/lib/fixturama/changes/request/responses.rb +22 -0
  17. data/lib/fixturama/changes/seed.rb +39 -0
  18. data/lib/fixturama/config.rb +5 -0
  19. data/lib/fixturama/fixture_error.rb +31 -0
  20. data/lib/fixturama/loader.rb +1 -0
  21. data/lib/fixturama/loader/context.rb +1 -0
  22. data/lib/fixturama/loader/value.rb +1 -0
  23. data/spec/fixturama/seed_fixture/_spec.rb +1 -0
  24. data/spec/fixturama/seed_fixture/seed.yml +0 -5
  25. metadata +34 -34
  26. data/lib/fixturama/seed.rb +0 -15
  27. data/lib/fixturama/stubs.rb +0 -79
  28. data/lib/fixturama/stubs/chain.rb +0 -90
  29. data/lib/fixturama/stubs/chain/actions.rb +0 -39
  30. data/lib/fixturama/stubs/chain/actions/raise.rb +0 -21
  31. data/lib/fixturama/stubs/chain/actions/return.rb +0 -23
  32. data/lib/fixturama/stubs/chain/arguments.rb +0 -86
  33. data/lib/fixturama/stubs/const.rb +0 -43
  34. data/lib/fixturama/stubs/request.rb +0 -98
  35. data/lib/fixturama/stubs/request/response.rb +0 -43
  36. data/lib/fixturama/stubs/request/responses.rb +0 -20
  37. data/lib/fixturama/utils.rb +0 -39
@@ -0,0 +1,35 @@
1
+ class Fixturama::Changes::Chain
2
+ #
3
+ # @private
4
+ # Raise a specified exception as a result of stubbing
5
+ #
6
+ class RaiseAction
7
+ attr_reader :repeat
8
+
9
+ def call
10
+ raise @error
11
+ end
12
+
13
+ private
14
+
15
+ def initialize(**options)
16
+ @error = error_from options
17
+ @repeat = repeat_from options
18
+ end
19
+
20
+ def error_from(options)
21
+ case value = options[:raise]
22
+ when NilClass, TrueClass, "true" then StandardError
23
+ when Class then value < Exception ? value : raise("Not an exception")
24
+ else Kernel.const_get(value)
25
+ end
26
+ rescue StandardError => err
27
+ raise Fixturama::FixtureError.new("an exception class", options, err)
28
+ end
29
+
30
+ def repeat_from(options)
31
+ options.fetch(:repeat, 1).to_i.tap { |val| return val if val.positive? }
32
+ raise Fixturama::FixtureError.new("a number of repeats", options)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ class Fixturama::Changes::Chain
2
+ #
3
+ # @private
4
+ # Return a specified value as a result of stubbing
5
+ #
6
+ class ReturnAction
7
+ attr_reader :repeat
8
+
9
+ def call
10
+ @value
11
+ end
12
+
13
+ private
14
+
15
+ def initialize(**options)
16
+ @value = value_from(options)
17
+ @repeat = repeat_from(options)
18
+ end
19
+
20
+ def value_from(options)
21
+ value = options[:return]
22
+ value.respond_to?(:dup) ? value.dup : value
23
+ rescue TypeError
24
+ # in the Ruby 2.3.0 Fixnum#dup is defined, but raises TypeError
25
+ value
26
+ end
27
+
28
+ def repeat_from(options)
29
+ options.fetch(:repeat, 1).to_i.tap { |val| return val if val.positive? }
30
+ raise Fixturama::FixtureError.new("a number of repeats", options)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ class Fixturama::Changes
2
+ #
3
+ # @private
4
+ # Stub a constant
5
+ #
6
+ class Const < Base
7
+ def key
8
+ name
9
+ end
10
+
11
+ def call(example)
12
+ example.send(:stub_const, name, value)
13
+ self
14
+ end
15
+
16
+ private
17
+
18
+ def initialize(**options)
19
+ @options = options
20
+ end
21
+
22
+ def name
23
+ @options[:const]
24
+ end
25
+
26
+ def value
27
+ @options[:value]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,91 @@
1
+ class Fixturama::Changes
2
+ #
3
+ # @private
4
+ # Stub an HTTP(S) request using +Webmock+
5
+ #
6
+ class Request < Base
7
+ require_relative "request/response"
8
+ require_relative "request/responses"
9
+
10
+ def call(example)
11
+ stub = example.stub_request(http_method, uri)
12
+ stub = stub.with(request) if request.any?
13
+ stub.to_return { |_| responses.next }
14
+ self
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :options
20
+
21
+ def initialize(options)
22
+ @options = options
23
+ with_error { @options = Hash(@options).transform_keys(&:to_sym) }
24
+ end
25
+
26
+ HTTP_METHODS = %i[get post put patch delete head options any].freeze
27
+
28
+ def http_method
29
+ with_error("http method") do
30
+ value = with_error("method") { options[:method]&.to_sym&.downcase }
31
+ value ||= :any
32
+ raise("Invalid HTTP method") unless HTTP_METHODS.include?(value)
33
+ value
34
+ end
35
+ end
36
+
37
+ def uri
38
+ with_error("uri") { maybe_regexp(options[:uri] || options[:url]) }
39
+ end
40
+
41
+ def headers
42
+ with_error("headers") do
43
+ Hash(options[:headers]).transform_keys(&:to_s) if options.key? :headers
44
+ end
45
+ end
46
+
47
+ def query
48
+ with_error("query") do
49
+ Hash(options[:query]).transform_keys(&:to_s) if options.key?(:query)
50
+ end
51
+ end
52
+
53
+ def body
54
+ with_error("body") { maybe_regexp options[:body] }
55
+ end
56
+
57
+ def basic_auth
58
+ with_error("basic auth") do
59
+ value = options[:auth] || options[:basic_auth]
60
+ Hash(value).transform_keys(&:to_s).values_at("user", "pass") if value
61
+ end
62
+ end
63
+
64
+ def request
65
+ @request ||= {
66
+ headers: headers,
67
+ body: body,
68
+ query: query,
69
+ basic_auth: basic_auth
70
+ }.select { |_, val| val }
71
+ end
72
+
73
+ def responses
74
+ @responses ||= Responses.new(options[:response] || options[:responses])
75
+ end
76
+
77
+ def with_error(part = nil)
78
+ yield
79
+ rescue StandardError => err
80
+ part = ["a valid request", part].compact.join(" ")
81
+ raise Fixturama::FixtureError.new(part, options, err)
82
+ end
83
+
84
+ def maybe_regexp(str)
85
+ return unless str
86
+
87
+ str = str.to_s
88
+ str[%r{\A/.*/\z}] ? Regexp.new(str[1..-2]) : str
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,62 @@
1
+ class Fixturama::Changes::Request
2
+ #
3
+ # @private
4
+ # Store data for a response to the corresponding request
5
+ #
6
+ class Response
7
+ # @!attribute [r] repeat A number of times the response to be repeated
8
+ # @return [Integer]
9
+ attr_reader :repeat
10
+
11
+ # @!attribute [r] to_h A hash for the +to_respond(...)+ part of the stub
12
+ # @return [Hash<Symbol, Object>]
13
+ attr_reader :to_h
14
+
15
+ private
16
+
17
+ def initialize(options)
18
+ @options = options
19
+ @options = with_error { Hash(options).transform_keys(&:to_sym) }
20
+ @to_h = build_hash
21
+ @repeat = build_repeat
22
+ end
23
+
24
+ def build_repeat
25
+ with_error("number of repeats") do
26
+ value = @options.fetch(:repeat, 1).to_i
27
+ value.positive? ? value : raise("Wrong value")
28
+ end
29
+ end
30
+
31
+ def build_hash
32
+ { status: status, body: body, headers: headers }.select { |_, v| v }
33
+ end
34
+
35
+ def status
36
+ with_error("status") { @options[:status]&.to_i } || 200
37
+ end
38
+
39
+ def body
40
+ with_error("body") do
41
+ case @options[:body]
42
+ when NilClass then nil
43
+ when Hash then JSON.dump(@options[:body])
44
+ else @options[:body].to_s
45
+ end
46
+ end
47
+ end
48
+
49
+ def headers
50
+ with_error("headers") do
51
+ Hash(@options[:headers]).map { |k, v| [k.to_s, v.to_s] }.to_h
52
+ end
53
+ end
54
+
55
+ def with_error(part = nil)
56
+ yield
57
+ rescue StandardError => err
58
+ object = ["a response", part].compact.join(" ")
59
+ raise Fixturama::FixtureError.new(object, options, err)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,22 @@
1
+ class Fixturama::Changes::Request
2
+ #
3
+ # @private
4
+ # Iterate by a consecutive responses to the request
5
+ #
6
+ class Responses
7
+ # @return [Fixturama::Changes::Request::Response]
8
+ def next
9
+ @list.count > 1 ? @list.pop : @list.first
10
+ end
11
+
12
+ private
13
+
14
+ def initialize(*list)
15
+ list = [{ status: 200 }] if list.empty?
16
+ @list = list.flatten.reverse.flat_map do |item|
17
+ response = Response.new(item)
18
+ [response.to_h] * response.repeat
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,39 @@
1
+ class Fixturama::Changes
2
+ #
3
+ # @private
4
+ # Seed objects using the +FactoryBot+
5
+ #
6
+ class Seed < Base
7
+ private
8
+
9
+ def initialize(**options)
10
+ @type = type_from(options)
11
+ @traits = traits_from(options)
12
+ @params = params_from(options)
13
+ @count = count_from(options)
14
+ create_object
15
+ end
16
+
17
+ def type_from(options)
18
+ options[:type]&.to_sym&.tap { |value| return value }
19
+ raise Fixturama::FixtureError.new("a factory", options)
20
+ end
21
+
22
+ def traits_from(options)
23
+ Array(options[:traits]).map(&:to_sym)
24
+ end
25
+
26
+ def params_from(options)
27
+ Hash(options[:params]).transform_keys(&:to_sym)
28
+ end
29
+
30
+ def count_from(options)
31
+ options.fetch(:count, 1).to_i.tap { |val| return val if val.positive? }
32
+ raise Fixturama::FixtureError.new("a valid number of objects", options)
33
+ end
34
+
35
+ def create_object
36
+ FactoryBot.create_list(@type, @count, *@traits, **@params)
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,8 @@
1
+ #
2
+ # @private
3
+ # Configures the gem to exclude conflicts between
4
+ # ids auto-generated by database and hardcoded in fixtures
5
+ #
1
6
  module Fixturama::Config
2
7
  module_function
3
8
 
@@ -0,0 +1,31 @@
1
+ #
2
+ # The exception complaining about invalid definition in some fixture
3
+ #
4
+ class Fixturama::FixtureError < ArgumentError
5
+ # The error message
6
+ # @return [String]
7
+ def message
8
+ <<~MESSAGE
9
+ Cannot infer #{@object} from the following part of the fixture #{@file}:
10
+ #{@data}
11
+ MESSAGE
12
+ end
13
+
14
+ # @private
15
+ # Add reference to the path of the fixture file
16
+ # @param [String] file
17
+ # @return [self]
18
+ def with_file(file)
19
+ @file = file
20
+ self
21
+ end
22
+
23
+ private
24
+
25
+ def initialize(object, data, _cause = nil)
26
+ @object = object
27
+ @data = YAML.dump(data)
28
+
29
+ super message
30
+ end
31
+ end
@@ -1,4 +1,5 @@
1
1
  #
2
+ # @private
2
3
  # Load fixture with some options
3
4
  #
4
5
  class Fixturama::Loader
@@ -1,5 +1,6 @@
1
1
  class Fixturama::Loader
2
2
  #
3
+ # @private
3
4
  # The context of some fixture
4
5
  #
5
6
  class Context
@@ -1,5 +1,6 @@
1
1
  class Fixturama::Loader
2
2
  #
3
+ # @private
3
4
  # Wraps a value with a reference to its key
4
5
  # in the [Fixturama::Loader::Context]
5
6
  #
@@ -26,6 +26,7 @@ RSpec.describe "seed_fixture" do
26
26
 
27
27
  it "runs the factory", aggregate_failures: true do
28
28
  expect(FactoryBot).to receive(:create_list).with(:foo, 1, :baz, qux: 42)
29
+
29
30
  expect(FactoryBot).to receive(:create_list) do |*args, **opts|
30
31
  expect(args).to eq [:foo, 3, :bar]
31
32
  expect(opts).to be_empty
@@ -9,8 +9,3 @@
9
9
  count: 3
10
10
  traits:
11
11
  - bar
12
-
13
- - type: foo
14
- count: 0
15
- traits:
16
- - baz
metadata CHANGED
@@ -1,114 +1,114 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fixturama
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kozin (nepalez)
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-09 00:00:00.000000000 Z
11
+ date: 2020-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: factory_bot
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - "~>"
17
18
  - !ruby/object:Gem::Version
18
19
  version: '4.0'
19
- name: factory_bot
20
- prerelease: false
21
20
  type: :runtime
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4.0'
27
27
  - !ruby/object:Gem::Dependency
28
+ name: rspec
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - "~>"
31
32
  - !ruby/object:Gem::Version
32
33
  version: '3.0'
33
- name: rspec
34
- prerelease: false
35
34
  type: :runtime
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
+ name: hashie
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - "~>"
45
46
  - !ruby/object:Gem::Version
46
47
  version: '3.0'
47
- name: hashie
48
- prerelease: false
49
48
  type: :runtime
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
+ name: webmock
56
57
  requirement: !ruby/object:Gem::Requirement
57
58
  requirements:
58
59
  - - "~>"
59
60
  - !ruby/object:Gem::Version
60
61
  version: '3.0'
61
- name: webmock
62
- prerelease: false
63
62
  type: :runtime
63
+ prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
+ name: rake
70
71
  requirement: !ruby/object:Gem::Requirement
71
72
  requirements:
72
73
  - - "~>"
73
74
  - !ruby/object:Gem::Version
74
75
  version: '10'
75
- name: rake
76
- prerelease: false
77
76
  type: :development
77
+ prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '10'
83
83
  - !ruby/object:Gem::Dependency
84
+ name: rspec-its
84
85
  requirement: !ruby/object:Gem::Requirement
85
86
  requirements:
86
87
  - - "~>"
87
88
  - !ruby/object:Gem::Version
88
89
  version: '1.0'
89
- name: rspec-its
90
- prerelease: false
91
90
  type: :development
91
+ prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.0'
97
97
  - !ruby/object:Gem::Dependency
98
+ name: rubocop
98
99
  requirement: !ruby/object:Gem::Requirement
99
100
  requirements:
100
101
  - - "~>"
101
102
  - !ruby/object:Gem::Version
102
103
  version: '0.49'
103
- name: rubocop
104
- prerelease: false
105
104
  type: :development
105
+ prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.49'
111
- description:
111
+ description:
112
112
  email: andrew.kozin@gmail.com
113
113
  executables: []
114
114
  extensions: []
@@ -127,23 +127,24 @@ files:
127
127
  - Rakefile
128
128
  - fixturama.gemspec
129
129
  - lib/fixturama.rb
130
+ - lib/fixturama/changes.rb
131
+ - lib/fixturama/changes/base.rb
132
+ - lib/fixturama/changes/chain.rb
133
+ - lib/fixturama/changes/chain/actions.rb
134
+ - lib/fixturama/changes/chain/arguments.rb
135
+ - lib/fixturama/changes/chain/raise_action.rb
136
+ - lib/fixturama/changes/chain/return_action.rb
137
+ - lib/fixturama/changes/const.rb
138
+ - lib/fixturama/changes/request.rb
139
+ - lib/fixturama/changes/request/response.rb
140
+ - lib/fixturama/changes/request/responses.rb
141
+ - lib/fixturama/changes/seed.rb
130
142
  - lib/fixturama/config.rb
143
+ - lib/fixturama/fixture_error.rb
131
144
  - lib/fixturama/loader.rb
132
145
  - lib/fixturama/loader/context.rb
133
146
  - lib/fixturama/loader/value.rb
134
147
  - lib/fixturama/rspec.rb
135
- - lib/fixturama/seed.rb
136
- - lib/fixturama/stubs.rb
137
- - lib/fixturama/stubs/chain.rb
138
- - lib/fixturama/stubs/chain/actions.rb
139
- - lib/fixturama/stubs/chain/actions/raise.rb
140
- - lib/fixturama/stubs/chain/actions/return.rb
141
- - lib/fixturama/stubs/chain/arguments.rb
142
- - lib/fixturama/stubs/const.rb
143
- - lib/fixturama/stubs/request.rb
144
- - lib/fixturama/stubs/request/response.rb
145
- - lib/fixturama/stubs/request/responses.rb
146
- - lib/fixturama/utils.rb
147
148
  - spec/fixturama/load_fixture/_spec.rb
148
149
  - spec/fixturama/load_fixture/data.json
149
150
  - spec/fixturama/load_fixture/data.yaml
@@ -157,7 +158,7 @@ homepage: https://github.com/nepalez/fixturama
157
158
  licenses:
158
159
  - MIT
159
160
  metadata: {}
160
- post_install_message:
161
+ post_install_message:
161
162
  rdoc_options: []
162
163
  require_paths:
163
164
  - lib
@@ -172,9 +173,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
173
  - !ruby/object:Gem::Version
173
174
  version: '0'
174
175
  requirements: []
175
- rubyforge_project:
176
- rubygems_version: 2.7.6
177
- signing_key:
176
+ rubygems_version: 3.0.6
177
+ signing_key:
178
178
  specification_version: 4
179
179
  summary: A set of helpers to prettify specs with fixtures
180
180
  test_files: