lesli_testing 1.4.1 → 1.4.2
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/lib/lesli_testing/core.rb +135 -0
- data/lib/lesli_testing/coverage.rb +0 -2
- data/lib/lesli_testing/engine.rb +13 -26
- data/lib/lesli_testing/environment.rb +44 -0
- data/lib/lesli_testing/fixtures.rb +303 -29
- data/lib/lesli_testing/helpers/response_integration_helper.rb +17 -10
- data/lib/lesli_testing/minitest/cli_reporter.rb +177 -67
- data/lib/lesli_testing/rails_integration.rb +31 -0
- data/lib/lesli_testing/testers.rb +71 -23
- data/lib/lesli_testing/version.rb +1 -1
- data/lib/lesli_testing.rb +12 -96
- data/lib/minitest/lesli_testing_plugin.rb +5 -1
- data/readme.md +112 -20
- metadata +5 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 433531e6c20b86725f4e12ec00bc0cb90116c21b84f8a8c74a463f6ab94a2164
|
|
4
|
+
data.tar.gz: f621205f275fef7decb3c1ec25f3af9888d78b8204e1fd5bf002da6bed4aafd6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67e13138ca3fd0a466cc9233884e763d3f686435f354ee9deab48890a3a71bb83279587921edaacc74a94757519051f6a7c4723a7a999380a2a744e20dd8f8e2
|
|
7
|
+
data.tar.gz: b7318e4af4ce796f07c3b2b6c458e3eb95c0f3a06a1bd598f397461f0a334d2d4a75e8a4ab1a2f98b99b89da97cd7b8d69c105d8240b00c67b640b2d0f6abc10
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
=begin
|
|
4
|
+
|
|
5
|
+
Lesli
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2026, Lesli Technologies, S. A.
|
|
8
|
+
|
|
9
|
+
This program is free software: you can redistribute it and/or modify
|
|
10
|
+
it under the terms of the GNU General Public License as published by
|
|
11
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
(at your option) any later version.
|
|
13
|
+
|
|
14
|
+
This program is distributed in the hope that it will be useful,
|
|
15
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
GNU General Public License for more details.
|
|
18
|
+
|
|
19
|
+
You should have received a copy of the GNU General Public License
|
|
20
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
21
|
+
|
|
22
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
|
23
|
+
|
|
24
|
+
Made with ♥ by LesliTech
|
|
25
|
+
Building a better future, one line of code at a time.
|
|
26
|
+
|
|
27
|
+
@contact hello@lesli.tech
|
|
28
|
+
@website https://www.lesli.tech
|
|
29
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
30
|
+
|
|
31
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
32
|
+
// ·
|
|
33
|
+
=end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
require_relative "version"
|
|
37
|
+
require_relative "environment"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
module LesliTesting
|
|
41
|
+
class Error < StandardError; end
|
|
42
|
+
|
|
43
|
+
class << self
|
|
44
|
+
|
|
45
|
+
attr_accessor :app_module;
|
|
46
|
+
attr_accessor :app_name;
|
|
47
|
+
attr_writer :options
|
|
48
|
+
|
|
49
|
+
def app(name, options = {})
|
|
50
|
+
configure(name, options.merge(coverage_profile: "app"))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def engine(name, options = {})
|
|
54
|
+
engine_options = options.dup
|
|
55
|
+
engine_target = engine_options.delete(:engine) || name
|
|
56
|
+
|
|
57
|
+
configure(
|
|
58
|
+
name,
|
|
59
|
+
engine_options.merge(
|
|
60
|
+
coverage_profile: "engine",
|
|
61
|
+
engine_target: engine_target
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def gem(name, options = {})
|
|
67
|
+
configure(name, options.merge(coverage_profile: "gem"))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def profile
|
|
71
|
+
@options && @options[:coverage_profile]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def options
|
|
77
|
+
@options ||= options_default
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def options_default
|
|
81
|
+
{
|
|
82
|
+
coverage_profile: "app",
|
|
83
|
+
coverage_missing_len: 25,
|
|
84
|
+
coverage_min_coverage: 90
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def configure(name, options)
|
|
89
|
+
self.app_name = name
|
|
90
|
+
self.options = options_default.merge(options)
|
|
91
|
+
configure_coverage()
|
|
92
|
+
configure_reporter()
|
|
93
|
+
configure_rails_integrations()
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def configure_coverage()
|
|
97
|
+
|
|
98
|
+
return unless LesliTesting::Environment.enabled?("COVERAGE")
|
|
99
|
+
return if defined?(SimpleCov) && SimpleCov.started_in_this_process?
|
|
100
|
+
|
|
101
|
+
require_relative "coverage"
|
|
102
|
+
|
|
103
|
+
# Start Coverage
|
|
104
|
+
LesliTesting::Coverage.start(
|
|
105
|
+
self.app_name,
|
|
106
|
+
profile: self.options[:coverage_profile],
|
|
107
|
+
missing_len: self.options[:coverage_missing_len],
|
|
108
|
+
min_coverage: self.options[:coverage_min_coverage]
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def configure_reporter
|
|
113
|
+
require "minitest"
|
|
114
|
+
require "termline" unless defined?(Termline)
|
|
115
|
+
require "minitest/lesli_testing_plugin"
|
|
116
|
+
|
|
117
|
+
# Force Minitest to know about Lesli Minitest reporter plugin
|
|
118
|
+
unless Minitest.extensions.include?("lesli_testing")
|
|
119
|
+
Minitest.register_plugin("lesli_testing")
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def configure_rails_integrations
|
|
124
|
+
return if self.options[:coverage_profile] == "gem"
|
|
125
|
+
|
|
126
|
+
require_relative "rails_integration"
|
|
127
|
+
LesliTesting::RailsIntegration.install!(
|
|
128
|
+
profile: self.options[:coverage_profile],
|
|
129
|
+
project_name: self.app_name,
|
|
130
|
+
engine_target: self.options[:engine_target],
|
|
131
|
+
options: self.options
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -35,7 +35,6 @@ Building a better future, one line of code at a time.
|
|
|
35
35
|
|
|
36
36
|
# Load code coverage tools
|
|
37
37
|
require "simplecov"
|
|
38
|
-
require "simplecov-html"
|
|
39
38
|
require "simplecov-console"
|
|
40
39
|
require "simplecov-cobertura"
|
|
41
40
|
require_relative "simplecov/profiles"
|
|
@@ -50,7 +49,6 @@ module LesliTesting
|
|
|
50
49
|
# Add coverage formatters
|
|
51
50
|
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
|
52
51
|
SimpleCov::Formatter::CoberturaFormatter,
|
|
53
|
-
SimpleCov::Formatter::HTMLFormatter,
|
|
54
52
|
SimpleCov::Formatter::Console
|
|
55
53
|
])
|
|
56
54
|
|
data/lib/lesli_testing/engine.rb
CHANGED
|
@@ -32,35 +32,22 @@ Building a better future, one line of code at a time.
|
|
|
32
32
|
|
|
33
33
|
module LesliTesting
|
|
34
34
|
class Engine < ::Rails::Engine
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
# Only run this if we are in the test environment
|
|
38
|
-
unless Rails.env.production?
|
|
35
|
+
class << self
|
|
36
|
+
attr_reader :engine_target
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
begin
|
|
45
|
-
# Find the constant for the gem's Engine
|
|
46
|
-
gem_engine = "#{gem_name}::Engine".safe_constantize
|
|
38
|
+
def configure(engine_target:)
|
|
39
|
+
@engine_target = engine_target
|
|
40
|
+
end
|
|
41
|
+
end
|
|
47
42
|
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
initializer "lesli_testing.load_required_migrations", after: :load_config_initializers do |app|
|
|
44
|
+
next unless Rails.env.test?
|
|
45
|
+
next unless LesliTesting::Engine.engine_target
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
app.config.paths["db/migrate"] << migration_path
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
rescue StandardError => e
|
|
60
|
-
puts "LesliTesting: Could not load migrations for #{gem_name}: #{e.message}"
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
47
|
+
LesliTesting::Fixtures.configure_migration_paths(
|
|
48
|
+
app,
|
|
49
|
+
engine_target: LesliTesting::Engine.engine_target
|
|
50
|
+
)
|
|
64
51
|
end
|
|
65
52
|
end
|
|
66
53
|
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
=begin
|
|
4
|
+
|
|
5
|
+
Lesli
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2026, Lesli Technologies, S. A.
|
|
8
|
+
|
|
9
|
+
This program is free software: you can redistribute it and/or modify
|
|
10
|
+
it under the terms of the GNU General Public License as published by
|
|
11
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
(at your option) any later version.
|
|
13
|
+
|
|
14
|
+
This program is distributed in the hope that it will be useful,
|
|
15
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
GNU General Public License for more details.
|
|
18
|
+
|
|
19
|
+
You should have received a copy of the GNU General Public License
|
|
20
|
+
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
21
|
+
|
|
22
|
+
Lesli · Ruby on Rails SaaS Development Framework.
|
|
23
|
+
|
|
24
|
+
Made with ♥ by LesliTech
|
|
25
|
+
Building a better future, one line of code at a time.
|
|
26
|
+
|
|
27
|
+
@contact hello@lesli.tech
|
|
28
|
+
@website https://www.lesli.tech
|
|
29
|
+
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
30
|
+
|
|
31
|
+
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
32
|
+
// ·
|
|
33
|
+
=end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
module LesliTesting
|
|
37
|
+
module Environment
|
|
38
|
+
TRUE_VALUES = %w[true 1 yes].freeze
|
|
39
|
+
|
|
40
|
+
def self.enabled?(name, env: ENV)
|
|
41
|
+
TRUE_VALUES.include?(env[name].to_s.strip.downcase)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -32,40 +32,314 @@ Building a better future, one line of code at a time.
|
|
|
32
32
|
|
|
33
33
|
module LesliTesting
|
|
34
34
|
module Fixtures
|
|
35
|
+
LESLI_FIXTURE_CLASSES = {
|
|
36
|
+
lesli_users: "Lesli::User",
|
|
37
|
+
lesli_accounts: "Lesli::Account"
|
|
38
|
+
}.freeze
|
|
39
|
+
|
|
35
40
|
class << self
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
if
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
41
|
+
def install!(profile: "app", engine_name: nil, options: {})
|
|
42
|
+
@configuration = build_configuration(profile, engine_name, options)
|
|
43
|
+
return if @installed
|
|
44
|
+
|
|
45
|
+
ActiveSupport.on_load(
|
|
46
|
+
:active_support_test_case,
|
|
47
|
+
run_once: true,
|
|
48
|
+
yield: true
|
|
49
|
+
) do |test_case|
|
|
50
|
+
configure_test_case(test_case, load_sets: true)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
ActiveSupport.on_load(
|
|
54
|
+
:action_dispatch_integration_test,
|
|
55
|
+
run_once: true,
|
|
56
|
+
yield: true
|
|
57
|
+
) do |test_case|
|
|
58
|
+
configure_test_case(test_case, load_sets: false)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
ActiveSupport.on_load(
|
|
62
|
+
:active_record,
|
|
63
|
+
run_once: true,
|
|
64
|
+
yield: true
|
|
65
|
+
) do
|
|
66
|
+
configure_migration_paths
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
@installed = true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def load_fixtures_for_engine(engine_module, test_case: nil)
|
|
73
|
+
test_case ||= ActiveSupport::TestCase if defined?(ActiveSupport::TestCase)
|
|
74
|
+
raise ArgumentError, "A Rails test case is required" unless test_case
|
|
75
|
+
|
|
76
|
+
configure_test_case(
|
|
77
|
+
test_case,
|
|
78
|
+
engine_module: engine_module,
|
|
79
|
+
load_sets: true
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def configure_migration_paths(application = nil, engine_target: nil)
|
|
84
|
+
configuration = @configuration
|
|
85
|
+
return [] unless configuration
|
|
86
|
+
return [] unless configuration[:profile] == "engine"
|
|
87
|
+
return [] unless configuration[:migrations][:enabled]
|
|
88
|
+
return [] unless test_environment?
|
|
89
|
+
|
|
90
|
+
application ||= Rails.application if defined?(Rails.application)
|
|
91
|
+
paths = migration_paths(application, engine_target: engine_target)
|
|
92
|
+
|
|
93
|
+
add_application_migration_paths(application, paths)
|
|
94
|
+
add_active_record_migration_paths(paths)
|
|
95
|
+
|
|
96
|
+
paths
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def test_environment?
|
|
102
|
+
return false unless defined?(Rails)
|
|
103
|
+
return false unless Rails.respond_to?(:env)
|
|
104
|
+
|
|
105
|
+
Rails.env.respond_to?(:test?) && Rails.env.test?
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def build_configuration(profile, engine_name, options)
|
|
109
|
+
fixture_options = options.fetch(:fixtures, {})
|
|
110
|
+
migration_options = options.fetch(:migrations, {})
|
|
111
|
+
default_shared = default_shared_engines(profile, engine_name)
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
profile: profile,
|
|
115
|
+
fixtures: build_fixture_configuration(
|
|
116
|
+
fixture_options,
|
|
117
|
+
profile,
|
|
118
|
+
engine_name,
|
|
119
|
+
default_shared
|
|
120
|
+
),
|
|
121
|
+
migrations: build_migration_configuration(
|
|
122
|
+
migration_options,
|
|
123
|
+
engine_name,
|
|
124
|
+
default_shared
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def build_fixture_configuration(options, profile, engine_name, default_shared)
|
|
130
|
+
return { enabled: false } if options == false
|
|
131
|
+
|
|
132
|
+
default_owner = engine_name if profile == "engine"
|
|
133
|
+
owner = options.fetch(:owner, default_owner)
|
|
134
|
+
shared = (default_shared + Array(options[:shared])).uniq
|
|
135
|
+
default_classes = if includes_lesli_fixtures?(owner, shared)
|
|
136
|
+
LESLI_FIXTURE_CLASSES
|
|
137
|
+
else
|
|
138
|
+
{}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
{
|
|
142
|
+
enabled: true,
|
|
143
|
+
owner: owner,
|
|
144
|
+
path: options[:path],
|
|
145
|
+
file_path: options[:file_path],
|
|
146
|
+
shared: shared,
|
|
147
|
+
shared_paths: Array(options[:shared_paths]),
|
|
148
|
+
sets: options.fetch(:sets, profile == "engine" ? :all : nil),
|
|
149
|
+
classes: default_classes.merge(options.fetch(:classes, {}))
|
|
150
|
+
}
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def build_migration_configuration(options, engine_name, default_shared)
|
|
154
|
+
return { enabled: false } if options == false
|
|
155
|
+
|
|
156
|
+
{
|
|
157
|
+
enabled: true,
|
|
158
|
+
owner: options.fetch(:owner, engine_name),
|
|
159
|
+
owner_explicit: options.key?(:owner),
|
|
160
|
+
include_dummy: options.fetch(:include_dummy, true),
|
|
161
|
+
include_owner: options.fetch(:include_owner, true),
|
|
162
|
+
shared: (default_shared + Array(options[:shared])).uniq,
|
|
163
|
+
paths: Array(options[:paths])
|
|
164
|
+
}
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def default_shared_engines(profile, engine_name)
|
|
168
|
+
return ["Lesli"] if profile == "app"
|
|
169
|
+
return [] unless profile == "engine"
|
|
170
|
+
return [] if ["Lesli", "Lesli::Engine"].include?(engine_name.to_s)
|
|
171
|
+
|
|
172
|
+
["Lesli"]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def includes_lesli_fixtures?(owner, shared)
|
|
176
|
+
[owner, *shared].any? do |reference|
|
|
177
|
+
["Lesli", "Lesli::Engine"].include?(reference.to_s)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def configure_test_case(test_case, engine_module: nil, load_sets:)
|
|
182
|
+
configuration = @configuration
|
|
183
|
+
return [] unless configuration
|
|
184
|
+
|
|
185
|
+
fixture_configuration = configuration[:fixtures]
|
|
186
|
+
return [] unless fixture_configuration[:enabled]
|
|
187
|
+
|
|
188
|
+
owner_engine = engine_module || resolve_engine(fixture_configuration[:owner])
|
|
189
|
+
configured_paths = fixture_paths(owner_engine, fixture_configuration)
|
|
190
|
+
|
|
191
|
+
include_active_record_fixtures(test_case)
|
|
192
|
+
assign_fixture_paths(test_case, configured_paths, configuration[:profile])
|
|
193
|
+
assign_file_fixture_path(test_case, owner_engine, fixture_configuration)
|
|
194
|
+
configure_fixture_sets(test_case, fixture_configuration) if load_sets
|
|
195
|
+
|
|
196
|
+
configured_paths
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def include_active_record_fixtures(test_case)
|
|
200
|
+
return unless defined?(ActiveRecord::TestFixtures)
|
|
201
|
+
return if test_case < ActiveRecord::TestFixtures
|
|
202
|
+
|
|
203
|
+
test_case.include(ActiveRecord::TestFixtures)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def fixture_paths(owner_engine, configuration)
|
|
207
|
+
paths = []
|
|
208
|
+
paths << expand_path(configuration[:path]) if configuration[:path]
|
|
209
|
+
paths << engine_path(owner_engine, "test", "fixtures") unless configuration[:path]
|
|
210
|
+
|
|
211
|
+
configuration[:shared].each do |shared_engine|
|
|
212
|
+
paths << engine_path(resolve_engine(shared_engine), "test", "fixtures")
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
paths.concat(configuration[:shared_paths].map { |path| expand_path(path) })
|
|
216
|
+
paths.compact.uniq
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def assign_fixture_paths(test_case, configured_paths, profile)
|
|
220
|
+
if test_case.respond_to?(:fixture_paths=)
|
|
221
|
+
current_paths = if test_case.respond_to?(:fixture_paths)
|
|
222
|
+
Array(test_case.fixture_paths)
|
|
223
|
+
else
|
|
224
|
+
[]
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
paths = if profile == "engine"
|
|
228
|
+
configured_paths + current_paths
|
|
229
|
+
else
|
|
230
|
+
current_paths + configured_paths
|
|
231
|
+
end
|
|
232
|
+
test_case.fixture_paths = paths.compact.uniq
|
|
233
|
+
elsif test_case.respond_to?(:class_attribute)
|
|
234
|
+
test_case.class_attribute :fixture_paths, default: configured_paths
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def assign_file_fixture_path(test_case, owner_engine, configuration)
|
|
239
|
+
return unless test_case.respond_to?(:file_fixture_path=)
|
|
240
|
+
|
|
241
|
+
file_path = configuration[:file_path]
|
|
242
|
+
file_path ||= engine_path(owner_engine, "test", "fixtures", "files") if owner_engine
|
|
243
|
+
test_case.file_fixture_path = expand_path(file_path) if file_path
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def configure_fixture_sets(test_case, configuration)
|
|
247
|
+
if test_case.respond_to?(:set_fixture_class) && configuration[:classes].any?
|
|
248
|
+
test_case.set_fixture_class(configuration[:classes])
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
sets = configuration[:sets]
|
|
252
|
+
return unless sets
|
|
253
|
+
return unless test_case.respond_to?(:fixtures)
|
|
254
|
+
|
|
255
|
+
sets == :all ? test_case.fixtures(:all) : test_case.fixtures(*Array(sets))
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def migration_paths(application, engine_target: nil)
|
|
259
|
+
configuration = @configuration[:migrations]
|
|
260
|
+
paths = []
|
|
261
|
+
|
|
262
|
+
if configuration[:include_dummy] && application&.respond_to?(:root)
|
|
263
|
+
paths << File.join(application.root.to_s, "db", "migrate")
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
if configuration[:include_owner]
|
|
267
|
+
owner = if configuration[:owner_explicit]
|
|
268
|
+
configuration[:owner]
|
|
269
|
+
else
|
|
270
|
+
engine_target || configuration[:owner]
|
|
64
271
|
end
|
|
272
|
+
paths << engine_path(resolve_engine(owner), "db", "migrate")
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
configuration[:shared].each do |shared_engine|
|
|
276
|
+
paths << engine_path(resolve_engine(shared_engine), "db", "migrate")
|
|
65
277
|
end
|
|
278
|
+
|
|
279
|
+
paths.concat(configuration[:paths].map { |path| expand_path(path) })
|
|
280
|
+
paths.compact.select { |path| Dir.exist?(path) }.uniq
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def add_application_migration_paths(application, paths)
|
|
284
|
+
return unless application&.respond_to?(:config)
|
|
285
|
+
|
|
286
|
+
rails_paths = application.config.paths["db/migrate"]
|
|
287
|
+
return unless rails_paths
|
|
288
|
+
|
|
289
|
+
registered_paths = rails_paths.expanded.map { |path| expand_path(path) }
|
|
290
|
+
paths.each do |path|
|
|
291
|
+
expanded_path = expand_path(path)
|
|
292
|
+
next if registered_paths.include?(expanded_path)
|
|
293
|
+
|
|
294
|
+
rails_paths << path
|
|
295
|
+
registered_paths << expanded_path
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def add_active_record_migration_paths(paths)
|
|
300
|
+
return unless defined?(ActiveRecord::Migrator)
|
|
301
|
+
return unless ActiveRecord::Migrator.respond_to?(:migrations_paths=)
|
|
302
|
+
|
|
303
|
+
current_paths = if ActiveRecord::Migrator.respond_to?(:migrations_paths)
|
|
304
|
+
Array(ActiveRecord::Migrator.migrations_paths)
|
|
305
|
+
else
|
|
306
|
+
[]
|
|
307
|
+
end
|
|
308
|
+
registered_paths = current_paths.map { |path| expand_path(path) }
|
|
309
|
+
missing_paths = paths.reject do |path|
|
|
310
|
+
registered_paths.include?(expand_path(path))
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
ActiveRecord::Migrator.migrations_paths = current_paths + missing_paths
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def resolve_engine(reference)
|
|
317
|
+
return reference if reference.respond_to?(:root)
|
|
318
|
+
return if reference.nil?
|
|
319
|
+
|
|
320
|
+
constant = constantize(reference.to_s)
|
|
321
|
+
return constant if constant&.respond_to?(:root)
|
|
322
|
+
return unless constant&.const_defined?(:Engine)
|
|
323
|
+
|
|
324
|
+
constant.const_get(:Engine)
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def constantize(name)
|
|
328
|
+
name.split("::").reject(&:empty?).inject(Object) do |namespace, constant_name|
|
|
329
|
+
namespace.const_get(constant_name)
|
|
330
|
+
end
|
|
331
|
+
rescue NameError
|
|
332
|
+
nil
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def engine_path(engine_module, *parts)
|
|
336
|
+
return unless engine_module&.respond_to?(:root)
|
|
337
|
+
|
|
338
|
+
File.join(engine_module.root.to_s, *parts)
|
|
66
339
|
end
|
|
67
340
|
|
|
68
|
-
def
|
|
341
|
+
def expand_path(path)
|
|
342
|
+
File.expand_path(path.to_s)
|
|
69
343
|
end
|
|
70
344
|
end
|
|
71
345
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Lesli
|
|
4
4
|
|
|
5
|
-
Copyright (c)
|
|
5
|
+
Copyright (c) 2026, Lesli Technologies, S. A.
|
|
6
6
|
|
|
7
7
|
This program is free software: you can redistribute it and/or modify
|
|
8
8
|
it under the terms of the GNU General Public License as published by
|
|
@@ -30,17 +30,24 @@ Building a better future, one line of code at a time.
|
|
|
30
30
|
// ·
|
|
31
31
|
=end
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
require "json"
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
module LesliTesting
|
|
36
|
+
module ResponseIntegrationHelper
|
|
37
|
+
|
|
38
|
+
# return the body of a request response parsed as JSON
|
|
39
|
+
def response_json(http_response = response)
|
|
40
|
+
JSON.parse(http_response.body.blank? ? "{}" : http_response.body)
|
|
41
|
+
end
|
|
39
42
|
|
|
43
|
+
def assert_successful_json_response(http_response = response)
|
|
44
|
+
assert_predicate(http_response, :successful?)
|
|
45
|
+
assert_equal("application/json", http_response.media_type)
|
|
46
|
+
end
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
# test a standard successful response for lesli 3
|
|
49
|
+
def expect_response_with_successful(http_response = response)
|
|
50
|
+
assert_successful_json_response(http_response)
|
|
51
|
+
end
|
|
45
52
|
end
|
|
46
53
|
end
|