Skip to content

Commit 219317c

Browse files
authored
100% test coverage. (#88)
1 parent 5b437f0 commit 219317c

18 files changed

Lines changed: 385 additions & 3 deletions

File tree

.github/workflows/test-coverage.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
- macos
2121

2222
ruby:
23+
- "3.3"
2324
- ruby
2425

2526
steps:

lib/console/event/spawn.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def initialize(environment, arguments, options)
6161
#
6262
# @parameter status [Process::Status] The status of the command.
6363
def status=(status)
64-
@end_time = Time.now
64+
@end_time = self.now
6565
@status = status
6666
end
6767

@@ -100,6 +100,12 @@ def emit(*arguments, **options)
100100
options[:severity] ||= :info
101101
super
102102
end
103+
104+
private
105+
106+
def now
107+
Clock.now
108+
end
103109
end
104110
end
105111
end

lib/console/resolver.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,13 @@ def waiting?
103103
#
104104
# @parameter trace_point [TracePoint] The trace point that triggered the event.
105105
def resolve(trace_point)
106-
if block = @names.delete(trace_point.self.to_s)
107-
block.call(trace_point.self)
106+
resolve_class(trace_point.self)
107+
end
108+
109+
# @parameter klass [Class] The class that was resolved.
110+
def resolve_class(klass)
111+
if block = @names.delete(klass.to_s)
112+
block.call(klass)
108113
end
109114

110115
if @names.empty?

test/console/compatible/logger.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,11 @@
5050

5151
expect(stream.string).to be(:include?, '"request_id": 137')
5252
end
53+
54+
it "ignores messages below the log level" do
55+
logger.level = Logger::WARN
56+
57+
expect(logger.add(Logger::INFO, "Hello World")).to be == true
58+
expect(stream.string).to be == ""
59+
end
5360
end

test/console/event/failure.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,23 @@ def detailed_message(...)
1414
end
1515
end
1616

17+
class PlainError
18+
def class
19+
StandardError
20+
end
21+
22+
def message
23+
"Plain error!"
24+
end
25+
26+
def backtrace
27+
[]
28+
end
29+
30+
def cause
31+
end
32+
end
33+
1734
describe Console::Event::Failure do
1835
include Sus::Fixtures::Console::CapturedLogger
1936

@@ -59,5 +76,44 @@ def detailed_message(...)
5976

6077
expect(failure.exception).to be == error
6178
end
79+
80+
it "logs failures directly" do
81+
Console::Event::Failure.log("It failed", error, name: "failure")
82+
83+
expect(console_capture.last).to have_keys(
84+
severity: be == :error,
85+
subject: be == "It failed",
86+
name: be == "failure",
87+
)
88+
end
89+
90+
it "includes nested causes" do
91+
begin
92+
begin
93+
raise RuntimeError, "Cause!"
94+
rescue
95+
raise TestError, "Test error!"
96+
end
97+
rescue TestError => error
98+
expect(Console::Event::Failure.for(error).to_hash).to have_keys(
99+
cause: have_keys(
100+
class: be == "RuntimeError",
101+
message: be =~ /Cause!/
102+
)
103+
)
104+
end
105+
end
106+
end
107+
108+
it "returns nil if the default root cannot be determined" do
109+
expect(Dir).to receive(:getwd).and_raise(Errno::EMFILE)
110+
111+
expect(subject.default_root).to be_nil
112+
end
113+
114+
it "uses the basic message when detailed messages are unavailable" do
115+
expect(subject.new(PlainError.new).to_hash).to have_keys(
116+
message: be == "Plain error!"
117+
)
62118
end
63119
end

test/console/event/spawn.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,38 @@
2323
)
2424
)
2525
end
26+
27+
it "records completion status and duration" do
28+
event = subject.for("ls")
29+
status = Object.new
30+
31+
def status.to_i
32+
0
33+
end
34+
35+
expect(event).to receive(:now).and_return(event.start_time + 1)
36+
37+
event.status = status
38+
39+
expect(event.end_time).to be == event.start_time + 1
40+
expect(event.status).to be == status
41+
expect(event.duration).to be == 1
42+
expect(event.to_hash).to have_keys(
43+
status: be == 0,
44+
duration: be == 1
45+
)
46+
end
47+
48+
it "uses the monotonic clock for completion time" do
49+
event = subject.for("ls")
50+
status = Object.new
51+
52+
def status.to_i
53+
0
54+
end
55+
56+
event.status = status
57+
58+
expect(event.duration).to be >= 0
59+
end
2660
end

test/console/filter.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ def before
5959
end
6060
end
6161

62+
with "#all!" do
63+
it "enables all messages" do
64+
logger.level = Console::Logger::FATAL
65+
logger.all!
66+
67+
logger.debug(MySubject, "Hello World")
68+
expect(output).to be(:include?, "Hello World")
69+
end
70+
end
71+
6272
with "#clear" do
6373
it "can't clear non-class subjects" do
6474
expect do

test/console/output/default.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,11 @@ def object.tty?
3232
output = subject.new(stream, env: {"TERM" => "xterm-256color", "DISPLAY" => ":0"})
3333
expect(output).to be_a(Console::Output::Serialized)
3434
end
35+
36+
it "should use XTerm output for GitHub Actions" do
37+
output = subject.new(stream, env: {"GITHUB_ACTIONS" => "true"})
38+
expect(output).to be_a(Console::Output::Terminal)
39+
expect(output.terminal).to be_a(Console::Terminal::XTerm)
40+
end
3541
end
3642
end

test/console/output/null.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2026, by Samuel Williams.
5+
6+
require "console/output/null"
7+
8+
describe Console::Output::Null do
9+
let(:output) {subject.new}
10+
11+
it "is its own last output" do
12+
expect(output.last_output).to be_equal(output)
13+
end
14+
15+
it "ignores calls" do
16+
expect(output.call("Hello World")).to be_nil
17+
end
18+
end

test/console/output/sensitive.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,18 @@
4040
expect(output).not.to be(:include?, "Samuel Williams")
4141
end
4242
end
43+
44+
with "sensitive: callable" do
45+
it "filters strings using the callable" do
46+
logger.call("token", sensitive: ->(value){value.upcase})
47+
48+
expect(output).to be(:include?, "TOKEN")
49+
end
50+
end
51+
52+
it "redacts nested arguments" do
53+
logger.call("subject", ["token"], {password: "token"}, :token)
54+
55+
expect(output).not.to be(:include?, "token")
56+
end
4357
end

0 commit comments

Comments
 (0)