Class: Rubydex::Linter::RuleTestCase
- Inherits:
-
Minitest::Test
- Object
- Minitest::Test
- Rubydex::Linter::RuleTestCase
- Defined in:
- lib/rubydex/linter/rule_test_case.rb
Overview
Base test case for Rubydex linter rules.
Add expected diagnostics below the source:
assert_diagnostics(<<~RUBY)
FOO = 123
^^^ Failure: FOO
RUBY
The carets mark the diagnostic range. Use ^{} for a zero-width range.
Pass a hash to test multiple files. Repeat an annotation line for each message line.
By default, FooTest tests the Foo rule.
Constant Summary collapse
- DEFAULT_FILE =
: String
"test.rb"- ANNOTATION_PATTERN =
: Regexp
/\A(?<indent>\s*)(?<carets>(?<!\\)\^+|\^\{\})(?:\s(?<message>.*))?\z/
Instance Attribute Summary collapse
-
#workspace_path ⇒ Object
readonly
: String.
Instance Method Summary collapse
-
#add_shared_source(sources) ⇒ Object
Registers sources that are loaded into the graph for every assertion.
-
#assert_diagnostics(*args, &rule_builder) ⇒ Object
Runs the rule and compares every diagnostic location with the inline annotations in the corresponding source.
-
#assert_handles_missing_required_dependency(dependency, *args, after_excluding: [], &rule_builder) ⇒ Object
: ( | String, | *(String | Hash[String | Symbol, String]), | ?after_excluding: Array, | ) ?{ (Graph) -> CustomRule } -> void.
-
#assert_no_diagnostics(*args, &rule_builder) ⇒ Object
Runs the rule and asserts no diagnostics are reported in the provided sources.
-
#ignored_diagnostic_files ⇒ Object
Returns absolute file paths whose diagnostics should be ignored.
-
#initialize(name) ⇒ RuleTestCase
constructor
: (String) -> void.
-
#rule_class ⇒ Object
: -> singleton(CustomRule).
-
#rule_config ⇒ Object
: -> LinterConfig.
-
#teardown ⇒ Object
: -> void.
Constructor Details
#initialize(name) ⇒ RuleTestCase
: (String) -> void
35 36 37 38 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 35 def initialize(name) super @workspace_path = File.realpath(Dir.mktmpdir("rubydex-rule-test-")) #: String end |
Instance Attribute Details
#workspace_path ⇒ Object (readonly)
: String
32 33 34 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 32 def workspace_path @workspace_path end |
Instance Method Details
#add_shared_source(sources) ⇒ Object
Registers sources that are loaded into the graph for every assertion. Shared sources must not contain caret annotations. Test-specific sources win on filename collision. : (Hash[String, String]) -> void
63 64 65 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 63 def add_shared_source(sources) shared_sources.merge!(sources) end |
#assert_diagnostics(*args, &rule_builder) ⇒ Object
Runs the rule and compares every diagnostic location with the inline annotations in the corresponding source. : (*(String | Hash[String | Symbol, String])) ?{ (Graph) -> CustomRule } -> Array
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 81 def assert_diagnostics(*args, &rule_builder) sources = validated_shared_source.merge(normalize_sources(args)) clean_per_file, expected_per_file = write_sources(sources) diagnostics = run_rule(&rule_builder) actual_per_file = annotations_for_diagnostics(diagnostics, clean_per_file) surprise_files = actual_per_file.keys - clean_per_file.keys - ignored_diagnostic_files refute_predicate( surprise_files, :any?, "Diagnostics in unexpected files: #{surprise_files.inspect}", ) clean_per_file.each do |filename, clean| expected = render_annotated(clean, expected_per_file[filename] || []) actual = render_annotated(clean, actual_per_file[filename] || []) assert_equal(expected, actual, "Mismatch in #{filename}") end diagnostics end |
#assert_handles_missing_required_dependency(dependency, *args, after_excluding: [], &rule_builder) ⇒ Object
: ( | String, | *(String | Hash[String | Symbol, String]), | ?after_excluding: Array, | ) ?{ (Graph) -> CustomRule } -> void
123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 123 def assert_handles_missing_required_dependency(dependency, *args, after_excluding: [], &rule_builder) sources = validated_shared_source.dup #: Hash[String, String] after_excluding.each { |filename| sources.delete(filename) } sources.merge!(normalize_sources(args)) write_sources(sources) error = assert_raises(MissingGraphDependencyError) do run_rule(&rule_builder) end = MissingGraphDependencyError.new(rule_class.rule_name, dependency). assert_equal(, error.) end |
#assert_no_diagnostics(*args, &rule_builder) ⇒ Object
Runs the rule and asserts no diagnostics are reported in the provided sources. Sources must not contain caret annotations. : (*(String | Hash[String | Symbol, String])) ?{ (Graph) -> CustomRule } -> Array
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 107 def assert_no_diagnostics(*args, &rule_builder) sources = validated_shared_source.merge(normalize_sources(args)) write_sources(sources) diagnostics = run_rule(&rule_builder) ignored = ignored_diagnostic_files reported = diagnostics.reject { |diagnostic| ignored.include?(diagnostic.location.to_file_path) } assert_empty(reported, "Expected no diagnostics, got #{reported.map(&:message).inspect}") diagnostics end |
#ignored_diagnostic_files ⇒ Object
Returns absolute file paths whose diagnostics should be ignored. : -> Array
69 70 71 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 69 def ignored_diagnostic_files @ignored_diagnostic_files ||= [] #: Array[String]? end |
#rule_class ⇒ Object
: -> singleton(CustomRule)
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 48 def rule_class @rule_class ||= begin name = self.class.to_s.delete_suffix("Test") if name == self.class.to_s raise "Could not infer rule class from #{self.class}; override `#rule_class`" end Object.const_get(name) #: as singleton(CustomRule) end #: singleton(CustomRule)? end |
#rule_config ⇒ Object
: -> LinterConfig
74 75 76 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 74 def rule_config @rule_config ||= LinterConfig.new({}) #: LinterConfig? end |
#teardown ⇒ Object
: -> void
41 42 43 44 45 |
# File 'lib/rubydex/linter/rule_test_case.rb', line 41 def teardown super ensure FileUtils.remove_entry(workspace_path) end |