smartest 0.1.0.alpha2 → 0.1.0.alpha3
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/CHANGELOG.md +2 -0
- data/DEVELOPMENT.md +1 -0
- data/README.md +36 -5
- data/SMARTEST_DESIGN.md +1 -1
- data/lib/smartest/dsl.rb +5 -1
- data/lib/smartest/init_generator.rb +61 -0
- data/lib/smartest/matcher_registry.rb +27 -0
- data/lib/smartest/runner.rb +8 -2
- data/lib/smartest/suite.rb +2 -1
- data/lib/smartest/version.rb +1 -1
- data/lib/smartest.rb +1 -0
- data/smartest/smartest_test.rb +182 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c1ce8aea4b74c7ca0de7f3a2b1472b79ea86849be91801e11922883b6423afdf
|
|
4
|
+
data.tar.gz: be5f8e88c1bd93eb061eb0a854b46a6c6094627b36cd22f8778026e35161992a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 864cea53cff77bf90e73bdf6528c9e6ff7ba633c89c8edbf011bd50552d9bf1aea606c0a9e4af83352847f88b1ca8571433987d2f933d20b50270b2d2b81079d
|
|
7
|
+
data.tar.gz: d587ffbf743f4fe75d8977346ae653fe2616ab70e4480453442f4677f7d4d6a4f84166f64c17b50417616693232149ef36214c8c12d530de41a9ff5f36c75a51
|
data/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
- Support per-test fixture caching and cleanup.
|
|
10
10
|
- Support suite-scoped fixtures through `suite_fixture`.
|
|
11
11
|
- Support `eq`, `include`, `be_nil`, and `raise_error` matchers.
|
|
12
|
+
- Support custom matcher modules through `use_matcher`.
|
|
13
|
+
- Generate an opt-in `PredicateMatcher` custom matcher for `be_<predicate>` calls.
|
|
12
14
|
- Add the `smartest` CLI.
|
|
13
15
|
- Add `--help` and `--version` CLI options.
|
|
14
16
|
- Use `smartest/**/*_test.rb` as the default CLI glob so Smartest can coexist with Minitest files under `test/`.
|
data/DEVELOPMENT.md
CHANGED
data/README.md
CHANGED
|
@@ -59,6 +59,8 @@ This creates:
|
|
|
59
59
|
```text
|
|
60
60
|
smartest/test_helper.rb
|
|
61
61
|
smartest/fixtures/
|
|
62
|
+
smartest/matchers/
|
|
63
|
+
smartest/matchers/predicate_matcher.rb
|
|
62
64
|
smartest/example_test.rb
|
|
63
65
|
```
|
|
64
66
|
|
|
@@ -171,6 +173,10 @@ be_nil
|
|
|
171
173
|
raise_error(ErrorClass)
|
|
172
174
|
```
|
|
173
175
|
|
|
176
|
+
Custom matcher modules can be registered with `use_matcher`. The generated
|
|
177
|
+
scaffold includes a `PredicateMatcher` custom matcher for `be_<predicate>` calls.
|
|
178
|
+
See [Matchers](documentation/docs/matchers.md).
|
|
179
|
+
|
|
174
180
|
## Fixtures
|
|
175
181
|
|
|
176
182
|
Fixtures are defined in classes.
|
|
@@ -184,9 +190,17 @@ class AppFixture < Smartest::Fixture
|
|
|
184
190
|
)
|
|
185
191
|
end
|
|
186
192
|
end
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Register fixture classes from `smartest/test_helper.rb`:
|
|
187
196
|
|
|
197
|
+
```ruby
|
|
188
198
|
use_fixture AppFixture
|
|
199
|
+
```
|
|
189
200
|
|
|
201
|
+
Tests request fixtures by keyword:
|
|
202
|
+
|
|
203
|
+
```ruby
|
|
190
204
|
test("user") do |user:|
|
|
191
205
|
expect(user.name).to eq("Alice")
|
|
192
206
|
end
|
|
@@ -337,8 +351,16 @@ class WebFixture < Smartest::Fixture
|
|
|
337
351
|
client
|
|
338
352
|
end
|
|
339
353
|
end
|
|
354
|
+
```
|
|
340
355
|
|
|
356
|
+
```ruby
|
|
357
|
+
# smartest/test_helper.rb
|
|
341
358
|
use_fixture WebFixture
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
```ruby
|
|
362
|
+
# smartest/web_test.rb
|
|
363
|
+
require "test_helper"
|
|
342
364
|
|
|
343
365
|
test("GET /me") do |logged_in_client:|
|
|
344
366
|
response = logged_in_client.get("/me")
|
|
@@ -369,7 +391,7 @@ server cleanup
|
|
|
369
391
|
|
|
370
392
|
## Registering fixture classes
|
|
371
393
|
|
|
372
|
-
Use `use_fixture`:
|
|
394
|
+
Use `use_fixture` from `smartest/test_helper.rb`:
|
|
373
395
|
|
|
374
396
|
```ruby
|
|
375
397
|
use_fixture AppFixture
|
|
@@ -429,6 +451,9 @@ smartest/
|
|
|
429
451
|
fixtures/
|
|
430
452
|
app_fixture.rb
|
|
431
453
|
web_fixture.rb
|
|
454
|
+
matchers/
|
|
455
|
+
predicate_matcher.rb
|
|
456
|
+
have_status_matcher.rb
|
|
432
457
|
example_test.rb
|
|
433
458
|
```
|
|
434
459
|
|
|
@@ -439,10 +464,18 @@ require "smartest/autorun"
|
|
|
439
464
|
Dir[File.join(__dir__, "fixtures", "**", "*.rb")].sort.each do |fixture_file|
|
|
440
465
|
require fixture_file
|
|
441
466
|
end
|
|
467
|
+
|
|
468
|
+
Dir[File.join(__dir__, "matchers", "**", "*.rb")].sort.each do |matcher_file|
|
|
469
|
+
require matcher_file
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
use_fixture WebFixture
|
|
473
|
+
use_matcher PredicateMatcher
|
|
442
474
|
```
|
|
443
475
|
|
|
444
|
-
The generated helper loads Ruby files under `smartest/fixtures/`
|
|
445
|
-
|
|
476
|
+
The generated helper loads Ruby files under `smartest/fixtures/` and
|
|
477
|
+
`smartest/matchers/` in sorted order. Register fixture classes and matcher
|
|
478
|
+
modules from the helper with `use_fixture` and `use_matcher`.
|
|
446
479
|
|
|
447
480
|
Example:
|
|
448
481
|
|
|
@@ -465,8 +498,6 @@ end
|
|
|
465
498
|
# smartest/example_test.rb
|
|
466
499
|
require "test_helper"
|
|
467
500
|
|
|
468
|
-
use_fixture WebFixture
|
|
469
|
-
|
|
470
501
|
test("GET /health") do |client:|
|
|
471
502
|
expect(client.get("/health").status).to eq(200)
|
|
472
503
|
end
|
data/SMARTEST_DESIGN.md
CHANGED
|
@@ -294,7 +294,7 @@ context.instance_exec(**fixtures, &block)
|
|
|
294
294
|
|
|
295
295
|
This keeps the top-level DSL small.
|
|
296
296
|
|
|
297
|
-
Only `test`, `fixture`, and `
|
|
297
|
+
Only `test`, `fixture`, `use_fixture`, and `use_matcher` need to be globally available when using `smartest/autorun`.
|
|
298
298
|
|
|
299
299
|
## Core architecture
|
|
300
300
|
|
data/lib/smartest/dsl.rb
CHANGED
|
@@ -17,6 +17,10 @@ module Smartest
|
|
|
17
17
|
Smartest.suite.fixture_classes.add(klass)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
def use_matcher(matcher_module)
|
|
21
|
+
Smartest.suite.matcher_modules.add(matcher_module)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private :test, :use_fixture, :use_matcher
|
|
21
25
|
end
|
|
22
26
|
end
|
|
@@ -13,6 +13,66 @@ module Smartest
|
|
|
13
13
|
Dir[File.join(__dir__, "fixtures", "**", "*.rb")].sort.each do |fixture_file|
|
|
14
14
|
require fixture_file
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
Dir[File.join(__dir__, "matchers", "**", "*.rb")].sort.each do |matcher_file|
|
|
18
|
+
require matcher_file
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
use_matcher PredicateMatcher
|
|
22
|
+
RUBY
|
|
23
|
+
"smartest/matchers/predicate_matcher.rb" => <<~RUBY,
|
|
24
|
+
# frozen_string_literal: true
|
|
25
|
+
|
|
26
|
+
module PredicateMatcher
|
|
27
|
+
def method_missing(name, *arguments, &block)
|
|
28
|
+
matcher_name = name.to_s
|
|
29
|
+
return super unless matcher_name.match?(/\\Abe_.+\\z/)
|
|
30
|
+
|
|
31
|
+
Matcher.new(matcher_name.delete_prefix("be_"), arguments, block)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def respond_to_missing?(name, include_private = false)
|
|
35
|
+
name.to_s.match?(/\\Abe_.+\\z/) || super
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class Matcher
|
|
39
|
+
def initialize(predicate_name, arguments, block)
|
|
40
|
+
@predicate_name = predicate_name
|
|
41
|
+
@predicate = "\#{predicate_name}?"
|
|
42
|
+
@arguments = arguments
|
|
43
|
+
@block = block
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def matches?(actual)
|
|
47
|
+
@actual = actual
|
|
48
|
+
return false unless actual.respond_to?(@predicate)
|
|
49
|
+
|
|
50
|
+
!!actual.public_send(@predicate, *@arguments, &@block)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def failure_message
|
|
54
|
+
return "expected \#{@actual.inspect} to respond to \#{@predicate}" unless @actual.respond_to?(@predicate)
|
|
55
|
+
|
|
56
|
+
"expected \#{@actual.inspect} to be \#{description}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def negated_failure_message
|
|
60
|
+
"expected \#{@actual.inspect} not to be \#{description}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def description
|
|
66
|
+
return @predicate_name if @arguments.empty?
|
|
67
|
+
|
|
68
|
+
"\#{@predicate_name} \#{argument_description}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def argument_description
|
|
72
|
+
@arguments.map(&:inspect).join(", ")
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
16
76
|
RUBY
|
|
17
77
|
"smartest/example_test.rb" => <<~RUBY
|
|
18
78
|
# frozen_string_literal: true
|
|
@@ -33,6 +93,7 @@ module Smartest
|
|
|
33
93
|
def run
|
|
34
94
|
create_directory("smartest")
|
|
35
95
|
create_directory("smartest/fixtures")
|
|
96
|
+
create_directory("smartest/matchers")
|
|
36
97
|
FILES.each { |path, contents| create_file(path, contents) }
|
|
37
98
|
|
|
38
99
|
@output.puts
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Smartest
|
|
4
|
+
class MatcherRegistry
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@matcher_modules = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def add(matcher_module)
|
|
12
|
+
unless matcher_module.is_a?(Module) && !matcher_module.is_a?(Class)
|
|
13
|
+
raise ArgumentError, "matcher must be a module"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
@matcher_modules << matcher_module unless @matcher_modules.include?(matcher_module)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def each(&block)
|
|
20
|
+
@matcher_modules.each(&block)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_a
|
|
24
|
+
@matcher_modules.dup
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/smartest/runner.rb
CHANGED
|
@@ -35,7 +35,7 @@ module Smartest
|
|
|
35
35
|
|
|
36
36
|
def run_one(test_case)
|
|
37
37
|
started_at = now
|
|
38
|
-
context =
|
|
38
|
+
context = build_context
|
|
39
39
|
fixture_set = nil
|
|
40
40
|
error = nil
|
|
41
41
|
cleanup_errors = []
|
|
@@ -69,11 +69,17 @@ module Smartest
|
|
|
69
69
|
def suite_fixture_set
|
|
70
70
|
@suite_fixture_set ||= FixtureSet.new(
|
|
71
71
|
@suite.fixture_classes,
|
|
72
|
-
context:
|
|
72
|
+
context: build_context,
|
|
73
73
|
scope: :suite
|
|
74
74
|
)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
+
def build_context
|
|
78
|
+
ExecutionContext.new.tap do |context|
|
|
79
|
+
@suite.matcher_modules.each { |matcher_module| context.extend(matcher_module) }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
77
83
|
def now
|
|
78
84
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
79
85
|
end
|
data/lib/smartest/suite.rb
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Smartest
|
|
4
4
|
class Suite
|
|
5
|
-
attr_reader :tests, :fixture_classes
|
|
5
|
+
attr_reader :tests, :fixture_classes, :matcher_modules
|
|
6
6
|
|
|
7
7
|
def initialize
|
|
8
8
|
@tests = TestRegistry.new
|
|
9
9
|
@fixture_classes = FixtureClassRegistry.new
|
|
10
|
+
@matcher_modules = MatcherRegistry.new
|
|
10
11
|
end
|
|
11
12
|
end
|
|
12
13
|
end
|
data/lib/smartest/version.rb
CHANGED
data/lib/smartest.rb
CHANGED
|
@@ -8,6 +8,7 @@ require_relative "smartest/test_registry"
|
|
|
8
8
|
require_relative "smartest/fixture_definition"
|
|
9
9
|
require_relative "smartest/fixture"
|
|
10
10
|
require_relative "smartest/fixture_class_registry"
|
|
11
|
+
require_relative "smartest/matcher_registry"
|
|
11
12
|
require_relative "smartest/fixture_set"
|
|
12
13
|
require_relative "smartest/suite"
|
|
13
14
|
require_relative "smartest/expectations"
|
data/smartest/smartest_test.rb
CHANGED
|
@@ -95,6 +95,58 @@ test("supports basic matchers") do
|
|
|
95
95
|
expect(status).to eq(0)
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
test("registers matcher modules for suite execution contexts") do
|
|
99
|
+
status_matcher = Class.new do
|
|
100
|
+
def initialize(expected)
|
|
101
|
+
@expected = expected
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def matches?(actual)
|
|
105
|
+
@actual = actual
|
|
106
|
+
actual.status == @expected
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def failure_message
|
|
110
|
+
"expected #{@actual.inspect} to have status #{@expected.inspect}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def negated_failure_message
|
|
114
|
+
"expected #{@actual.inspect} not to have status #{@expected.inspect}"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
custom_matchers = Module.new do
|
|
119
|
+
define_method(:have_status) do |expected|
|
|
120
|
+
status_matcher.new(expected)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
response = Struct.new(:status).new(200)
|
|
125
|
+
suite = Smartest::Suite.new
|
|
126
|
+
suite.matcher_modules.add(custom_matchers)
|
|
127
|
+
suite.tests.add(SmartestSelfTest.test_case("custom matcher", proc { expect(response).to have_status(200) }))
|
|
128
|
+
|
|
129
|
+
status, = SmartestSelfTest.run_suite(suite)
|
|
130
|
+
|
|
131
|
+
expect(status).to eq(0)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
test("rejects non-module matcher registrations") do
|
|
135
|
+
error = SmartestSelfTest.capture_error(ArgumentError) do
|
|
136
|
+
Smartest::MatcherRegistry.new.add(Object.new)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
expect(error.message).to include("matcher must be a module")
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
test("rejects class matcher registrations") do
|
|
143
|
+
error = SmartestSelfTest.capture_error(ArgumentError) do
|
|
144
|
+
Smartest::MatcherRegistry.new.add(Class.new)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
expect(error.message).to include("matcher must be a module")
|
|
148
|
+
end
|
|
149
|
+
|
|
98
150
|
test("resolves keyword fixture dependencies per test") do
|
|
99
151
|
calls = []
|
|
100
152
|
|
|
@@ -477,6 +529,72 @@ test("cli loads files and returns failure status") do
|
|
|
477
529
|
end
|
|
478
530
|
end
|
|
479
531
|
|
|
532
|
+
test("cli loads matcher files registered in test helper") do
|
|
533
|
+
Dir.mktmpdir do |dir|
|
|
534
|
+
smartest_dir = File.join(dir, "smartest")
|
|
535
|
+
matchers_dir = File.join(smartest_dir, "matchers")
|
|
536
|
+
FileUtils.mkdir_p(matchers_dir)
|
|
537
|
+
File.write(File.join(smartest_dir, "test_helper.rb"), <<~RUBY)
|
|
538
|
+
require "smartest/autorun"
|
|
539
|
+
|
|
540
|
+
Dir[File.join(__dir__, "matchers", "**", "*.rb")].sort.each do |matcher_file|
|
|
541
|
+
require matcher_file
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
use_matcher HaveStatusMatcher
|
|
545
|
+
RUBY
|
|
546
|
+
File.write(File.join(matchers_dir, "have_status_matcher.rb"), <<~RUBY)
|
|
547
|
+
module HaveStatusMatcher
|
|
548
|
+
class MatcherImpl
|
|
549
|
+
def initialize(expected)
|
|
550
|
+
@expected = expected
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
def matches?(actual)
|
|
554
|
+
@actual = actual
|
|
555
|
+
actual.status == @expected
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
def failure_message
|
|
559
|
+
"expected \#{@actual.inspect} to have status \#{@expected.inspect}"
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
def negated_failure_message
|
|
563
|
+
"expected \#{@actual.inspect} not to have status \#{@expected.inspect}"
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
def have_status(expected)
|
|
568
|
+
MatcherImpl.new(expected)
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
RUBY
|
|
572
|
+
|
|
573
|
+
File.write(File.join(smartest_dir, "sample_test.rb"), <<~RUBY)
|
|
574
|
+
require "test_helper"
|
|
575
|
+
|
|
576
|
+
Response = Struct.new(:status)
|
|
577
|
+
|
|
578
|
+
test("custom matcher") do
|
|
579
|
+
expect(Response.new(200)).to have_status(200)
|
|
580
|
+
end
|
|
581
|
+
RUBY
|
|
582
|
+
|
|
583
|
+
stdout, stderr, status = Open3.capture3(
|
|
584
|
+
{ "RUBYLIB" => File.expand_path("../lib", __dir__) },
|
|
585
|
+
"ruby",
|
|
586
|
+
File.expand_path("../exe/smartest", __dir__),
|
|
587
|
+
"smartest/sample_test.rb",
|
|
588
|
+
chdir: dir
|
|
589
|
+
)
|
|
590
|
+
|
|
591
|
+
expect(status.success?).to eq(true)
|
|
592
|
+
expect(stderr).to eq("")
|
|
593
|
+
expect(stdout).to include("custom matcher")
|
|
594
|
+
expect(stdout).to include("1 test, 1 passed, 0 failed")
|
|
595
|
+
end
|
|
596
|
+
end
|
|
597
|
+
|
|
480
598
|
test("cli runs tests matching a file line filter") do
|
|
481
599
|
Dir.mktmpdir do |dir|
|
|
482
600
|
smartest_dir = File.join(dir, "smartest")
|
|
@@ -645,11 +763,17 @@ test("cli initializes a runnable test scaffold") do
|
|
|
645
763
|
expect(stderr).to eq("")
|
|
646
764
|
expect(stdout).to include("create smartest")
|
|
647
765
|
expect(stdout).to include("create smartest/fixtures")
|
|
766
|
+
expect(stdout).to include("create smartest/matchers")
|
|
648
767
|
expect(stdout).to include("create smartest/test_helper.rb")
|
|
768
|
+
expect(stdout).to include("create smartest/matchers/predicate_matcher.rb")
|
|
649
769
|
expect(stdout).to include("create smartest/example_test.rb")
|
|
650
770
|
helper_contents = File.read(File.join(dir, "smartest/test_helper.rb"))
|
|
651
771
|
expect(helper_contents).to include('require "smartest/autorun"')
|
|
652
772
|
expect(helper_contents).to include('Dir[File.join(__dir__, "fixtures", "**", "*.rb")].sort.each')
|
|
773
|
+
expect(helper_contents).to include('Dir[File.join(__dir__, "matchers", "**", "*.rb")].sort.each')
|
|
774
|
+
expect(helper_contents).to include("use_matcher PredicateMatcher")
|
|
775
|
+
predicate_matcher_contents = File.read(File.join(dir, "smartest/matchers/predicate_matcher.rb"))
|
|
776
|
+
expect(predicate_matcher_contents).to include("module PredicateMatcher")
|
|
653
777
|
expect(File.read(File.join(dir, "smartest/example_test.rb"))).to include('require "test_helper"')
|
|
654
778
|
|
|
655
779
|
nested_fixtures_dir = File.join(dir, "smartest/fixtures/nested")
|
|
@@ -672,6 +796,54 @@ test("cli initializes a runnable test scaffold") do
|
|
|
672
796
|
end
|
|
673
797
|
RUBY
|
|
674
798
|
|
|
799
|
+
nested_matchers_dir = File.join(dir, "smartest/matchers/nested")
|
|
800
|
+
FileUtils.mkdir_p(nested_matchers_dir)
|
|
801
|
+
File.write(File.join(nested_matchers_dir, "auto_loaded_matcher.rb"), <<~RUBY)
|
|
802
|
+
module AutoLoadedMatcher
|
|
803
|
+
class Matcher
|
|
804
|
+
def initialize(expected)
|
|
805
|
+
@expected = expected
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
def matches?(actual)
|
|
809
|
+
@actual = actual
|
|
810
|
+
actual == @expected
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def failure_message
|
|
814
|
+
"expected \#{@actual.inspect} to auto-eq \#{@expected.inspect}"
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
def negated_failure_message
|
|
818
|
+
"expected \#{@actual.inspect} not to auto-eq \#{@expected.inspect}"
|
|
819
|
+
end
|
|
820
|
+
end
|
|
821
|
+
|
|
822
|
+
def auto_eq(expected)
|
|
823
|
+
Matcher.new(expected)
|
|
824
|
+
end
|
|
825
|
+
end
|
|
826
|
+
RUBY
|
|
827
|
+
|
|
828
|
+
File.write(File.join(dir, "smartest/auto_loaded_matcher_test.rb"), <<~RUBY)
|
|
829
|
+
require "test_helper"
|
|
830
|
+
|
|
831
|
+
use_matcher AutoLoadedMatcher
|
|
832
|
+
|
|
833
|
+
test("auto-loaded matcher") do
|
|
834
|
+
expect("loaded from smartest/matchers").to auto_eq("loaded from smartest/matchers")
|
|
835
|
+
end
|
|
836
|
+
RUBY
|
|
837
|
+
|
|
838
|
+
File.write(File.join(dir, "smartest/predicate_matcher_test.rb"), <<~RUBY)
|
|
839
|
+
require "test_helper"
|
|
840
|
+
|
|
841
|
+
test("generated predicate matcher") do
|
|
842
|
+
expect("").to be_empty
|
|
843
|
+
expect(2).to be_between(1, 3)
|
|
844
|
+
end
|
|
845
|
+
RUBY
|
|
846
|
+
|
|
675
847
|
run_stdout, run_stderr, run_status = Open3.capture3(
|
|
676
848
|
{ "RUBYLIB" => File.expand_path("../lib", __dir__) },
|
|
677
849
|
"ruby",
|
|
@@ -683,7 +855,9 @@ test("cli initializes a runnable test scaffold") do
|
|
|
683
855
|
expect(run_stderr).to eq("")
|
|
684
856
|
expect(run_stdout).to include("example")
|
|
685
857
|
expect(run_stdout).to include("auto-loaded fixture")
|
|
686
|
-
expect(run_stdout).to include("
|
|
858
|
+
expect(run_stdout).to include("auto-loaded matcher")
|
|
859
|
+
expect(run_stdout).to include("generated predicate matcher")
|
|
860
|
+
expect(run_stdout).to include("4 tests, 4 passed, 0 failed")
|
|
687
861
|
end
|
|
688
862
|
end
|
|
689
863
|
|
|
@@ -691,13 +865,17 @@ test("cli init does not overwrite existing scaffold files") do
|
|
|
691
865
|
Dir.mktmpdir do |dir|
|
|
692
866
|
smartest_dir = File.join(dir, "smartest")
|
|
693
867
|
fixture_dir = File.join(smartest_dir, "fixtures")
|
|
868
|
+
matcher_dir = File.join(smartest_dir, "matchers")
|
|
694
869
|
FileUtils.mkdir_p(fixture_dir)
|
|
870
|
+
FileUtils.mkdir_p(matcher_dir)
|
|
695
871
|
helper_path = File.join(smartest_dir, "test_helper.rb")
|
|
696
872
|
example_path = File.join(smartest_dir, "example_test.rb")
|
|
697
873
|
fixture_path = File.join(fixture_dir, "custom_fixture.rb")
|
|
874
|
+
matcher_path = File.join(matcher_dir, "predicate_matcher.rb")
|
|
698
875
|
File.write(helper_path, "# custom helper\n")
|
|
699
876
|
File.write(example_path, "# custom test\n")
|
|
700
877
|
File.write(fixture_path, "# custom fixture\n")
|
|
878
|
+
File.write(matcher_path, "# custom matcher\n")
|
|
701
879
|
|
|
702
880
|
stdout, stderr, status = Open3.capture3(
|
|
703
881
|
{ "RUBYLIB" => File.expand_path("../lib", __dir__) },
|
|
@@ -711,10 +889,13 @@ test("cli init does not overwrite existing scaffold files") do
|
|
|
711
889
|
expect(stderr).to eq("")
|
|
712
890
|
expect(stdout).to include("exist smartest")
|
|
713
891
|
expect(stdout).to include("exist smartest/fixtures")
|
|
892
|
+
expect(stdout).to include("exist smartest/matchers")
|
|
714
893
|
expect(stdout).to include("exist smartest/test_helper.rb")
|
|
894
|
+
expect(stdout).to include("exist smartest/matchers/predicate_matcher.rb")
|
|
715
895
|
expect(stdout).to include("exist smartest/example_test.rb")
|
|
716
896
|
expect(File.read(helper_path)).to eq("# custom helper\n")
|
|
717
897
|
expect(File.read(example_path)).to eq("# custom test\n")
|
|
718
898
|
expect(File.read(fixture_path)).to eq("# custom fixture\n")
|
|
899
|
+
expect(File.read(matcher_path)).to eq("# custom matcher\n")
|
|
719
900
|
end
|
|
720
901
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smartest
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.0.
|
|
4
|
+
version: 0.1.0.alpha3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yusuke Iwaki
|
|
@@ -53,6 +53,7 @@ files:
|
|
|
53
53
|
- lib/smartest/fixture_definition.rb
|
|
54
54
|
- lib/smartest/fixture_set.rb
|
|
55
55
|
- lib/smartest/init_generator.rb
|
|
56
|
+
- lib/smartest/matcher_registry.rb
|
|
56
57
|
- lib/smartest/matchers.rb
|
|
57
58
|
- lib/smartest/parameter_extractor.rb
|
|
58
59
|
- lib/smartest/reporter.rb
|