lesli_testing 1.2.2 → 1.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 582a2365a947f562ffdbd75bfe09f5af077bb1309b12cd9adeb29c8886d13472
4
- data.tar.gz: a73846f568ac913e621716a49273000631fbbb9255e40e74e59db3f49b2cd41c
3
+ metadata.gz: e1cf4a585e7dba931395ea96d8d0c34a5043d4d89f04ad76a54efa9bfd3859ca
4
+ data.tar.gz: 23ad0d2b61b1ae38c6eb564259f034a2c06cf577b8432a9d3ec061effd223bbc
5
5
  SHA512:
6
- metadata.gz: 9ddde3d544c159212ddcaf4aae80e9f0cd1294165cae78de2dacda04a7a667bf208479a64c38b6d65c4872cdf5229935bfacc3bdd80b4db0dc1be9a66a7f9aed
7
- data.tar.gz: a035d7f5b72ab485137995eeb8c70102c4ac5e2dd1220a590c40f9bd4732dcdbaadce35bc89f3689f7d103816078570cd053479c99dcb27c466e6e4dc209f920
6
+ metadata.gz: 6639e33ce003c35998736b06e908b8e8ff44b19a68e4d24978f4dcbb848c084313579d7c9a9b673591b7d3de21b7c5d3bd00a97664faa737c5f6ccb05e90f03a
7
+ data.tar.gz: d31df87681c091a836d4d6b1c7f77c6dbb8f76fb776d637ed5c628106c3c18241123845b5538dd45501b47ac66a572a263df1c7f4a68c644c8a3ab8fa82bcac8
@@ -34,6 +34,21 @@ module LesliTesting
34
34
  module Config
35
35
  def self.apply(engine_module = nil)
36
36
 
37
+ if defined?(Lesli)
38
+ # Load fixtures from Lesli
39
+ if ActiveSupport::TestCase.respond_to?(:fixture_paths=)
40
+ ActiveSupport::TestCase.fixture_paths = [ Lesli::Engine.root.join("test", "fixtures").to_s ]
41
+ ActionDispatch::IntegrationTest.fixture_paths = ActiveSupport::TestCase.fixture_paths
42
+ ActiveSupport::TestCase.file_fixture_path = Lesli::Engine.root.join("test", "fixtures", "files").to_s
43
+
44
+ # IMPORTANT: attach fixture sets to namespaced models BEFORE loading fixtures
45
+ ActiveSupport::TestCase.set_fixture_class(
46
+ lesli_users: "Lesli::User",
47
+ lesli_accounts: "Lesli::Account"
48
+ )
49
+ end
50
+ end
51
+
37
52
  # Load dummy app for unit testing
38
53
  # Run tests across all the engines: LESLI_INTEGRATION_TEST=true rails test
39
54
  # Run tests for the current engine: rails test
@@ -45,12 +60,6 @@ module LesliTesting
45
60
  ActionDispatch::IntegrationTest.fixture_paths = ActiveSupport::TestCase.fixture_paths
46
61
  ActiveSupport::TestCase.file_fixture_path = engine_module.root.join("test", "fixtures", "files").to_s
47
62
 
48
- # IMPORTANT: attach fixture sets to namespaced models BEFORE loading fixtures
49
- ActiveSupport::TestCase.set_fixture_class(
50
- lesli_users: "Lesli::User",
51
- lesli_accounts: "Lesli::Account"
52
- )
53
-
54
63
  ActiveSupport::TestCase.fixtures :all
55
64
  end
56
65
  end
@@ -42,7 +42,7 @@ module LesliTesting
42
42
  ])
43
43
 
44
44
  # Define the limit to allow missing tested code
45
- SimpleCov::Formatter::Console.missing_len = 10
45
+ SimpleCov::Formatter::Console.missing_len = min_coverage
46
46
 
47
47
  SimpleCov.start "rails" do
48
48
  command_name engine_name
@@ -40,11 +40,13 @@ require "simplecov-cobertura"
40
40
  require "minitest/lesli_testing_plugin"
41
41
  require_relative "reporters/cli_reporter"
42
42
 
43
+
43
44
  # Force Minitest to know about Lesli Minitest reporter plugin
44
45
  unless Minitest.extensions.include?("lesli_testing")
45
46
  Minitest.register_plugin("lesli_testing")
46
47
  end
47
48
 
49
+
48
50
  # Load test configuration and test helper modules
49
51
  require_relative "coverage"
50
52
  require_relative "testers"
@@ -55,19 +57,26 @@ module LesliTesting
55
57
 
56
58
  class << self
57
59
 
58
- def start_coverage!(engine_module = nil, options = {})
59
- return if defined?(SimpleCov) && SimpleCov.running
60
+ attr_accessor :engine_module;
61
+
62
+ def configure(engine_module = nil)
63
+ self.engine_module = engine_module
64
+ end
60
65
 
61
- name = engine_module ? engine_module.name : "RailsApp"
66
+ def configure_coverage(options)
67
+
68
+ engine_name = self.engine_module ? self.engine_module.name : "RailsApp"
69
+
70
+ return if defined?(SimpleCov) && SimpleCov.running
62
71
 
63
72
  # Start Coverage
64
- LesliTesting::Coverage.start(name, options[:min_coverage] || 40)
65
- end
73
+ LesliTesting::Coverage.start(engine_name, options[:min_coverage] || 40)
74
+ end
66
75
 
67
- def configure_tests!(engine_module = nil)
76
+ def configure_engine()
68
77
 
69
78
  # Apply Minitest/Reporters/Paths
70
- LesliTesting::Config.apply(engine_module)
79
+ LesliTesting::Config.apply(self.engine_module)
71
80
  end
72
81
  end
73
82
  end
@@ -7,43 +7,54 @@ module LesliTesting
7
7
  class CliReporter < Minitest::StatisticsReporter
8
8
  def start
9
9
  super
10
+
11
+ Termline.br
12
+
10
13
  Termline.m(
11
- Termline::Style.colorize(" Running Lesli tests...", :blue),
12
- Termline::Style.colorize(" -> For a better result run test over a clean database", :blue),
13
- Termline::Style.colorize(" -> You can use: rake dev:db:reset", :blue)
14
+ Termline::Style.colorize("Running Lesli tests...", :blue),
15
+ Termline::Style.colorize("-> For a better result run test over a clean database", :blue),
16
+ Termline::Style.colorize("-> You can use: rake dev:db:reset", :blue)
14
17
  )
15
- Termline.br
18
+
19
+ Termline.br 2
16
20
  end
17
21
 
18
22
  def record(test)
19
23
  super
20
24
 
21
- assert_color = :green
22
- assert_color = :yellow if test.assertions < 5
23
- assert_color = :red if test.assertions < 2
24
-
25
- parts = []
26
- parts << Termline::Style.colorize('['+Time.now.strftime('%H:%M:%S:%L')+']', :gray)
27
-
28
- case test.result_code
29
- when "."
30
- parts << Termline::Style.colorize("PASS", :green)
31
- when "F"
32
- parts << Termline::Style.colorize("FAIL", :red)
33
- when "E"
34
- parts << Termline::Style.colorize("ERROR", :red)
35
- when "S"
36
- parts << Termline::Style.colorize("SKIP", :yellow)
25
+ # Only print the line if the configuration allows it
26
+ return if ENV["QUIET"]
27
+
28
+ # Map result codes to styles
29
+ status_map = {
30
+ "." => [:green, "PASS"],
31
+ "S" => [:yellow, "SKIP"],
32
+ "E" => [:red, "ERROR"],
33
+ "F" => [:red, "FAIL"]
34
+ }
35
+ color, label = status_map[test.result_code] || [:gray, "????"]
36
+
37
+ # Determine assertion health
38
+ assert_color = case test.assertions
39
+ when 0..1 then :red
40
+ when 2..4 then :yellow
41
+ else :green
37
42
  end
38
43
 
39
- parts << '::'
40
- parts << Termline::Style.colorize(test.klass, :blue)
41
- parts << '->'
42
- parts << Termline::Style.colorize(test.name, :skyblue)
43
- parts << Termline::Style.colorize("(#{ test.assertions} asserts)", assert_color)
44
- parts << Termline::Style.colorize("#{"(%.2fs)" % test.time}", :red) if test.time > 1
44
+ parts = [
45
+ Termline::Style.colorize("[#{Time.now.strftime('%H:%M:%S')}]", :gray),
46
+ Termline::Style.colorize(label, color),
47
+ "::",
48
+ Termline::Style.colorize(test.klass, :blue),
49
+ "->",
50
+ Termline::Style.colorize(test.name, :skyblue),
51
+ Termline::Style.colorize("(#{test.assertions} asserts)", assert_color)
52
+ ]
53
+
54
+ # Add execution time per test
55
+ parts << Termline::Style.colorize("(%.2fs)" % test.time, :red) if test.time > 1
45
56
 
46
- puts(parts.compact.join(" ").strip)
57
+ puts(parts.join(" "))
47
58
  end
48
59
 
49
60
  def report
@@ -86,7 +97,7 @@ module LesliTesting
86
97
  Termline.danger("Test suite failed", tag:'FAILURE')
87
98
  end
88
99
 
89
- Termline.br
100
+ Termline.br 2
90
101
 
91
102
  print_failure_details if total_failures.positive? || total_errors.positive?
92
103
 
@@ -104,7 +115,8 @@ module LesliTesting
104
115
  failure_tag = failure.is_a?(Minitest::Assertion) ? "FAILURE" : "ERROR"
105
116
  failure_msg = "#{result.class}##{result.name} (#{result.assertions} asserts)"
106
117
 
107
- location_file = "#{result.source_location.first} (line: #{result.source_location.second})"
118
+ file, line = result.source_location
119
+ location_file = file ? "#{file} (line: #{line})" : "Location unknown"
108
120
 
109
121
  Termline.br
110
122
  Termline.line(6)
@@ -116,6 +128,7 @@ module LesliTesting
116
128
  if failure.is_a?(Minitest::Assertion)
117
129
  result.failure.message.to_s.lines.each do |message|
118
130
  puts(parse_minitest_assertion_messages(message))
131
+ #puts(parse_minitest_assertion_messages2(message))
119
132
  end
120
133
  end
121
134
  end
@@ -123,11 +136,75 @@ module LesliTesting
123
136
  Termline.br
124
137
  end
125
138
 
126
- def parse_minitest_assertion_messages message
127
- msg = message.strip
128
- return Termline::Style.colorize(" + #{msg}", :green) if msg.start_with? "Expected:"
129
- return Termline::Style.colorize(" - #{msg}", :red) if msg.start_with? "Actual:"
130
- return Termline::Style.colorize(" #{Termline::Style.icon(:warning)} #{msg}", :yellow)
139
+ def parse_minitest_assertion_messages(message)
140
+ message.to_s.rstrip.lines.map do |line|
141
+ msg = line.strip
142
+
143
+ case msg
144
+
145
+ # 1. Unified Diff Headers
146
+ # Covers Minitest diff output like:
147
+ # --- expected
148
+ # +++ actual
149
+ # @@ -1 +1 @@
150
+ when /^--- /
151
+ Termline::Style.colorize("#{msg}:", :red)
152
+
153
+ when /^\+\+\+ /
154
+ Termline::Style.colorize("++#{msg}:", :green)
155
+
156
+ when /^@@ /
157
+ Termline::Style.colorize("#{msg}", :skyblue)
158
+
159
+ # 2. Unified Diff Content Lines
160
+ # Covers actual changed lines inside the diff, like:
161
+ # -[:lesli_support_item_tasks, "lesli_support"]
162
+ # +[:lesli_support_items_tasks, "lesli_support"]
163
+ # The negative lookahead avoids matching the diff headers above.
164
+ when /^-(?!-)/
165
+ Termline::Style.colorize(" #{Termline::Style.icon(:remove)}-#{msg}", :red)
166
+
167
+ when /^\+(?!\+)/
168
+ Termline::Style.colorize(" #{Termline::Style.icon(:add)}+#{msg}", :green)
169
+
170
+ # 3. Boolean/Nil Failures
171
+ # Covers cases like:
172
+ # Expected true to be nil
173
+ # Expected false to be truthy
174
+ # Expected "abc" to be empty
175
+ when /Expected (.*) to be (nil|truthy|falsey)/, /Expected (.*) to be (.*)/
176
+ Termline::Style.colorize(" #{Termline::Style.icon(:info)} #{msg}", :skyblue)
177
+
178
+ # 4. Standard Expected vs Actual Output
179
+ # Covers simple assertion output like:
180
+ # Expected: 1
181
+ # Actual: 2
182
+ when /^Expected:?\s+/
183
+ Termline::Style.colorize(" #{Termline::Style.icon(:add)} #{msg}", :green)
184
+
185
+ when /^Actual:?\s+/
186
+ Termline::Style.colorize(" #{Termline::Style.icon(:remove)} #{msg}", :red)
187
+
188
+ # 5. Rails Difference Failures
189
+ # Covers assertions like:
190
+ # "User.count" didn't change by 1
191
+ # actual change was 0
192
+ when /"(.*)" didn't change by (.*)/, /actual change was (.*)/
193
+ Termline::Style.colorize(" #{Termline::Style.icon(:warning)} #{msg}", :yellow)
194
+
195
+ # 6. Collection/Count Failures
196
+ # Covers collection assertions like:
197
+ # Expected 5 elements, found 2
198
+ # Expected exactly 1 nodes
199
+ when /Expected (.*) elements?, found (.*)/, /Expected exactly (.*) nodes/
200
+ Termline::Style.colorize(" #{Termline::Style.icon(:list)} #{msg}", :magenta)
201
+
202
+ # 7. Fallback for Custom or Unrecognized Messages
203
+ # Covers anything else not matched above.
204
+ else
205
+ Termline::Style.colorize(" #{Termline::Style.icon(:arrow_right)} #{msg}", :gray)
206
+ end
207
+ end.join("\n")
131
208
  end
132
209
  end
133
210
  end
@@ -37,24 +37,29 @@ require_relative "helpers/response_integration_helper"
37
37
  #
38
38
  module LesliTesting
39
39
 
40
- class IntegrationTester < ActionDispatch::IntegrationTest
41
- include ResponseIntegrationHelper
40
+ if defined?(ActionDispatch::IntegrationTest)
41
+ class IntegrationTester < ActionDispatch::IntegrationTest
42
+ include ResponseIntegrationHelper
43
+ end
42
44
  end
43
45
 
44
- class ViewTester < ActionView::TestCase
45
- # We use a hook to include the helpers only when the class is used.
46
- # This ensures Lesli core is fully loaded by Rails before we ask for the helpers.
47
- def self.inherited(subclass)
48
- super
49
- subclass.class_eval do
50
- include Lesli::HtmlHelper if defined?(Lesli::HtmlHelper)
51
- include Lesli::SystemHelper if defined?(Lesli::SystemHelper)
46
+ if defined?(ActionView::TestCase)
47
+ class ViewTester < ActionView::TestCase
48
+ # We use a hook to include the helpers only when the class is used.
49
+ # This ensures Lesli core is fully loaded by Rails before we ask for the helpers.
50
+ def self.inherited(subclass)
51
+ super
52
+ subclass.class_eval do
53
+ include Lesli::HtmlHelper if defined?(Lesli::HtmlHelper)
54
+ include Lesli::SystemHelper if defined?(Lesli::SystemHelper)
55
+ end
52
56
  end
53
57
  end
54
58
  end
55
59
 
56
- # Define the base classes inside the namespace
57
- class ModelTester < ActiveSupport::TestCase
58
- include ActiveSupport::Testing::TimeHelpers
60
+ if defined?(ActiveSupport::TestCase)
61
+ class ModelTester < ActiveSupport::TestCase
62
+ include ActiveSupport::Testing::TimeHelpers
63
+ end
59
64
  end
60
65
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LesliTesting
4
- VERSION = "1.2.2"
5
- BUILD = "1774678451"
4
+ VERSION = "1.2.4"
5
+ BUILD = "1775525290"
6
6
  end
@@ -1,11 +1,11 @@
1
1
  require "lesli_testing/reporters/cli_reporter"
2
2
 
3
3
  module Minitest
4
- def self.plugin_lesli_testing_options(opts, options)
5
- end
4
+ def self.plugin_lesli_testing_options(opts, options)
5
+ end
6
6
 
7
- def self.plugin_lesli_testing_init(options)
8
- reporter.reporters.clear if reporter.respond_to?(:reporters)
9
- reporter << LesliTesting::Reporters::CliReporter.new($stdout, options)
10
- end
7
+ def self.plugin_lesli_testing_init(options)
8
+ reporter.reporters.clear if reporter.respond_to?(:reporters)
9
+ reporter << LesliTesting::Reporters::CliReporter.new($stdout, options)
10
+ end
11
11
  end
data/readme.md CHANGED
@@ -10,11 +10,60 @@
10
10
 
11
11
  ### Quick start
12
12
 
13
+
14
+ **Install LesliTesting gem**
15
+
13
16
  ```shell
14
- # Add LesliAdmin engine gem
15
17
  bundle add lesli_testing
16
18
  ```
17
19
 
20
+ **Include LesliTesting in your rails/test/test_helper.rb**
21
+
22
+ ```ruby
23
+
24
+ # load lesli testing tools
25
+ require "lesli_testing/loader"
26
+
27
+
28
+ # register engine for testing
29
+ LesliTesting.configure(Lesli::Engine)
30
+
31
+
32
+ # initialize coverage
33
+ LesliTesting.configure_coverage({ :min_coverage => 10 })
34
+
35
+
36
+ # Loading dummy app
37
+ require_relative "../test/dummy/config/environment"
38
+ ActiveRecord::Migrator.migrations_paths = [ File.expand_path("../test/dummy/db/migrate", __dir__) ]
39
+ ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__)
40
+ require "rails/test_help"
41
+
42
+
43
+ # configure tests
44
+ LesliTesting.configure_engine()
45
+ ```
46
+
47
+ **Run your tests D:**
48
+
49
+ ```shell
50
+ rails test
51
+
52
+ # or
53
+
54
+ COVERAGE=true rails test
55
+ ```
56
+
57
+ **Result :D**
58
+
59
+ <div align="center">
60
+ <img
61
+ style="width:100%;max-width:800px;border-radius:6px;"
62
+ alt="LesliTesting screenshot" src="./docs/images/screenshot.png" />
63
+ </div>
64
+
65
+ <br />
66
+ <br />
18
67
 
19
68
  ### Documentation
20
69
  * [website](https://www.lesli.dev/)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lesli_testing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Lesli Development Team