rails_edge_test 2.1.0 → 3.0.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/.envrc +6 -2
- data/.github/workflows/ci.yml +10 -4
- data/.gitignore +0 -1
- data/.rubocop.yml +42 -0
- data/.rubocop_todo.yml +22 -0
- data/.ruby-version +1 -0
- data/Appraisals +2 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +253 -0
- data/README.md +33 -18
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/exe/generate_edges +5 -5
- data/flake.lock +116 -0
- data/flake.nix +94 -0
- data/gemset.nix +1286 -0
- data/lib/rails_edge_test/configuration.rb +5 -9
- data/lib/rails_edge_test/dsl/action.rb +41 -37
- data/lib/rails_edge_test/dsl/controller.rb +24 -20
- data/lib/rails_edge_test/dsl/edge.rb +113 -112
- data/lib/rails_edge_test/dsl/let_handler.rb +16 -14
- data/lib/rails_edge_test/dsl.rb +2 -2
- data/lib/rails_edge_test/printers/boring.rb +27 -27
- data/lib/rails_edge_test/printers/silent.rb +13 -17
- data/lib/rails_edge_test/printers/tree.rb +42 -39
- data/lib/rails_edge_test/runner.rb +8 -5
- data/lib/rails_edge_test/version.rb +3 -1
- data/lib/rails_edge_test.rb +14 -15
- data/rails_edge_test.gemspec +18 -18
- data/shell.nix +3 -23
- metadata +16 -91
- data/nix/.bundle/config +0 -3
- data/nix/Gemfile +0 -12
- data/nix/Gemfile.lock +0 -172
- data/nix/gemset.nix +0 -554
- data/nix/sources.json +0 -14
- data/nix/sources.nix +0 -194
- data/nix/update-gemset.sh +0 -7
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RailsEdgeTest
|
2
4
|
class Configuration
|
3
5
|
attr_accessor :elm_path, :edge_root_path, :printer
|
@@ -35,23 +37,17 @@ module RailsEdgeTest
|
|
35
37
|
end
|
36
38
|
|
37
39
|
def wrap_suite_execution(&block)
|
38
|
-
@before_suite_blocks.each
|
39
|
-
before_suit_block.call
|
40
|
-
end
|
40
|
+
@before_suite_blocks.each(&:call)
|
41
41
|
|
42
42
|
block.call
|
43
43
|
end
|
44
44
|
|
45
45
|
def wrap_edge_execution(&edge)
|
46
|
-
@before_each_blocks.each
|
47
|
-
before_each_block.call
|
48
|
-
end
|
46
|
+
@before_each_blocks.each(&:call)
|
49
47
|
|
50
48
|
edge.call
|
51
49
|
|
52
|
-
@after_each_blocks.each
|
53
|
-
after_each_block.call
|
54
|
-
end
|
50
|
+
@after_each_blocks.each(&:call)
|
55
51
|
end
|
56
52
|
end
|
57
53
|
end
|
@@ -1,49 +1,53 @@
|
|
1
|
-
|
2
|
-
Action = Struct.new(:name, :controller) do
|
3
|
-
def initialize(*args)
|
4
|
-
super
|
5
|
-
@edges = {}
|
6
|
-
@let_handler = LetHandler.new
|
7
|
-
end
|
1
|
+
# frozen_string_literal: true
|
8
2
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
module RailsEdgeTest
|
4
|
+
module Dsl
|
5
|
+
Action = Struct.new(:name, :controller) do
|
6
|
+
def initialize(*args)
|
7
|
+
super
|
8
|
+
@edges = {}
|
9
|
+
@let_handler = LetHandler.new
|
10
|
+
end
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def edge(description, &block)
|
13
|
+
edge = Edge.new(description, self)
|
14
|
+
@edges[edge] = block
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
def let(title, &block)
|
18
|
+
@let_handler.add_definition(title, &block)
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
def generate(title, &block)
|
22
|
+
@let_handler.add_definition("generate_#{title}", &block)
|
23
|
+
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
def __edges
|
26
|
+
@edges
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
def __let_handler
|
30
|
+
@let_handler
|
31
|
+
end
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
def controller_class
|
34
|
+
controller.controller_class
|
35
|
+
end
|
36
|
+
|
37
|
+
# support calling methods defined in controller
|
38
|
+
def method_missing(method_name, ...)
|
39
|
+
if controller.respond_to?(method_name)
|
40
|
+
controller.public_send(method_name, ...)
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
40
44
|
end
|
41
|
-
end
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
# always define respond_to_missing? when defining method_missing:
|
47
|
+
# https://thoughtbot.com/blog/always-define-respond-to-missing-when-overriding
|
48
|
+
def respond_to_missing?(method_name, include_private = false)
|
49
|
+
controller.respond_to?(method_name) || super
|
50
|
+
end
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -1,27 +1,31 @@
|
|
1
|
-
|
2
|
-
Controller = Struct.new(:controller_class) do
|
3
|
-
def initialize(*args)
|
4
|
-
super
|
5
|
-
@actions = []
|
6
|
-
@let_handler = LetHandler.new
|
7
|
-
end
|
1
|
+
# frozen_string_literal: true
|
8
2
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
3
|
+
module RailsEdgeTest
|
4
|
+
module Dsl
|
5
|
+
Controller = Struct.new(:controller_class) do
|
6
|
+
def initialize(*args)
|
7
|
+
super
|
8
|
+
@actions = []
|
9
|
+
@let_handler = LetHandler.new
|
10
|
+
end
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def action(name, &block)
|
13
|
+
new_action = Action.new(name, self)
|
14
|
+
new_action.instance_exec(&block)
|
15
|
+
@actions << new_action
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
def let(title, &block)
|
19
|
+
@let_handler.add_definition(title, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def __actions
|
23
|
+
@actions
|
24
|
+
end
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
def __let_handler
|
27
|
+
@let_handler
|
28
|
+
end
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
@@ -1,146 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'action_dispatch'
|
2
4
|
require 'action_controller'
|
3
5
|
require 'action_controller/test_case'
|
4
6
|
|
5
|
-
module RailsEdgeTest
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
delegate :controller_class, to: :action
|
14
|
-
delegate :session, to: :request
|
15
|
-
|
16
|
-
def request
|
17
|
-
@request ||= ActionController::TestRequest.create(controller_class)
|
18
|
-
end
|
19
|
-
|
20
|
-
# In the context of the edge, we want `controller` to be the rails controller
|
21
|
-
# instead of our own RailsEdgeTest::Dsl::Controller. In this way the user can
|
22
|
-
# directly access the rails controller within their edge.
|
23
|
-
def controller
|
24
|
-
@controller ||= controller_class.new
|
25
|
-
end
|
26
|
-
|
27
|
-
def response
|
28
|
-
@response
|
29
|
-
end
|
7
|
+
module RailsEdgeTest
|
8
|
+
module Dsl
|
9
|
+
Edge = Struct.new(:description, :action) do
|
10
|
+
def initialize(*args)
|
11
|
+
super
|
12
|
+
@let_cache = {}
|
13
|
+
end
|
30
14
|
|
31
|
-
|
32
|
-
|
33
|
-
end
|
15
|
+
delegate :controller_class, to: :action
|
16
|
+
delegate :session, to: :request
|
34
17
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
process(parameters)
|
39
|
-
end
|
18
|
+
def request
|
19
|
+
@request ||= ActionController::TestRequest.create(controller_class)
|
20
|
+
end
|
40
21
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
22
|
+
# In the context of the edge, we want `controller` to be the rails controller
|
23
|
+
# instead of our own RailsEdgeTest::Dsl::Controller. In this way the user can
|
24
|
+
# directly access the rails controller within their edge.
|
25
|
+
def controller
|
26
|
+
@controller ||= controller_class.new
|
27
|
+
end
|
46
28
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
request.headers['X-CSRF-Token'] = controller.send :form_authenticity_token
|
51
|
-
end
|
29
|
+
def response
|
30
|
+
@response
|
31
|
+
end
|
52
32
|
|
53
|
-
|
54
|
-
|
55
|
-
::Rails.application.routes,
|
56
|
-
controller_class.controller_path,
|
57
|
-
action.name.to_s,
|
58
|
-
parameters.stringify_keys!,
|
59
|
-
'',
|
60
|
-
''
|
61
|
-
)
|
62
|
-
|
63
|
-
response = ActionDispatch::Response.new.tap do |res|
|
64
|
-
res.request = request
|
33
|
+
def perform_get(parameters = {})
|
34
|
+
process(parameters)
|
65
35
|
end
|
66
36
|
|
67
|
-
|
68
|
-
|
37
|
+
def perform_post(parameters = {})
|
38
|
+
request.instance_variable_set(:@method, 'POST')
|
39
|
+
request.env['REQUEST_METHOD'] = 'POST'
|
40
|
+
process(parameters)
|
41
|
+
end
|
69
42
|
|
70
|
-
|
71
|
-
|
72
|
-
|
43
|
+
def perform_delete(parameters = {})
|
44
|
+
request.instance_variable_set(:@method, 'DELETE')
|
45
|
+
request.env['REQUEST_METHOD'] = 'DELETE'
|
46
|
+
process(parameters)
|
47
|
+
end
|
73
48
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
49
|
+
def set_authenticity_token
|
50
|
+
r = request
|
51
|
+
controller.instance_eval { @_request = r }
|
52
|
+
request.headers['X-CSRF-Token'] = controller.send :form_authenticity_token
|
53
|
+
end
|
79
54
|
|
80
|
-
|
81
|
-
|
55
|
+
def process(parameters = {})
|
56
|
+
request.assign_parameters(
|
57
|
+
::Rails.application.routes,
|
58
|
+
controller_class.controller_path,
|
59
|
+
action.name.to_s,
|
60
|
+
parameters.stringify_keys!,
|
61
|
+
'',
|
62
|
+
''
|
63
|
+
)
|
64
|
+
|
65
|
+
response = ActionDispatch::Response.new.tap do |res|
|
66
|
+
res.request = request
|
67
|
+
end
|
68
|
+
|
69
|
+
@response = controller.dispatch(action.name, request, response)
|
70
|
+
end
|
82
71
|
|
83
|
-
|
84
|
-
|
72
|
+
def produce_elm_file(module_name, ivar: nil)
|
73
|
+
json = produce_json(ivar: ivar)
|
74
|
+
json = json.gsub('\\', '\\\\\\\\') # unbelievably, this replaces \ with \\
|
85
75
|
|
76
|
+
filepath = File.join(
|
77
|
+
RailsEdgeTest.configuration.elm_path,
|
78
|
+
'Edge',
|
79
|
+
controller_class.name.gsub('::', '/')
|
80
|
+
)
|
86
81
|
|
87
|
-
|
88
|
-
|
89
|
-
"""
|
90
|
-
#{json}
|
91
|
-
"""
|
92
|
-
ELM
|
82
|
+
full_module_name =
|
83
|
+
"#{controller_class.name.gsub('::', '.')}.#{module_name}"
|
93
84
|
|
94
|
-
|
95
|
-
|
85
|
+
data = <<~ELM
|
86
|
+
module Edge.#{full_module_name} exposing (json)
|
96
87
|
|
97
|
-
private
|
98
88
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
89
|
+
json : String
|
90
|
+
json =
|
91
|
+
"""
|
92
|
+
#{json}
|
93
|
+
"""
|
94
|
+
ELM
|
103
95
|
|
104
|
-
|
105
|
-
fail "Request did not result in a successful (2xx) response!"
|
96
|
+
write_file(filepath, "#{module_name}.elm", data)
|
106
97
|
end
|
107
98
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
99
|
+
private
|
100
|
+
|
101
|
+
def produce_json(ivar: nil)
|
102
|
+
unless response
|
103
|
+
raise 'Must perform a request (for example `perform_get`) before attempting to produce a json file.'
|
104
|
+
end
|
105
|
+
|
106
|
+
raise 'Request did not result in a successful (2xx) response!' if response.is_a?(Array) && response[0] >= 300
|
107
|
+
|
108
|
+
ActiveSupport::JSON::Encoding.escape_html_entities_in_json = false
|
109
|
+
if ivar
|
110
|
+
value = controller.send(:instance_variable_get, ivar)
|
111
|
+
JSON.pretty_unparse(value.as_json)
|
112
|
+
elsif response[1]['Content-Type']&.starts_with?('application/json')
|
113
|
+
value = JSON.parse(response[2].body)
|
114
|
+
JSON.pretty_unparse(value)
|
115
|
+
else
|
116
|
+
response[2].body
|
117
|
+
end
|
117
118
|
end
|
118
|
-
end
|
119
119
|
|
120
|
-
|
121
|
-
|
120
|
+
def write_file(filepath, filename, data)
|
121
|
+
FileUtils.mkdir_p(filepath)
|
122
122
|
|
123
|
-
|
123
|
+
filepath = File.join(filepath, filename)
|
124
124
|
|
125
|
-
|
126
|
-
|
127
|
-
|
125
|
+
File.open(filepath, 'w') do |f|
|
126
|
+
f.write(data)
|
127
|
+
f.flush
|
128
|
+
end
|
128
129
|
end
|
129
|
-
end
|
130
130
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
131
|
+
# support calling methods defined in action
|
132
|
+
def method_missing(method_name, ...)
|
133
|
+
if action.respond_to?(method_name)
|
134
|
+
action.public_send(method_name, ...)
|
135
|
+
else
|
136
|
+
super
|
137
|
+
end
|
137
138
|
end
|
138
|
-
end
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
140
|
+
# always define respond_to_missing? when defining method_missing:
|
141
|
+
# https://thoughtbot.com/blog/always-define-respond-to-missing-when-overriding
|
142
|
+
def respond_to_missing?(method_name, include_private = false)
|
143
|
+
action.respond_to?(method_name) || super
|
144
|
+
end
|
144
145
|
end
|
145
146
|
end
|
146
147
|
end
|
@@ -1,22 +1,24 @@
|
|
1
|
-
|
2
|
-
class LetHandler
|
3
|
-
attr_reader :let_blocks
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module RailsEdgeTest
|
4
|
+
module Dsl
|
5
|
+
class LetHandler
|
6
|
+
attr_reader :let_blocks
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def initialize
|
9
|
+
@let_blocks = {}
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
unless block
|
16
|
-
fail NoMethodError, "no method or let block defined with name #{title}"
|
12
|
+
def add_definition(title, &block)
|
13
|
+
@let_blocks[title] = block
|
17
14
|
end
|
18
15
|
|
19
|
-
|
16
|
+
def execute(title)
|
17
|
+
block = @let_blocks[title]
|
18
|
+
raise NoMethodError, "no method or let block defined with name #{title}" unless block
|
19
|
+
|
20
|
+
block.call
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
data/lib/rails_edge_test/dsl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RailsEdgeTest
|
2
4
|
module Dsl
|
3
5
|
def controller(controller_class, &block)
|
@@ -16,7 +18,6 @@ module RailsEdgeTest
|
|
16
18
|
printer.begin_suite
|
17
19
|
|
18
20
|
RailsEdgeTest.configuration.wrap_suite_execution do
|
19
|
-
|
20
21
|
@controllers.each do |controller|
|
21
22
|
printer.begin_controller(controller)
|
22
23
|
|
@@ -40,7 +41,6 @@ module RailsEdgeTest
|
|
40
41
|
|
41
42
|
printer.end_controller
|
42
43
|
end
|
43
|
-
|
44
44
|
end
|
45
45
|
printer.end_suite
|
46
46
|
end
|
@@ -1,39 +1,39 @@
|
|
1
|
-
|
2
|
-
class Boring
|
3
|
-
def initialize
|
4
|
-
@count = 0
|
5
|
-
end
|
1
|
+
# frozen_string_literal: true
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
module RailsEdgeTest
|
4
|
+
module Printers
|
5
|
+
class Boring
|
6
|
+
def initialize
|
7
|
+
@count = 0
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def begin_suite
|
11
|
+
puts ''
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def end_suite
|
15
|
+
puts "\n#{@count} edge specs executed."
|
16
|
+
end
|
18
17
|
|
19
|
-
|
18
|
+
def begin_controller(_controller)
|
19
|
+
print '.'
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
+
def end_controller; end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def end_action
|
24
|
+
def begin_action(_action)
|
25
|
+
print '.'
|
26
|
+
end
|
28
27
|
|
29
|
-
|
28
|
+
def end_action; end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
def begin_edge(_edge)
|
31
|
+
print '.'
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
34
|
+
def end_edge
|
35
|
+
@count += 1
|
36
|
+
end
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -1,27 +1,23 @@
|
|
1
|
-
|
2
|
-
class Silent
|
3
|
-
def begin_suite
|
4
|
-
end
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
module RailsEdgeTest
|
4
|
+
module Printers
|
5
|
+
class Silent
|
6
|
+
def begin_suite; end
|
8
7
|
|
9
|
-
|
10
|
-
end
|
8
|
+
def end_suite; end
|
11
9
|
|
12
|
-
|
13
|
-
end
|
10
|
+
def begin_controller(_controller); end
|
14
11
|
|
15
|
-
|
16
|
-
end
|
12
|
+
def end_controller; end
|
17
13
|
|
18
|
-
|
19
|
-
end
|
14
|
+
def begin_action(_action); end
|
20
15
|
|
21
|
-
|
22
|
-
|
16
|
+
def end_action; end
|
17
|
+
|
18
|
+
def begin_edge(_edge); end
|
23
19
|
|
24
|
-
|
20
|
+
def end_edge; end
|
25
21
|
end
|
26
22
|
end
|
27
23
|
end
|