tdd-guard-rspec 0.1.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 +7 -0
- data/lib/tdd_guard_rspec/formatter.rb +127 -0
- metadata +85 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3cad067cd532fad7f91309f8026eaaab5337c88f139d5f97b3242d68fe1d801c
|
|
4
|
+
data.tar.gz: 7db1c42445d642dda3511b6897f1e6bb06cfa7f08b39605c5dd085410f5f4312
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 76febe048a73141057a088baf3527d29ebdcf2bbe6b57e0fe17d967d39f8e5a527cd7fdf9d3046e8b7881479d62600104fd4e96f36cf1e0843d4ee51c77fa40b
|
|
7
|
+
data.tar.gz: 4790dc1eed3f738bc17cd9210b971aa60152bce66099af796f9cf34cc8b3a17ef36491a8d0bcf958db86a565455bf7d51a990701d2bd03f11ac956271af4e2a8
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
require "rspec/core/formatters/base_formatter"
|
|
6
|
+
|
|
7
|
+
module TddGuardRspec
|
|
8
|
+
# RSpec formatter that captures test results for TDD Guard validation.
|
|
9
|
+
# Mirrors the pytest reporter's single-class architecture.
|
|
10
|
+
class Formatter < RSpec::Core::Formatters::BaseFormatter
|
|
11
|
+
RSpec::Core::Formatters.register self,
|
|
12
|
+
:example_passed,
|
|
13
|
+
:example_failed,
|
|
14
|
+
:example_pending,
|
|
15
|
+
:message,
|
|
16
|
+
:dump_summary,
|
|
17
|
+
:close
|
|
18
|
+
|
|
19
|
+
DEFAULT_DATA_DIR = ".claude/tdd-guard/data"
|
|
20
|
+
|
|
21
|
+
def initialize(output)
|
|
22
|
+
super(output)
|
|
23
|
+
@test_results = []
|
|
24
|
+
@load_errors = []
|
|
25
|
+
@errors_outside = 0
|
|
26
|
+
@storage_dir = determine_storage_dir
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def example_passed(notification)
|
|
30
|
+
record_example(notification.example, "passed")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def example_failed(notification)
|
|
34
|
+
example = notification.example
|
|
35
|
+
errors = [{ "message" => notification.exception.message }]
|
|
36
|
+
record_example(example, "failed", errors)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def example_pending(notification)
|
|
40
|
+
record_example(notification.example, "skipped")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def message(notification)
|
|
44
|
+
msg = notification.message
|
|
45
|
+
@load_errors << msg if msg.include?("An error occurred while loading")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def dump_summary(notification)
|
|
49
|
+
@errors_outside = notification.errors_outside_of_examples_count
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def close(_notification)
|
|
53
|
+
add_load_error_results if @test_results.empty? && @errors_outside > 0
|
|
54
|
+
|
|
55
|
+
modules_map = {}
|
|
56
|
+
@test_results.each do |test|
|
|
57
|
+
module_path = test["fullName"].split("::").first
|
|
58
|
+
modules_map[module_path] ||= { "moduleId" => module_path, "tests" => [] }
|
|
59
|
+
modules_map[module_path]["tests"] << test
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
result = { "testModules" => modules_map.values }
|
|
63
|
+
|
|
64
|
+
FileUtils.mkdir_p(@storage_dir)
|
|
65
|
+
File.write(File.join(@storage_dir, "test.json"), JSON.pretty_generate(result))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def record_example(example, state, errors = nil)
|
|
71
|
+
file_path = example.file_path.sub(%r{^\./}, "")
|
|
72
|
+
test = {
|
|
73
|
+
"name" => example.description,
|
|
74
|
+
"fullName" => "#{file_path}::#{example.full_description}",
|
|
75
|
+
"state" => state
|
|
76
|
+
}
|
|
77
|
+
test["errors"] = errors if errors
|
|
78
|
+
@test_results << test
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def add_load_error_results
|
|
82
|
+
@load_errors.each do |error_msg|
|
|
83
|
+
file_path = extract_file_path(error_msg)
|
|
84
|
+
error_name = extract_error_name(error_msg)
|
|
85
|
+
@test_results << {
|
|
86
|
+
"name" => error_name,
|
|
87
|
+
"fullName" => "#{file_path}::#{error_name}",
|
|
88
|
+
"state" => "failed",
|
|
89
|
+
"errors" => [{ "message" => error_msg.strip }]
|
|
90
|
+
}
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def extract_file_path(error_msg)
|
|
95
|
+
match = error_msg.match(/An error occurred while loading (.+)\./)
|
|
96
|
+
return "unknown" unless match
|
|
97
|
+
|
|
98
|
+
match[1].sub(%r{^\./}, "").strip
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def extract_error_name(error_msg)
|
|
102
|
+
match = error_msg.match(/^(\w+Error):\s*(.+?)$/m)
|
|
103
|
+
return "LoadError" unless match
|
|
104
|
+
|
|
105
|
+
"#{match[1]}: #{match[2].strip}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def determine_storage_dir
|
|
109
|
+
project_root = ENV["TDD_GUARD_PROJECT_ROOT"]
|
|
110
|
+
return DEFAULT_DATA_DIR unless project_root && !project_root.empty?
|
|
111
|
+
return DEFAULT_DATA_DIR unless absolute_path?(project_root)
|
|
112
|
+
return DEFAULT_DATA_DIR unless cwd_within?(project_root)
|
|
113
|
+
|
|
114
|
+
File.join(project_root, DEFAULT_DATA_DIR)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def absolute_path?(path)
|
|
118
|
+
File.absolute_path?(path)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def cwd_within?(root)
|
|
122
|
+
expanded = File.expand_path(root)
|
|
123
|
+
cwd = Dir.pwd
|
|
124
|
+
cwd == expanded || cwd.start_with?("#{expanded}/")
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: tdd-guard-rspec
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Hiro-Chiba
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-04-03 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rspec-core
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rspec
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: climate_control
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.0'
|
|
55
|
+
description: RSpec formatter that captures test results for TDD Guard validation.
|
|
56
|
+
email:
|
|
57
|
+
executables: []
|
|
58
|
+
extensions: []
|
|
59
|
+
extra_rdoc_files: []
|
|
60
|
+
files:
|
|
61
|
+
- lib/tdd_guard_rspec/formatter.rb
|
|
62
|
+
homepage: https://github.com/nizos/tdd-guard
|
|
63
|
+
licenses:
|
|
64
|
+
- MIT
|
|
65
|
+
metadata: {}
|
|
66
|
+
post_install_message:
|
|
67
|
+
rdoc_options: []
|
|
68
|
+
require_paths:
|
|
69
|
+
- lib
|
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 3.3.0
|
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '0'
|
|
80
|
+
requirements: []
|
|
81
|
+
rubygems_version: 3.3.15
|
|
82
|
+
signing_key:
|
|
83
|
+
specification_version: 4
|
|
84
|
+
summary: RSpec formatter for TDD Guard - enforces Test-Driven Development principles
|
|
85
|
+
test_files: []
|