neospec 0.0.1
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/.buildkite/bin/check-formatting +7 -0
- data/.buildkite/bin/install-asdf +16 -0
- data/.buildkite/bin/install-ruby +11 -0
- data/.buildkite/bin/install-taylor +15 -0
- data/.buildkite/bin/setup-ruby +5 -0
- data/.buildkite/bin/test-ruby +8 -0
- data/.buildkite/bin/test-taylor +8 -0
- data/.buildkite/pipeline.yml +52 -0
- data/.tool-versions +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +66 -0
- data/README.md +43 -0
- data/Rakefile +16 -0
- data/docs/example_spec.rb +28 -0
- data/lib/neospec/color.rb +8 -0
- data/lib/neospec/expector.rb +55 -0
- data/lib/neospec/logger/basic.rb +32 -0
- data/lib/neospec/logger/symbols.rb +18 -0
- data/lib/neospec/report/basic.rb +57 -0
- data/lib/neospec/results.rb +29 -0
- data/lib/neospec/runner/basic.rb +11 -0
- data/lib/neospec/spec/result/failure.rb +14 -0
- data/lib/neospec/spec/result.rb +31 -0
- data/lib/neospec/spec.rb +66 -0
- data/lib/neospec/suite.rb +28 -0
- data/lib/neospec/version.rb +3 -0
- data/lib/neospec.rb +38 -0
- data/neospec.gemspec +30 -0
- data/spec/neospec/expector_spec.rb +201 -0
- data/spec/neospec/logger/basic_spec.rb +101 -0
- data/spec/neospec/logger/symbols_spec.rb +54 -0
- data/spec/neospec/report/basic_spec.rb +115 -0
- data/spec/neospec/results_spec.rb +151 -0
- data/spec/neospec/runner/basic_spec.rb +27 -0
- data/spec/neospec/spec/result_spec.rb +64 -0
- data/spec/neospec/spec_spec.rb +103 -0
- data/spec/neospec/suite_spec.rb +56 -0
- data/spec/neospec/version_spec.rb +3 -0
- data/spec/neospec_spec.rb +11 -0
- data/spec/run.rb +30 -0
- data/spec/support/test_logger.rb +15 -0
- data/spec/support/test_outputter.rb +15 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 38bd481896e0d5370273be416eff657d82318f3e1ff9f517bdb16bb14e80167e
|
4
|
+
data.tar.gz: 5583a0d624da8f0b6a1f9afc0590ec565f5cbe5aa1ec2bdca5eb1d69a7235cf4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5bb3bffd7c3b17f9ca90109e6ec9097de59d353b2ae7c6ee4747c7f8ab55dd580f7059e15c4c205c46bf99450ea36d2a11e6281560ae4dd60f4f79f214365984
|
7
|
+
data.tar.gz: 803bb7a2562b2138d40e04857c0b2463a8bfdb99084e5ee06479e5dff2322ddfe18168364ab932fa3fc9e8a2dc4ded3da643bea0c19d51ccff6b156f9d306274
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
set -euo pipefail
|
3
|
+
|
4
|
+
if [ ! -f "/root/.asdf/bin/asdf" ]; then
|
5
|
+
ASDF_VERSION=v0.16.4
|
6
|
+
ASDF_PLATFORM=amd64
|
7
|
+
ASDF_URL=https://github.com/asdf-vm/asdf/releases/download/$ASDF_VERSION/asdf-$ASDF_VERSION-linux-$ASDF_PLATFORM.tar.gz
|
8
|
+
|
9
|
+
wget -O /root/asdf.tar.gz "${ASDF_URL}"
|
10
|
+
tar xfv /root/asdf.tar.gz
|
11
|
+
mkdir -p /root/.asdf/bin/
|
12
|
+
mv asdf /root/.asdf/bin/asdf
|
13
|
+
rm /root/asdf.tar.gz
|
14
|
+
|
15
|
+
asdf plugin add ruby
|
16
|
+
fi
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
set -euo pipefail
|
3
|
+
|
4
|
+
TAYLOR_VERSION=$1
|
5
|
+
|
6
|
+
if [ ! -f "/root/.taylor-versions/taylor-${TAYLOR_VERSION}" ]; then
|
7
|
+
TAYLOR_URL=https://github.com/HellRok/Taylor/releases/download/${TAYLOR_VERSION}/taylor-linux-${TAYLOR_VERSION}.zip
|
8
|
+
|
9
|
+
wget -O /root/taylor.zip "${TAYLOR_URL}"
|
10
|
+
unzip /root/taylor.zip
|
11
|
+
mkdir -p /root/.taylor-versions/
|
12
|
+
mv taylor /root/.taylor-versions/taylor-${TAYLOR_VERSION}
|
13
|
+
rm /root/taylor.zip
|
14
|
+
fi
|
15
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
steps:
|
2
|
+
- label: 'Formatting'
|
3
|
+
commands:
|
4
|
+
- .buildkite/bin/check-formatting
|
5
|
+
|
6
|
+
- label: 'Ruby - 3.5'
|
7
|
+
commands:
|
8
|
+
- .buildkite/bin/test-ruby 3.5.0-preview1
|
9
|
+
|
10
|
+
- label: 'Ruby - 3.4'
|
11
|
+
commands:
|
12
|
+
- .buildkite/bin/test-ruby 3.4.5
|
13
|
+
|
14
|
+
- label: 'Ruby - 3.3'
|
15
|
+
commands:
|
16
|
+
- .buildkite/bin/test-ruby 3.3.8
|
17
|
+
|
18
|
+
- label: 'Ruby - 3.2'
|
19
|
+
commands:
|
20
|
+
- .buildkite/bin/test-ruby 3.2.8
|
21
|
+
|
22
|
+
- label: 'Ruby - 3.1'
|
23
|
+
commands:
|
24
|
+
- .buildkite/bin/test-ruby 3.1.7
|
25
|
+
|
26
|
+
- label: 'Ruby - 3.0'
|
27
|
+
commands:
|
28
|
+
- .buildkite/bin/test-ruby 3.0.7
|
29
|
+
|
30
|
+
- label: 'Ruby - 2.7'
|
31
|
+
commands:
|
32
|
+
- .buildkite/bin/test-ruby 2.7.8
|
33
|
+
|
34
|
+
- label: 'Ruby - 2.6'
|
35
|
+
commands:
|
36
|
+
- .buildkite/bin/test-ruby 2.6.10
|
37
|
+
|
38
|
+
- label: 'JRuby - 10'
|
39
|
+
commands:
|
40
|
+
- .buildkite/bin/test-ruby jruby-10.0.0.1
|
41
|
+
|
42
|
+
- label: 'JRuby - 9'
|
43
|
+
commands:
|
44
|
+
- .buildkite/bin/test-ruby jruby-9.4.13.0
|
45
|
+
|
46
|
+
- label: 'TruffleRuby - 24'
|
47
|
+
commands:
|
48
|
+
- .buildkite/bin/test-ruby truffleruby-24.2.1
|
49
|
+
|
50
|
+
- label: 'Taylor - v0.3.14.1'
|
51
|
+
commands:
|
52
|
+
- .buildkite/bin/test-taylor v0.3.14.1
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 3.4.5
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
GEM
|
2
|
+
specs:
|
3
|
+
|
4
|
+
GEM
|
5
|
+
remote: https://rubygems.org/
|
6
|
+
specs:
|
7
|
+
ast (2.4.3)
|
8
|
+
json (2.13.1)
|
9
|
+
language_server-protocol (3.17.0.5)
|
10
|
+
lint_roller (1.1.0)
|
11
|
+
parallel (1.27.0)
|
12
|
+
parser (3.3.8.0)
|
13
|
+
ast (~> 2.4.1)
|
14
|
+
racc
|
15
|
+
prism (1.4.0)
|
16
|
+
racc (1.8.1)
|
17
|
+
rainbow (3.1.1)
|
18
|
+
rake (13.3.0)
|
19
|
+
regexp_parser (2.10.0)
|
20
|
+
rubocop (1.75.8)
|
21
|
+
json (~> 2.3)
|
22
|
+
language_server-protocol (~> 3.17.0.2)
|
23
|
+
lint_roller (~> 1.1.0)
|
24
|
+
parallel (~> 1.10)
|
25
|
+
parser (>= 3.3.0.2)
|
26
|
+
rainbow (>= 2.2.2, < 4.0)
|
27
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
28
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
29
|
+
ruby-progressbar (~> 1.7)
|
30
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
31
|
+
rubocop-ast (1.46.0)
|
32
|
+
parser (>= 3.3.7.2)
|
33
|
+
prism (~> 1.4)
|
34
|
+
rubocop-performance (1.25.0)
|
35
|
+
lint_roller (~> 1.1)
|
36
|
+
rubocop (>= 1.75.0, < 2.0)
|
37
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
38
|
+
ruby-progressbar (1.13.0)
|
39
|
+
standard (1.50.0)
|
40
|
+
language_server-protocol (~> 3.17.0.2)
|
41
|
+
lint_roller (~> 1.0)
|
42
|
+
rubocop (~> 1.75.5)
|
43
|
+
standard-custom (~> 1.0.0)
|
44
|
+
standard-performance (~> 1.8)
|
45
|
+
standard-custom (1.0.2)
|
46
|
+
lint_roller (~> 1.0)
|
47
|
+
rubocop (~> 1.50)
|
48
|
+
standard-performance (1.8.0)
|
49
|
+
lint_roller (~> 1.1)
|
50
|
+
rubocop-performance (~> 1.25.0)
|
51
|
+
standardrb (1.0.1)
|
52
|
+
standard
|
53
|
+
unicode-display_width (3.1.4)
|
54
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
55
|
+
unicode-emoji (4.0.4)
|
56
|
+
|
57
|
+
PLATFORMS
|
58
|
+
arm64-darwin-24
|
59
|
+
ruby
|
60
|
+
|
61
|
+
DEPENDENCIES
|
62
|
+
rake!
|
63
|
+
standardrb!
|
64
|
+
|
65
|
+
BUNDLED WITH
|
66
|
+
2.6.9
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# neospec
|
2
|
+
|
3
|
+
## Usage
|
4
|
+
|
5
|
+
Add `gem "neospec"` to your `Gemfile` and run `bundle install`.
|
6
|
+
|
7
|
+
Then it can be as simple as:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
require "neospec"
|
11
|
+
|
12
|
+
unit = Neospec::Suite.new
|
13
|
+
neospec = Neospec.new(suites: [unit])
|
14
|
+
|
15
|
+
unit.describe "An example test" do
|
16
|
+
Given "apples are ripe" do
|
17
|
+
@apples = :ripe
|
18
|
+
end
|
19
|
+
|
20
|
+
And "bananas are ripe" do
|
21
|
+
@bananas = :ripe
|
22
|
+
end
|
23
|
+
|
24
|
+
Then "apples and bananas are as ripe as each other" do
|
25
|
+
expect(@apples).to_equal(@bananas)
|
26
|
+
end
|
27
|
+
|
28
|
+
But "the bananas become TOO ripe" do
|
29
|
+
@bananas = :over_ripe
|
30
|
+
end
|
31
|
+
|
32
|
+
Then "apples and bananas are now not as ripe as each other" do
|
33
|
+
expect(@apples).not_to_equal(@bananas)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
neospec.run!
|
38
|
+
```
|
39
|
+
|
40
|
+
## Not yet implemented
|
41
|
+
|
42
|
+
- Early exit upon hitting a failure
|
43
|
+
- Expect errors
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "standard/rake"
|
2
|
+
|
3
|
+
task neospec: ["neospec:ruby", "neospec:taylor"]
|
4
|
+
|
5
|
+
task "neospec:ruby" do
|
6
|
+
require "./spec/run"
|
7
|
+
end
|
8
|
+
|
9
|
+
task "neospec:taylor" do
|
10
|
+
exec "taylor spec/run.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
task "example" do
|
14
|
+
$LOAD_PATH << "./lib"
|
15
|
+
require "./docs/example_spec"
|
16
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "neospec"
|
2
|
+
|
3
|
+
unit = Neospec::Suite.new
|
4
|
+
neospec = Neospec.new(suites: [unit])
|
5
|
+
|
6
|
+
unit.describe "An example test" do
|
7
|
+
Given "apples are ripe" do
|
8
|
+
@apples = :ripe
|
9
|
+
end
|
10
|
+
|
11
|
+
And "bananas are ripe" do
|
12
|
+
@bananas = :ripe
|
13
|
+
end
|
14
|
+
|
15
|
+
Then "apples and bananas are as ripe as each other" do
|
16
|
+
expect(@apples).to_equal(@bananas)
|
17
|
+
end
|
18
|
+
|
19
|
+
But "the bananas become TOO ripe" do
|
20
|
+
@bananas = :over_ripe
|
21
|
+
end
|
22
|
+
|
23
|
+
Then "apples and bananas are now not as ripe as each other" do
|
24
|
+
expect(@apples).not_to_equal(@bananas)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
neospec.run!
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Neospec
|
2
|
+
class Expector
|
3
|
+
attr_reader :failure, :result
|
4
|
+
|
5
|
+
def initialize(result:, actual:, stack:, logger:)
|
6
|
+
@actual = actual
|
7
|
+
@stack = stack
|
8
|
+
@logger = logger
|
9
|
+
@result = result
|
10
|
+
end
|
11
|
+
|
12
|
+
def log(message, context: nil)
|
13
|
+
@logger.log(message, context: context, result: @result)
|
14
|
+
end
|
15
|
+
|
16
|
+
def succeeded(message)
|
17
|
+
@result.expectations += 1
|
18
|
+
log(message, context: :expect)
|
19
|
+
end
|
20
|
+
|
21
|
+
def failed(message)
|
22
|
+
@result.expectations += 1
|
23
|
+
@result.failures << Neospec::Spec::Result::Failure.new(
|
24
|
+
stack: @stack,
|
25
|
+
message: "Expected #{message}"
|
26
|
+
)
|
27
|
+
|
28
|
+
log(message, context: :expect)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_equal(expected)
|
32
|
+
if @actual == expected
|
33
|
+
succeeded "to be equal"
|
34
|
+
else
|
35
|
+
failed "'#{expected}' to equal '#{@actual}'"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def not_to_equal(expected)
|
40
|
+
if @actual != expected
|
41
|
+
succeeded "not to be equal"
|
42
|
+
else
|
43
|
+
failed "'#{expected}' not to equal '#{@actual}'"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_be_a(expected)
|
48
|
+
if @actual.is_a?(expected)
|
49
|
+
succeeded "to be a #{expected}"
|
50
|
+
else
|
51
|
+
failed "'#{expected}' to equal '#{@actual.class}'"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Neospec
|
2
|
+
module Logger
|
3
|
+
class Basic
|
4
|
+
def initialize(color: true, output: $stdout)
|
5
|
+
@color = color
|
6
|
+
@output = output
|
7
|
+
end
|
8
|
+
|
9
|
+
def log(message, context: nil, result: nil)
|
10
|
+
case context
|
11
|
+
when :describe
|
12
|
+
if @color
|
13
|
+
@output.puts "#{Neospec::Color::BLUE}#{message}#{Neospec::Color::RESET}"
|
14
|
+
else
|
15
|
+
@output.puts message
|
16
|
+
end
|
17
|
+
when :expect
|
18
|
+
if @color
|
19
|
+
str = " "
|
20
|
+
str << (result.successful? ? "#{Neospec::Color::GREEN}✓" : "#{Neospec::Color::RED}✗")
|
21
|
+
str << " #{context} #{message}#{Neospec::Color::RESET}"
|
22
|
+
@output.puts str
|
23
|
+
else
|
24
|
+
@output.puts " #{result.successful? ? "✓" : "✗"} #{context} #{message}"
|
25
|
+
end
|
26
|
+
else
|
27
|
+
@output.puts " #{context} #{message}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Neospec
|
2
|
+
module Logger
|
3
|
+
class Symbols
|
4
|
+
def initialize(color: true, output: $stdout)
|
5
|
+
@color = color
|
6
|
+
@output = output
|
7
|
+
end
|
8
|
+
|
9
|
+
def log(message, context: nil, result: nil)
|
10
|
+
if context == :expect
|
11
|
+
@output.write "#{
|
12
|
+
result.successful? ? "#{Neospec::Color::GREEN}✓" : "#{Neospec::Color::RED}✗"
|
13
|
+
}#{Neospec::Color::RESET}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Neospec
|
2
|
+
module Report
|
3
|
+
module Basic
|
4
|
+
def self.call(results, output: $stdout)
|
5
|
+
output.puts "\n#{successes(results)}#{failures(results)}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.successes(results)
|
9
|
+
<<~STR.chomp
|
10
|
+
Finished in #{formatted_duration(results.duration)}
|
11
|
+
|
12
|
+
Results:
|
13
|
+
Specs:\t#{results.specs.size}
|
14
|
+
Expectations:\t#{results.expectations}
|
15
|
+
STR
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.failures(results)
|
19
|
+
return if results.successful?
|
20
|
+
|
21
|
+
output = "\n Failures:\t#{results.failures.size}\n\n"
|
22
|
+
output << "Failures:\n"
|
23
|
+
|
24
|
+
output += results.failures.map do |failure|
|
25
|
+
failure_output = [" #{Neospec::Color::RED}#{failure.message}#{Neospec::Color::RESET}"]
|
26
|
+
failure.stack.first(5).each do |location|
|
27
|
+
failure_output << " > #{location}"
|
28
|
+
end
|
29
|
+
|
30
|
+
failure_output.join("\n")
|
31
|
+
end.join("\n\n")
|
32
|
+
|
33
|
+
output
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.formatted_duration(duration)
|
37
|
+
if duration < 1
|
38
|
+
"#{(duration * 1000).round(2)} milliseconds"
|
39
|
+
elsif duration < 60
|
40
|
+
"#{duration.round(2)} seconds"
|
41
|
+
elsif duration < 3600
|
42
|
+
minutes = (duration / 60).to_i
|
43
|
+
seconds = (duration % 60).to_i
|
44
|
+
"#{minutes} minute#{(minutes == 1) ? "" : "s"} #{seconds} second#{(seconds == 1) ? "" : "s"}"
|
45
|
+
elsif duration < 86400
|
46
|
+
hours = (duration / 3600).to_i
|
47
|
+
minutes = ((duration % 3600) / 60).to_i
|
48
|
+
"#{hours} hour#{(hours == 1) ? "" : "s"} #{minutes} minute#{(minutes == 1) ? "" : "s"}"
|
49
|
+
else
|
50
|
+
days = (duration / 86400).to_i
|
51
|
+
hours = ((duration % 86400) / 3600).to_i
|
52
|
+
"#{days} day#{(days == 1) ? "" : "s"} #{hours} hour#{(hours == 1) ? "" : "s"}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Neospec
|
2
|
+
class Results
|
3
|
+
attr_accessor :suites
|
4
|
+
|
5
|
+
def initialize(suites: [])
|
6
|
+
@suites = suites
|
7
|
+
end
|
8
|
+
|
9
|
+
def specs
|
10
|
+
@suites.flat_map(&:specs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def successful?
|
14
|
+
specs.all?(&:successful?)
|
15
|
+
end
|
16
|
+
|
17
|
+
def failures
|
18
|
+
specs.flat_map(&:failures)
|
19
|
+
end
|
20
|
+
|
21
|
+
def duration
|
22
|
+
specs.sum(0, &:duration)
|
23
|
+
end
|
24
|
+
|
25
|
+
def expectations
|
26
|
+
specs.sum(0, &:expectations)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Neospec
|
2
|
+
class Spec
|
3
|
+
class Result
|
4
|
+
attr_accessor :expectations, :failures, :start, :finish
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@expectations = 0
|
8
|
+
@failures = []
|
9
|
+
@start = nil
|
10
|
+
@finish = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def successful?
|
14
|
+
@failures.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def start!
|
18
|
+
@start = Time.now
|
19
|
+
end
|
20
|
+
|
21
|
+
def finish!
|
22
|
+
@finish = Time.now
|
23
|
+
end
|
24
|
+
|
25
|
+
def duration
|
26
|
+
return if @start.nil? || @finish.nil?
|
27
|
+
@finish - @start
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/neospec/spec.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
class Neospec
|
2
|
+
class Spec
|
3
|
+
COMMANDS = %w[Given And But When Then]
|
4
|
+
|
5
|
+
def initialize(description:, block:)
|
6
|
+
# Everything here is prefixed to prevent people's specs overriding it,
|
7
|
+
# this came to be because I've already accidentally done this a few
|
8
|
+
# times.
|
9
|
+
@__result = Neospec::Spec::Result.new
|
10
|
+
@__description = description
|
11
|
+
@__block = block
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
@__description
|
16
|
+
end
|
17
|
+
|
18
|
+
def result
|
19
|
+
@__result
|
20
|
+
end
|
21
|
+
|
22
|
+
def duration
|
23
|
+
@__result.duration
|
24
|
+
end
|
25
|
+
|
26
|
+
def successful?
|
27
|
+
@__result.successful?
|
28
|
+
end
|
29
|
+
|
30
|
+
def expectations
|
31
|
+
@__result.expectations
|
32
|
+
end
|
33
|
+
|
34
|
+
def failures
|
35
|
+
@__result.failures
|
36
|
+
end
|
37
|
+
|
38
|
+
def log(message, context: nil, result: nil)
|
39
|
+
@__logger.log(message, context: context, result: result)
|
40
|
+
end
|
41
|
+
|
42
|
+
def run(logger:)
|
43
|
+
@__logger = logger
|
44
|
+
instance_exec { log(@__description, context: :describe) }
|
45
|
+
result.start!
|
46
|
+
instance_exec(&@__block)
|
47
|
+
result.finish!
|
48
|
+
end
|
49
|
+
|
50
|
+
COMMANDS.each do |command|
|
51
|
+
define_method(command) do |description, &block|
|
52
|
+
log(description, context: command.to_sym)
|
53
|
+
block.call
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def expect(value)
|
58
|
+
Neospec::Expector.new(
|
59
|
+
result: @__result,
|
60
|
+
actual: value,
|
61
|
+
stack: caller,
|
62
|
+
logger: @__logger
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Neospec
|
2
|
+
class Suite
|
3
|
+
attr_accessor :specs, :runner
|
4
|
+
|
5
|
+
def initialize(runner: Neospec::Runner::Basic.new)
|
6
|
+
@runner = runner
|
7
|
+
@specs = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def results
|
11
|
+
@specs.map(&:result)
|
12
|
+
end
|
13
|
+
|
14
|
+
def describe(description, &block)
|
15
|
+
@specs << Neospec::Spec.new(
|
16
|
+
description: description,
|
17
|
+
block: block
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(logger:)
|
22
|
+
runner.run(
|
23
|
+
logger: logger,
|
24
|
+
suite: self
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|