fix 0.0.1.pre → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.travis.yml +4 -2
- data/README.md +81 -49
- data/Rakefile +17 -0
- data/VERSION.semver +1 -1
- data/example/duck/README.md +9 -0
- data/example/duck/app.rb +3 -0
- data/example/duck/lib.rb +14 -0
- data/example/duck/spec.rb +31 -0
- data/example/duck/test.rb +6 -0
- data/fix.gemspec +10 -6
- data/lib/fix.rb +3 -17
- data/lib/fix/dsl.rb +10 -0
- data/lib/fix/expectation.rb +48 -0
- data/lib/fix/expectation_high.rb +26 -0
- data/lib/fix/expectation_low.rb +44 -0
- data/lib/fix/expectation_medium.rb +29 -0
- data/lib/fix/expectation_set.rb +8 -0
- data/lib/fix/helper/it_helper.rb +12 -0
- data/lib/fix/helper/its_helper.rb +12 -0
- data/lib/fix/helper/let_accessor_helper.rb +11 -0
- data/lib/fix/helper/let_reader_helper.rb +9 -0
- data/lib/fix/helper/let_writer_helper.rb +13 -0
- data/lib/fix/helper/on_helper.rb +12 -0
- data/lib/fix/helper/requirement_helper.rb +44 -0
- data/lib/fix/it.rb +14 -0
- data/lib/fix/its.rb +14 -0
- data/lib/fix/on.rb +20 -0
- data/lib/fix/spec.rb +16 -10
- data/lib/fix/subject.rb +43 -10
- data/lib/fix/test.rb +114 -0
- data/lib/fix/version.rb +9 -0
- data/spec/TODO +0 -0
- data/spec/spec_helper.rb +2 -4
- data/spec/support.rb +3 -0
- data/spec/support/coverage.rb +3 -0
- data/spec/support/env.rb +4 -0
- data/spec/support/presenter.rb +0 -0
- metadata +85 -22
- data/.ruby-version +0 -1
- data/bin/fix +0 -58
- data/lib/fix/base_matcher.rb +0 -38
- data/lib/fix/call.rb +0 -16
- data/lib/fix/constant.rb +0 -37
- data/lib/fix/expectation_target.rb +0 -41
- data/lib/fix/helper.rb +0 -34
- data/lib/fix/scope.rb +0 -20
- data/logo.png +0 -0
- data/logo.svg +0 -19
- data/spec/subject_spec.rb +0 -5
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative File.join 'expectation_high'
|
2
|
+
|
3
|
+
module Fix
|
4
|
+
class ExpectationMedium < ExpectationHigh
|
5
|
+
def evaluate front_object
|
6
|
+
subject = Subject.new front_object, *@args
|
7
|
+
got = nil
|
8
|
+
|
9
|
+
Thread.new {
|
10
|
+
report = expect { got = subject.actual }.
|
11
|
+
public_send target, @matcher => @expected
|
12
|
+
|
13
|
+
data = presenter report, got
|
14
|
+
|
15
|
+
Hash[ data.to_a + meta(subject).to_a ]
|
16
|
+
}.value
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def pass? report
|
22
|
+
report.pass? || report.exception.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def level
|
26
|
+
2
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative File.join 'let_reader_helper'
|
2
|
+
|
3
|
+
module Fix
|
4
|
+
module Helper
|
5
|
+
module RequirementHelper
|
6
|
+
include Helper::LetReaderHelper
|
7
|
+
|
8
|
+
def MUST definition
|
9
|
+
ExpectationHigh.new true, definition, *@args
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method :is_REQUIRED_to, :MUST
|
13
|
+
alias_method :SHALL, :MUST
|
14
|
+
|
15
|
+
def MUST_NOT definition
|
16
|
+
ExpectationHigh.new false, definition, *@args
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method :SHALL_NOT, :MUST_NOT
|
20
|
+
|
21
|
+
def SHOULD definition
|
22
|
+
ExpectationMedium.new true, definition, *@args
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :is_RECOMMENDED_to, :SHOULD
|
26
|
+
|
27
|
+
def SHOULD_NOT definition
|
28
|
+
ExpectationMedium.new false, definition, *@args
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :is_NOT_RECOMMENDED_to, :SHOULD_NOT
|
32
|
+
|
33
|
+
def MAY definition
|
34
|
+
ExpectationLow.new true, definition, *@args
|
35
|
+
end
|
36
|
+
|
37
|
+
alias_method :is_OPTIONAL_to, :MAY
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
require_relative File.join '..', 'expectation_high'
|
43
|
+
require_relative File.join '..', 'expectation_low'
|
44
|
+
require_relative File.join '..', 'expectation_medium'
|
data/lib/fix/it.rb
ADDED
data/lib/fix/its.rb
ADDED
data/lib/fix/on.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative File.join 'helper', 'it_helper'
|
2
|
+
require_relative File.join 'helper', 'its_helper'
|
3
|
+
require_relative File.join 'helper', 'let_accessor_helper'
|
4
|
+
require_relative File.join 'helper', 'on_helper' unless defined? Fix::Helper::OnHelper
|
5
|
+
|
6
|
+
module Fix
|
7
|
+
class On
|
8
|
+
include Helper::ItHelper
|
9
|
+
include Helper::ItsHelper
|
10
|
+
include Helper::LetAccessorHelper
|
11
|
+
include Helper::OnHelper
|
12
|
+
|
13
|
+
def initialize defs, *args
|
14
|
+
@defs = defs
|
15
|
+
@args = args
|
16
|
+
|
17
|
+
freeze
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/fix/spec.rb
CHANGED
@@ -1,20 +1,26 @@
|
|
1
|
+
require_relative File.join 'dsl'
|
2
|
+
require_relative File.join 'test'
|
3
|
+
|
1
4
|
module Fix
|
2
5
|
class Spec
|
3
|
-
|
6
|
+
include DSL
|
7
|
+
|
8
|
+
def initialize title = nil, &block
|
9
|
+
@title = title
|
10
|
+
@defs = {}
|
11
|
+
@args = []
|
4
12
|
|
5
|
-
|
6
|
-
@examples = Set.new
|
13
|
+
instance_eval(&block)
|
7
14
|
|
8
|
-
|
9
|
-
|
10
|
-
end
|
15
|
+
freeze
|
16
|
+
end
|
11
17
|
|
12
|
-
|
13
|
-
|
18
|
+
def test front_object, seed: Random.new_seed, color: true, stdout: STDOUT, stderr: STDERR
|
19
|
+
Test.new front_object, seed: Random.new_seed, color: true, stdout: STDOUT, stderr: STDERR
|
14
20
|
end
|
15
21
|
|
16
|
-
def
|
17
|
-
|
22
|
+
def valid? front_object
|
23
|
+
Test.new(front_object).pass?
|
18
24
|
end
|
19
25
|
end
|
20
26
|
end
|
data/lib/fix/subject.rb
CHANGED
@@ -1,22 +1,55 @@
|
|
1
1
|
module Fix
|
2
2
|
class Subject
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :error
|
4
4
|
|
5
|
-
def initialize
|
6
|
-
@
|
7
|
-
@
|
5
|
+
def initialize input, *args
|
6
|
+
@input = input
|
7
|
+
@args = args
|
8
|
+
@error = nil
|
9
|
+
|
10
|
+
@implemented = nil
|
11
|
+
|
12
|
+
begin
|
13
|
+
param_id = 0
|
14
|
+
@cache_value = params.inject(input) do |mem, param|
|
15
|
+
param_id = param_id.next
|
16
|
+
@implemented = mem.respond_to? param.first, false
|
17
|
+
mem.public_send(*param)
|
18
|
+
end
|
19
|
+
rescue => e
|
20
|
+
@error = {
|
21
|
+
exception: e,
|
22
|
+
param_id: param_id
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
freeze
|
27
|
+
end
|
28
|
+
|
29
|
+
def actual
|
30
|
+
if valid?
|
31
|
+
@cache_value.public_send(*challenge)
|
32
|
+
else
|
33
|
+
raise @error.fetch :exception
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def params
|
38
|
+
@args[0..-2]
|
8
39
|
end
|
9
40
|
|
10
|
-
def
|
11
|
-
|
41
|
+
def challenge
|
42
|
+
@args.last
|
12
43
|
end
|
13
44
|
|
14
|
-
def
|
15
|
-
@
|
45
|
+
def implemented?
|
46
|
+
@implemented && valid? && @cache_value.respond_to?(challenge.first, false)
|
16
47
|
end
|
17
48
|
|
18
|
-
|
19
|
-
|
49
|
+
private
|
50
|
+
|
51
|
+
def valid?
|
52
|
+
@error.nil?
|
20
53
|
end
|
21
54
|
end
|
22
55
|
end
|
data/lib/fix/test.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require_relative File.join 'expectation_set'
|
2
|
+
|
3
|
+
module Fix
|
4
|
+
class Test
|
5
|
+
attr_reader :total_time
|
6
|
+
|
7
|
+
def initialize front_object, seed: Random.new_seed, color: true, stdout: STDOUT, stderr: STDERR
|
8
|
+
@options = { color: color, stdout: stdout, stderr: stderr }
|
9
|
+
@options.fetch(:stdout).puts about "Run options: --seed #{seed}"
|
10
|
+
|
11
|
+
random = Random.new seed
|
12
|
+
expectations = ExpectationSet.instance.to_a.shuffle(random: random)
|
13
|
+
|
14
|
+
start_time = Time.now
|
15
|
+
@results = expectations.map do |expectation|
|
16
|
+
log expectation.evaluate front_object
|
17
|
+
end
|
18
|
+
@total_time = Time.now - start_time
|
19
|
+
|
20
|
+
@options.fetch(:stdout).puts about "\nFinished in #{@total_time} seconds."
|
21
|
+
@options.fetch(:stdout).puts statistics
|
22
|
+
|
23
|
+
freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
def pass?
|
27
|
+
@results.all? {|result| state(result) == :success }
|
28
|
+
end
|
29
|
+
|
30
|
+
def fail?
|
31
|
+
!pass?
|
32
|
+
end
|
33
|
+
|
34
|
+
def statistics
|
35
|
+
errors = @results.select {|result| state(result) == :error }
|
36
|
+
failures = @results.select {|result| state(result) == :failure }
|
37
|
+
|
38
|
+
color = if errors.any?
|
39
|
+
:error
|
40
|
+
elsif failures.any?
|
41
|
+
:failure
|
42
|
+
else
|
43
|
+
:success
|
44
|
+
end
|
45
|
+
|
46
|
+
__send__ color, [
|
47
|
+
"#{@results.length} tests",
|
48
|
+
"#{failures.length} failures",
|
49
|
+
"#{errors.length} errors"
|
50
|
+
].join(', ')
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def log result
|
56
|
+
color = state result
|
57
|
+
std = (color == :success ? :stdout : :stderr)
|
58
|
+
|
59
|
+
@options.fetch(std).print __send__ color, char(result)
|
60
|
+
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
def colorize state, string
|
65
|
+
@options[:color] ? "\e[#{state}m#{string}\e[0m" : string
|
66
|
+
end
|
67
|
+
|
68
|
+
def about string
|
69
|
+
colorize 37, string
|
70
|
+
end
|
71
|
+
|
72
|
+
def error string
|
73
|
+
colorize 31, string
|
74
|
+
end
|
75
|
+
|
76
|
+
def success string
|
77
|
+
colorize 32, string
|
78
|
+
end
|
79
|
+
|
80
|
+
def pending string
|
81
|
+
colorize 33, string
|
82
|
+
end
|
83
|
+
|
84
|
+
def matcher string
|
85
|
+
colorize 34, string
|
86
|
+
end
|
87
|
+
|
88
|
+
def failure string
|
89
|
+
colorize 35, string
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the state of the expectation.
|
93
|
+
def state data
|
94
|
+
if data.fetch :pass
|
95
|
+
:success
|
96
|
+
elsif data.fetch(:exception).nil?
|
97
|
+
:failure
|
98
|
+
else
|
99
|
+
:error
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns a char as the result of the expectation.
|
104
|
+
def char data
|
105
|
+
if data.fetch :pass
|
106
|
+
'.'
|
107
|
+
elsif data.fetch(:exception).nil?
|
108
|
+
'F'
|
109
|
+
else
|
110
|
+
'E'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|