m-spec 0.1.7 → 0.2.3
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/Gemfile +1 -1
- data/README.md +36 -4
- data/exe/m-spec +25 -4
- data/lib/m-spec.rb +4 -0
- data/lib/m-spec/core/helpers/readable.rb +13 -8
- data/lib/m-spec/core/matchers/output.rb +4 -4
- data/lib/m-spec/core/matchers/raise_error.rb +31 -0
- data/lib/m-spec/core/spec_example.rb +26 -0
- data/lib/m-spec/core/spec_result.rb +3 -3
- data/lib/m-spec/core/specs.rb +35 -0
- data/lib/m-spec/mocks/allow.rb +1 -1
- data/lib/m-spec/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f6acd7d54cf75d89e1c6775a87596f48765d537726dbde5bfb9f7edbf94d8b3
|
4
|
+
data.tar.gz: dc0fc6487f6b34ebb5bed6fad56c1eaf9b8fb7a834d302deeafd95095fa5433a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 709cbf7e8ac930b83c63c575dbac520bdf49d56eaf9c479f917504f1400e0f2f382426cab4639c3ceae3a17b1aa99dee31151aceffdaa441ee3f457ad96a0a1a
|
7
|
+
data.tar.gz: d64e4dd9cad0bcd54a0c988fa733d53de9a94df8030605d79c01a03632c29bad3ae5977394b736a403dd5ecd727c6fbb0faa01509b249d552013c63e5dd3184b
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Mspec
|
2
2
|
|
3
|
-
The lightest-weight spec framework in ruby. Built for learning at [Makers](https://makers.tech). You have
|
3
|
+
The lightest-weight spec framework in ruby. Built for learning at [Makers](https://makers.tech). You have three matchers, an equality matcher, an output matcher and an error matcher. Test setup and teardown is your responsibility. For additional features, you must extend the gem.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -18,6 +18,14 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install m-spec
|
20
20
|
|
21
|
+
## Setup
|
22
|
+
|
23
|
+
Initialize m-spec with a `.m-spec` and a `.rubocop.yml` file
|
24
|
+
```sh
|
25
|
+
m-spec --init
|
26
|
+
```
|
27
|
+
|
28
|
+
|
21
29
|
## Usage
|
22
30
|
|
23
31
|
We care about isolating unit tests, so there's a very simple mocking library.
|
@@ -43,19 +51,38 @@ describe 'The Animal' do
|
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
46
|
-
describe '
|
47
|
-
it '
|
54
|
+
describe 'test doubles' do
|
55
|
+
it 'can be stubbed' do
|
48
56
|
mock = test_double
|
49
57
|
allow(mock).to receive(:speak) { 'Hello!' }
|
50
58
|
expect(mock.speak).to eq 'Hello!'
|
51
59
|
end
|
60
|
+
it 'can have optional names' do
|
61
|
+
mock = test_double('a name')
|
62
|
+
allow(mock).to receive(:speak) { 'Hello!' }
|
63
|
+
expect(mock.speak).to eq 'Hello!'
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'can be sent messages with any args' do
|
67
|
+
mock = test_double('a name')
|
68
|
+
allow(mock).to receive(:speak) { 'Hello!' }
|
69
|
+
expect(mock.speak('example arg')).to eq 'Hello!'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'testing output' do
|
74
|
+
it 'captures strings' do
|
75
|
+
expect { puts('hello') }.to output("hello\n")
|
76
|
+
end
|
52
77
|
end
|
53
78
|
```
|
54
79
|
|
55
|
-
To run your specs, pass the spec file directly as an argument. You have to run individual spec files.
|
80
|
+
To run your specs, pass the spec file directly as an argument. You have to run individual spec files, or create a file that requires your specs.
|
56
81
|
|
57
82
|
```sh
|
58
83
|
$ m-spec ./spec/animal_spec.rb
|
84
|
+
# or
|
85
|
+
$ m-spec ./spec_runner.rb
|
59
86
|
```
|
60
87
|
|
61
88
|
```
|
@@ -67,6 +94,11 @@ The Animal
|
|
67
94
|
# /path/to/directory/spec/animal_spec.rb:11:in `block (2 levels) in <top (required)>'
|
68
95
|
stubbing
|
69
96
|
we can mock too!
|
97
|
+
|
98
|
+
Inspecting 3 files
|
99
|
+
...
|
100
|
+
|
101
|
+
3 files inspected, no offenses detected
|
70
102
|
```
|
71
103
|
|
72
104
|
It's got simple one-level indentation, simple colour coding for test passes and failures, and simple failure messages with expected and actual values and the failing spec file path and line number.
|
data/exe/m-spec
CHANGED
@@ -2,16 +2,37 @@
|
|
2
2
|
require 'm-spec'
|
3
3
|
|
4
4
|
def run_rubocop!
|
5
|
-
|
6
|
-
|
5
|
+
# needs default
|
6
|
+
if File.exist?('.rubocop.yml')
|
7
|
+
puts "\n---Readability Tests---\n\n"
|
8
|
+
system("bundle exec rubocop")
|
9
|
+
else
|
10
|
+
puts "ERROR: No '.rubocop.yml' found, please create one at your project \
|
11
|
+
root or re-initialize m-spec with `m-spec --init`"
|
12
|
+
end
|
7
13
|
end
|
8
14
|
|
9
15
|
def run_specs!
|
10
16
|
spec_file = ARGV[0]
|
11
|
-
|
17
|
+
Mspec::Specs.new(spec_file).run!
|
12
18
|
end
|
13
19
|
|
14
|
-
if
|
20
|
+
if ARGV[0] == '--init'
|
21
|
+
contents = File.read("#{ENV['GEM_HOME']}/gems/m-spec-#{Mspec::VERSION}/.rubocop.yml")
|
22
|
+
File.open('.rubocop.yml', 'w') do |file|
|
23
|
+
file.write(contents)
|
24
|
+
end
|
25
|
+
puts 'created: .rubocop.yml'
|
26
|
+
|
27
|
+
contents =
|
28
|
+
"# This has been auto-generated. Feel free to delete these comments.\
|
29
|
+
\n#\n# Try adding options below: '--no-rubocop' or '--only-rubocop' \
|
30
|
+
without the quotes."
|
31
|
+
File.open('.m-spec', 'w') do |file|
|
32
|
+
file.write(contents)
|
33
|
+
end
|
34
|
+
puts 'created: .m-spec'
|
35
|
+
elsif File.exist?('./.m-spec')
|
15
36
|
File.open('./.m-spec', 'r') do |file|
|
16
37
|
options = file.read.split
|
17
38
|
if options.include?('--only-rubocop')
|
data/lib/m-spec.rb
CHANGED
@@ -5,8 +5,12 @@ require "m-spec/version"
|
|
5
5
|
require "m-spec/core/expect"
|
6
6
|
require "m-spec/core/spec_error"
|
7
7
|
require "m-spec/core/spec_result"
|
8
|
+
require "m-spec/core/spec_example"
|
9
|
+
require "m-spec/core/specs"
|
8
10
|
require "m-spec/core/matchers/equal"
|
9
11
|
require "m-spec/core/matchers/output"
|
12
|
+
require "m-spec/core/matchers/raise_error"
|
13
|
+
|
10
14
|
require "m-spec/core/helpers/readable"
|
11
15
|
|
12
16
|
require "m-spec/mocks/allow"
|
@@ -9,21 +9,22 @@ def describe(str)
|
|
9
9
|
yield
|
10
10
|
end
|
11
11
|
|
12
|
-
def it(str)
|
13
|
-
|
14
|
-
|
12
|
+
def it(str, specs = Mspec::Specs.instance)
|
13
|
+
spec_example = Mspec::SpecExample.new(str, yield)
|
14
|
+
specs.add(spec_example)
|
15
|
+
if spec_example.success?
|
15
16
|
puts " \e[#{COLOUR_CODES[:green]}m#{str}\e[0m"
|
16
17
|
else
|
17
|
-
puts " \e[#{COLOUR_CODES[:red]}m#{str}\e[0m"
|
18
|
-
|
18
|
+
puts " \e[#{COLOUR_CODES[:red]}m#{str}\n\e[0m"
|
19
|
+
spec_example.failure_message.each do |line|
|
19
20
|
puts " \e[#{COLOUR_CODES[:red]}m#{line}\e[0m"
|
20
21
|
end
|
21
|
-
puts " \e[#{COLOUR_CODES[:light_blue]}m# #{
|
22
|
+
puts "\n \e[#{COLOUR_CODES[:light_blue]}m# #{spec_example.trace}\e[0m"
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
def expect(obj=nil, &block)
|
26
|
-
if obj
|
26
|
+
def expect(obj = nil, &block)
|
27
|
+
if !obj.nil?
|
27
28
|
Mspec::Expect.new(obj)
|
28
29
|
else
|
29
30
|
Mspec::Expect.new(block)
|
@@ -37,3 +38,7 @@ end
|
|
37
38
|
def eq(obj)
|
38
39
|
Mspec::Matchers::Equal.new(obj)
|
39
40
|
end
|
41
|
+
|
42
|
+
def raise_error(error_class)
|
43
|
+
Mspec::Matchers::RaiseError.new(error_class)
|
44
|
+
end
|
@@ -3,7 +3,7 @@ require 'stringio'
|
|
3
3
|
module Mspec
|
4
4
|
module Matchers
|
5
5
|
class Output
|
6
|
-
attr_reader :value, :
|
6
|
+
attr_reader :value, :actual
|
7
7
|
|
8
8
|
def initialize(value)
|
9
9
|
@value = value
|
@@ -13,14 +13,14 @@ module Mspec
|
|
13
13
|
output = mock_output do
|
14
14
|
block.call
|
15
15
|
end
|
16
|
-
@
|
16
|
+
@actual = output.string
|
17
17
|
|
18
|
-
@value == @
|
18
|
+
@value == @actual
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
-
def mock_output(output=StringIO.new, &block)
|
23
|
+
def mock_output(output = StringIO.new, &block)
|
24
24
|
$stdout = output
|
25
25
|
block.call
|
26
26
|
$stdout = STDOUT
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module Mspec
|
4
|
+
module Matchers
|
5
|
+
class RaiseError
|
6
|
+
attr_reader :value, :actual
|
7
|
+
|
8
|
+
def initialize(value)
|
9
|
+
@value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def check(block)
|
13
|
+
@actual = catch_error do
|
14
|
+
block.call
|
15
|
+
end
|
16
|
+
|
17
|
+
@value == @actual
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def catch_error(&block)
|
23
|
+
begin
|
24
|
+
block.call
|
25
|
+
rescue StandardError => e
|
26
|
+
e.class
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mspec
|
2
|
+
class SpecExample
|
3
|
+
attr_reader :description, :result
|
4
|
+
|
5
|
+
def initialize(description, result)
|
6
|
+
@description = description
|
7
|
+
@result = result
|
8
|
+
end
|
9
|
+
|
10
|
+
def success?
|
11
|
+
@result.success?
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure?
|
15
|
+
!success?
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure_message
|
19
|
+
@result.failure_message
|
20
|
+
end
|
21
|
+
|
22
|
+
def trace
|
23
|
+
@result.trace
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -12,8 +12,8 @@ module Mspec
|
|
12
12
|
|
13
13
|
def failure_message
|
14
14
|
[
|
15
|
-
"Expected: #{@expected_result.value.inspect}",
|
16
|
-
"Got: #{test_code_result.inspect}",
|
15
|
+
"Expected: ".rjust(10) + "#{@expected_result.value.inspect}",
|
16
|
+
"Got: ".rjust(10) + "#{test_code_result.inspect}",
|
17
17
|
]
|
18
18
|
end
|
19
19
|
|
@@ -25,7 +25,7 @@ module Mspec
|
|
25
25
|
|
26
26
|
def test_code_result
|
27
27
|
if @test_code.value.is_a?(Proc)
|
28
|
-
@expected_result.
|
28
|
+
@expected_result.actual
|
29
29
|
else
|
30
30
|
@test_code.value
|
31
31
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Mspec
|
2
|
+
class Specs
|
3
|
+
attr_reader :data
|
4
|
+
|
5
|
+
def initialize(file)
|
6
|
+
@file = file
|
7
|
+
@data = []
|
8
|
+
@@instance = self
|
9
|
+
end
|
10
|
+
|
11
|
+
def run!
|
12
|
+
require(@file)
|
13
|
+
summary
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(spec)
|
17
|
+
@data << spec
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.instance
|
21
|
+
@@instance
|
22
|
+
end
|
23
|
+
|
24
|
+
def summary
|
25
|
+
puts "\n---Summary---\n\n"
|
26
|
+
puts "#{@data.length} examples found"
|
27
|
+
failures = @data.select(&:failure?)
|
28
|
+
|
29
|
+
puts "#{failures.length} failures"
|
30
|
+
failures.each_with_index do |spec, index|
|
31
|
+
puts " \e[#{COLOUR_CODES[:red]}m#{index+1}. #{spec.trace}\e[0m"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/m-spec/mocks/allow.rb
CHANGED
data/lib/m-spec/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: m-spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edward Withers
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -76,8 +76,11 @@ files:
|
|
76
76
|
- lib/m-spec/core/helpers/readable.rb
|
77
77
|
- lib/m-spec/core/matchers/equal.rb
|
78
78
|
- lib/m-spec/core/matchers/output.rb
|
79
|
+
- lib/m-spec/core/matchers/raise_error.rb
|
79
80
|
- lib/m-spec/core/spec_error.rb
|
81
|
+
- lib/m-spec/core/spec_example.rb
|
80
82
|
- lib/m-spec/core/spec_result.rb
|
83
|
+
- lib/m-spec/core/specs.rb
|
81
84
|
- lib/m-spec/mocks/allow.rb
|
82
85
|
- lib/m-spec/mocks/helpers/readable.rb
|
83
86
|
- lib/m-spec/mocks/mock.rb
|