fix 0.0.1.pre → 0.1.0
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/.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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74b5daa559c487d3ea7737a0fd4f58233759c7e2
|
4
|
+
data.tar.gz: 5991787e6e0961b202c12ea2574758cf17bf2755
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6902d25e683dd69f5a516a9a8b3b22a20695d0c168bd2acc1b76a65b509f4d08d5b690553452025ee925d395ad8b694211b8cfecbd024e3b06afd1362b7e16a6
|
7
|
+
data.tar.gz: 2bb3e3b8b59bff07f4092493d95d45c2b4ff590420b33adac42bf913346dcba4c3e6edafa6a67dac4b1bf0e11afad0342b37caf40015a1ff9c2abc188d3aa4d9
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,22 +1,24 @@
|
|
1
1
|
# Fix
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/cyril/fix.rb)
|
4
|
+
[](https://coveralls.io/r/cyril/fix.rb)
|
5
|
+
[](https://gemnasium.com/cyril/fix.rb)
|
6
|
+
[](https://rubygems.org/gems/fix)
|
7
|
+
[](http://inch-ci.org/github/cyril/fix.rb)
|
8
|
+
[](http://rubydoc.info/gems/fix/frames)
|
9
|
+
[](http://cyril.mit-license.org/)
|
4
10
|
|
5
|
-
|
11
|
+
> A specing framework for Ruby.
|
6
12
|
|
7
|
-
##
|
13
|
+
## Contact
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
[](https://codeclimate.com/github/cyril/fix.rb)
|
13
|
-
[](https://gemnasium.com/cyril/fix.rb)
|
14
|
-
[](http://inch-ci.org/github/cyril/fix.rb)
|
15
|
-

|
15
|
+
* Home page: http://fixrb.org/
|
16
|
+
* Bugs/issues: https://github.com/cyril/fix.rb/issues
|
17
|
+
* Support: https://stackoverflow.com/questions/tagged/fix-ruby
|
16
18
|
|
17
19
|
## Rubies
|
18
20
|
|
19
|
-
__Fix__
|
21
|
+
__Fix__ is supported by Ruby (MRI) 2+.
|
20
22
|
|
21
23
|
## Installation
|
22
24
|
|
@@ -28,67 +30,97 @@ gem 'fix'
|
|
28
30
|
|
29
31
|
And then execute:
|
30
32
|
|
31
|
-
|
33
|
+
```shell
|
34
|
+
$ bundle
|
35
|
+
```
|
32
36
|
|
33
37
|
Or install it yourself as:
|
34
38
|
|
35
|
-
|
39
|
+
```shell
|
40
|
+
$ gem install fix
|
41
|
+
```
|
42
|
+
|
43
|
+
## Philosophy
|
36
44
|
|
37
|
-
|
45
|
+
### Minimalist
|
46
|
+
|
47
|
+
With ~400 lignes of **simple code** built on top of [Spectus expectation library](cyril/spectus.rb), facilities such as benchmarking and mocking are not supported. Fix offers however a **consistent** syntax to **DRY** and focus your BDD.
|
48
|
+
|
49
|
+
### Resistant
|
50
|
+
|
51
|
+
While specs behave like **documents** which can be logic-less, their interpretation should not be questioned regardless of the version of Fix, preventing from software erosion. Also, Fix specs are complient with **[RFC 2119](http://tools.ietf.org/html/rfc2119)**.
|
38
52
|
|
39
|
-
|
53
|
+
### Complexity
|
54
|
+
|
55
|
+
Monkey-patching, magic tricks and friends are not included. Instead, animated by **authentic** and **immutable** Ruby objects, unambiguous, understandable and structured specs are encouraged.
|
56
|
+
|
57
|
+
### Objective
|
58
|
+
|
59
|
+
After having loaded atomically the specs in read-only, the code to be tested can also be loaded and evaluated in **isolation** by Fix. There is a separation of concerns between the specs and the code.
|
60
|
+
|
61
|
+
## Usage
|
40
62
|
|
41
63
|
```ruby
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
"OHAI!"
|
64
|
+
class Duck
|
65
|
+
def walks
|
66
|
+
"Klop klop!"
|
46
67
|
end
|
47
68
|
|
48
|
-
def
|
49
|
-
"
|
69
|
+
def swims
|
70
|
+
"Swoosh..."
|
71
|
+
end
|
72
|
+
|
73
|
+
def quacks
|
74
|
+
puts "Quaaaaaack!"
|
50
75
|
end
|
51
76
|
end
|
77
|
+
|
78
|
+
@bird = Duck.new
|
52
79
|
```
|
53
80
|
|
54
|
-
|
81
|
+
> When I see a `#<Duck:0x007f96b285d6d0>` that ...
|
55
82
|
|
56
83
|
```ruby
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
84
|
+
require 'fix'
|
85
|
+
|
86
|
+
@duck_spec = Fix::Spec.new :duck do
|
87
|
+
on :swims do
|
88
|
+
it { SHALL eql: "Swoosh..." }
|
89
|
+
it { MAY capture_stdout: " ...\n" }
|
90
|
+
end
|
91
|
+
|
92
|
+
on :quacks do
|
93
|
+
it { SHOULD capture_stdout: "Quaaaaaack!\n" }
|
94
|
+
end
|
95
|
+
|
96
|
+
on :speaks do
|
97
|
+
it { MUST raise_exception: NoMethodError }
|
98
|
+
end
|
99
|
+
|
100
|
+
on :sings do
|
101
|
+
it { MAY eql: "♪... ♫..." }
|
73
102
|
end
|
74
103
|
end
|
75
|
-
```
|
76
104
|
|
77
|
-
|
105
|
+
case @duck_spec.valid? @bird
|
106
|
+
when true then puts "I call that #{@bird} a duck."
|
107
|
+
else warn 'WAT?'
|
108
|
+
end
|
109
|
+
```
|
78
110
|
|
79
111
|
```bash
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
Finished in 0.
|
84
|
-
|
112
|
+
ruby test.rb
|
113
|
+
# Run options: --seed 241686681690348892099960370893524466040
|
114
|
+
# .....
|
115
|
+
# Finished in 0.001033 seconds.
|
116
|
+
# 5 tests, 0 failures, 0 errors
|
85
117
|
```
|
86
118
|
|
87
|
-
|
119
|
+
> I call that `#<Duck:0x007f96b285d6d0>` a duck.
|
88
120
|
|
89
121
|
## Contributing
|
90
122
|
|
91
|
-
1. Fork it
|
123
|
+
1. [Fork it](https://github.com/cyril/fix.rb/fork)
|
92
124
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
93
125
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
94
126
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -96,8 +128,8 @@ PS: Thanks to the Minitest authors that I picked up the example.
|
|
96
128
|
|
97
129
|
## Versioning
|
98
130
|
|
99
|
-
__Fix__
|
131
|
+
__Fix__ follows [Semantic Versioning 2.0](http://semver.org/)
|
100
132
|
|
101
133
|
## Copyright
|
102
134
|
|
103
|
-
|
135
|
+
© 2014 [Cyril Wack](https://plus.google.com/+CyrilWack?rel=author)
|
data/Rakefile
CHANGED
@@ -1 +1,18 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.pattern = File.join 'spec', '**', '*_spec.rb'
|
6
|
+
t.verbose = true
|
7
|
+
t.warning = true
|
8
|
+
end
|
9
|
+
|
10
|
+
namespace :test do
|
11
|
+
task :coverage do
|
12
|
+
ENV['COVERAGE'] = 'true'
|
13
|
+
Rake::Task['test'].invoke
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
task(:doc_stats) { ruby '-S yard stats' }
|
18
|
+
task default: [:test, :doc_stats]
|
data/VERSION.semver
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
data/example/duck/app.rb
ADDED
data/example/duck/lib.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'fix'
|
2
|
+
|
3
|
+
@spec = Fix::Spec.new :duck do
|
4
|
+
let(:word) { "Quaaa" }
|
5
|
+
|
6
|
+
on :swims do
|
7
|
+
it { MUST capture_stderr: " ...\n" }
|
8
|
+
end
|
9
|
+
|
10
|
+
on :quacks do
|
11
|
+
let(:quaaaaaack) { word + "aaack!\n" }
|
12
|
+
|
13
|
+
it { SHOULD capture_stdout: quaaaaaack }
|
14
|
+
end
|
15
|
+
|
16
|
+
its(:speaks) { MUST raise_exception: NoMethodError }
|
17
|
+
|
18
|
+
on :sings do
|
19
|
+
it { MAY eql: "♪... ♫..." }
|
20
|
+
end
|
21
|
+
|
22
|
+
on :walks do
|
23
|
+
let(:walks) { "#{word}... Klop klop!" }
|
24
|
+
|
25
|
+
it { MUST eql: walks }
|
26
|
+
|
27
|
+
on :split, '... ' do
|
28
|
+
its(:last) { MUST eql: "Klop klop!" }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/fix.gemspec
CHANGED
@@ -3,16 +3,20 @@ Gem::Specification.new do |spec|
|
|
3
3
|
spec.version = File.read('VERSION.semver')
|
4
4
|
spec.authors = ['Cyril Wack']
|
5
5
|
spec.email = ['cyril@sashite.com']
|
6
|
-
spec.summary = %q{
|
7
|
-
spec.description = %q{
|
8
|
-
spec.homepage = '
|
6
|
+
spec.summary = %q{Specing framework.}
|
7
|
+
spec.description = %q{A specing framework for Ruby.}
|
8
|
+
spec.homepage = 'http://fixrb.org/'
|
9
9
|
spec.license = 'MIT'
|
10
10
|
|
11
11
|
spec.files = `git ls-files -z`.split("\x0")
|
12
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
13
12
|
spec.test_files = spec.files.grep(%r{^spec/})
|
14
13
|
spec.require_paths = ['lib']
|
14
|
+
spec.required_ruby_version = '>= 2.0.0'
|
15
15
|
|
16
|
-
spec.
|
17
|
-
|
16
|
+
spec.add_dependency 'spectus', '~> 1.0.0.pre'
|
17
|
+
|
18
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
19
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
20
|
+
spec.add_development_dependency 'yard', '~> 0.8'
|
21
|
+
spec.add_development_dependency 'coveralls', '~> 0.7'
|
18
22
|
end
|
data/lib/fix.rb
CHANGED
@@ -1,20 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
helper
|
4
|
-
base_matcher
|
5
|
-
expectation_target
|
6
|
-
call
|
7
|
-
constant
|
8
|
-
subject
|
9
|
-
spec
|
10
|
-
).each {|path| require_relative File.join 'fix', path }
|
1
|
+
require_relative File.join 'fix', 'spec'
|
2
|
+
require_relative File.join 'fix', 'version'
|
11
3
|
|
4
|
+
# Namespace for the Fix framework.
|
12
5
|
module Fix
|
13
|
-
def constant *syms, &block
|
14
|
-
@@spec = Spec.new *syms, &block
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.run
|
18
|
-
@@spec.run
|
19
|
-
end
|
20
6
|
end
|
data/lib/fix/dsl.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative File.join 'expectation_set'
|
2
|
+
require 'spectus'
|
3
|
+
|
4
|
+
module Fix
|
5
|
+
class Expectation
|
6
|
+
include Spectus::DSL
|
7
|
+
|
8
|
+
def initialize positive, definition, *args
|
9
|
+
@positive = positive
|
10
|
+
@matcher, @expected = definition.to_a.flatten 1
|
11
|
+
@args = args
|
12
|
+
|
13
|
+
freeze
|
14
|
+
|
15
|
+
ExpectationSet.instance.add self
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def pass? report
|
21
|
+
report.pass?
|
22
|
+
end
|
23
|
+
|
24
|
+
def presenter report, got
|
25
|
+
{
|
26
|
+
pass: pass?(report),
|
27
|
+
negated: report.negated,
|
28
|
+
matcher: report.matcher,
|
29
|
+
expected: report.expected,
|
30
|
+
exception: report.exception,
|
31
|
+
got: got
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def meta subject
|
36
|
+
{
|
37
|
+
level: level,
|
38
|
+
params: subject.params,
|
39
|
+
challenge: subject.challenge,
|
40
|
+
subject_exception: subject.error
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def target
|
45
|
+
@positive ? :to : :not_to
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative File.join 'expectation'
|
2
|
+
require_relative File.join 'subject'
|
3
|
+
|
4
|
+
module Fix
|
5
|
+
class ExpectationHigh < Expectation
|
6
|
+
def evaluate front_object
|
7
|
+
subject = Subject.new front_object, *@args
|
8
|
+
got = nil
|
9
|
+
|
10
|
+
Thread.new {
|
11
|
+
report = expect { got = subject.actual }.
|
12
|
+
public_send target, @matcher => @expected
|
13
|
+
|
14
|
+
data = presenter report, got
|
15
|
+
|
16
|
+
Hash[ data.to_a + meta(subject).to_a ]
|
17
|
+
}.value
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def level
|
23
|
+
1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative File.join 'expectation_medium'
|
2
|
+
|
3
|
+
module Fix
|
4
|
+
class ExpectationLow < ExpectationMedium
|
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, subject
|
14
|
+
|
15
|
+
Hash[ data.to_a + meta(subject).to_a ]
|
16
|
+
}.value
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def pass? report, subject
|
22
|
+
if subject.implemented?
|
23
|
+
report.exception.nil?
|
24
|
+
else
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def level
|
30
|
+
3
|
31
|
+
end
|
32
|
+
|
33
|
+
def presenter report, got, subject
|
34
|
+
{
|
35
|
+
pass: pass?(report, subject),
|
36
|
+
negated: report.negated,
|
37
|
+
matcher: report.matcher,
|
38
|
+
expected: report.expected,
|
39
|
+
exception: report.exception,
|
40
|
+
got: got
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|