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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.travis.yml +4 -2
  4. data/README.md +81 -49
  5. data/Rakefile +17 -0
  6. data/VERSION.semver +1 -1
  7. data/example/duck/README.md +9 -0
  8. data/example/duck/app.rb +3 -0
  9. data/example/duck/lib.rb +14 -0
  10. data/example/duck/spec.rb +31 -0
  11. data/example/duck/test.rb +6 -0
  12. data/fix.gemspec +10 -6
  13. data/lib/fix.rb +3 -17
  14. data/lib/fix/dsl.rb +10 -0
  15. data/lib/fix/expectation.rb +48 -0
  16. data/lib/fix/expectation_high.rb +26 -0
  17. data/lib/fix/expectation_low.rb +44 -0
  18. data/lib/fix/expectation_medium.rb +29 -0
  19. data/lib/fix/expectation_set.rb +8 -0
  20. data/lib/fix/helper/it_helper.rb +12 -0
  21. data/lib/fix/helper/its_helper.rb +12 -0
  22. data/lib/fix/helper/let_accessor_helper.rb +11 -0
  23. data/lib/fix/helper/let_reader_helper.rb +9 -0
  24. data/lib/fix/helper/let_writer_helper.rb +13 -0
  25. data/lib/fix/helper/on_helper.rb +12 -0
  26. data/lib/fix/helper/requirement_helper.rb +44 -0
  27. data/lib/fix/it.rb +14 -0
  28. data/lib/fix/its.rb +14 -0
  29. data/lib/fix/on.rb +20 -0
  30. data/lib/fix/spec.rb +16 -10
  31. data/lib/fix/subject.rb +43 -10
  32. data/lib/fix/test.rb +114 -0
  33. data/lib/fix/version.rb +9 -0
  34. data/spec/TODO +0 -0
  35. data/spec/spec_helper.rb +2 -4
  36. data/spec/support.rb +3 -0
  37. data/spec/support/coverage.rb +3 -0
  38. data/spec/support/env.rb +4 -0
  39. data/spec/support/presenter.rb +0 -0
  40. metadata +85 -22
  41. data/.ruby-version +0 -1
  42. data/bin/fix +0 -58
  43. data/lib/fix/base_matcher.rb +0 -38
  44. data/lib/fix/call.rb +0 -16
  45. data/lib/fix/constant.rb +0 -37
  46. data/lib/fix/expectation_target.rb +0 -41
  47. data/lib/fix/helper.rb +0 -34
  48. data/lib/fix/scope.rb +0 -20
  49. data/logo.png +0 -0
  50. data/logo.svg +0 -19
  51. data/spec/subject_spec.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e0bdb51428d1e9befcd3f876463ec42ecd33f24
4
- data.tar.gz: 080b67c3571d376c76c11c7073a1905179a5e79e
3
+ metadata.gz: 74b5daa559c487d3ea7737a0fd4f58233759c7e2
4
+ data.tar.gz: 5991787e6e0961b202c12ea2574758cf17bf2755
5
5
  SHA512:
6
- metadata.gz: e2cce45a87309814780a680087b0f8c6805ec87e53960c5e56d047894f5aeef544bc3053dcaed099c023a970cb5e585043aa8857937300ede5cd6a7eadd4c801
7
- data.tar.gz: 7733c37958d09da34948aaf7b357874bfc9cfc647849aaf0baac451b6c0731b73c46c418d0a9424ace1171ad047ef95e568478f2f2d9fa6940f315bb1cc064d4
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
@@ -1,4 +1,6 @@
1
1
  language: ruby
2
- script: 'bundle exec rake test'
2
+ script: 'bundle exec rake test:coverage'
3
3
  rvm:
4
- - 2.1.2
4
+ - 2.0.0
5
+ - 2.1.3
6
+ - ruby-head
data/README.md CHANGED
@@ -1,22 +1,24 @@
1
1
  # Fix
2
2
 
3
- Minimal and fast BDD framework for Ruby.
3
+ [![Build Status](https://travis-ci.org/cyril/fix.rb.svg?branch=master)](https://travis-ci.org/cyril/fix.rb)
4
+ [![Coverage Status](http://img.shields.io/coveralls/cyril/fix.rb.svg?branch=master)](https://coveralls.io/r/cyril/fix.rb)
5
+ [![Dependency Status](https://gemnasium.com/cyril/fix.rb.svg)](https://gemnasium.com/cyril/fix.rb)
6
+ [![Gem Version](http://img.shields.io/gem/v/fix.svg)](https://rubygems.org/gems/fix)
7
+ [![Inline docs](http://inch-ci.org/github/cyril/fix.rb.svg?branch=master)](http://inch-ci.org/github/cyril/fix.rb)
8
+ [![Documentation](http://img.shields.io/:yard-docs-38c800.svg)](http://rubydoc.info/gems/fix/frames)
9
+ [![License](http://img.shields.io/:license-MIT-38c800.svg)](http://cyril.mit-license.org/)
4
10
 
5
- ![Fix](https://raw.githubusercontent.com/cyril/fix.rb/master/logo.svg)
11
+ > A specing framework for Ruby.
6
12
 
7
- ## Status
13
+ ## Contact
8
14
 
9
- [![Gem Version](https://badge.fury.io/rb/fix.png)](http://badge.fury.io/rb/fix)
10
- [![Build Status](https://secure.travis-ci.org/cyril/fix.rb.png?branch=master)](http://travis-ci.org/cyril/fix.rb?branch=master)
11
- [![Coverage](https://coveralls.io/repos/cyril/fix.rb/badge.png?branch=master)](https://coveralls.io/r/cyril/fix.rb)
12
- [![Code Climate](https://codeclimate.com/github/cyril/fix.rb.png)](https://codeclimate.com/github/cyril/fix.rb)
13
- [![Dependencies](https://gemnasium.com/cyril/fix.rb.png)](https://gemnasium.com/cyril/fix.rb)
14
- [![Inline docs](http://inch-ci.org/github/cyril/fix.rb.png)](http://inch-ci.org/github/cyril/fix.rb)
15
- ![](https://ruby-gem-downloads-badge.herokuapp.com/fix?type=total)
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__ supports Ruby (MRI) 2+.
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
- $ bundle
33
+ ```shell
34
+ $ bundle
35
+ ```
32
36
 
33
37
  Or install it yourself as:
34
38
 
35
- $ gem install fix
39
+ ```shell
40
+ $ gem install fix
41
+ ```
42
+
43
+ ## Philosophy
36
44
 
37
- ## Usage
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
- Given that you'd like to test the following class:
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
- # app.rb
43
- class Meme
44
- def i_can_has_cheezburger?
45
- "OHAI!"
64
+ class Duck
65
+ def walks
66
+ "Klop klop!"
46
67
  end
47
68
 
48
- def will_it_blend?
49
- "YES!"
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
- Define your tests as methods:
81
+ > When I see a `#<Duck:0x007f96b285d6d0>` that ...
55
82
 
56
83
  ```ruby
57
- # spec.rb
58
- require "app"
59
-
60
- constant :Meme do
61
- call :new do
62
- scope "when asked about cheeseburgers" do
63
- call :i_can_has_cheezburger? do
64
- subject.should eql "OHAI!"
65
- end
66
- end
67
-
68
- scope "when asked about blending possibilities" do
69
- call :will_it_blend? do
70
- subject.should_not match /^no/i
71
- end
72
- end
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
- And then, test it:
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
- $ fix ./spec.rb
81
- /Users/bob/spec.rb
82
- ..
83
- Finished in 0.004397 seconds
84
- 2 examples, 0 failures
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
- PS: Thanks to the Minitest authors that I picked up the example.
119
+ > I call that `#<Duck:0x007f96b285d6d0>` a duck.
88
120
 
89
121
  ## Contributing
90
122
 
91
- 1. Fork it ( https://github.com/cyril/fix.rb/fork )
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__ uses [Semantic Versioning 2.0.0](http://semver.org).
131
+ __Fix__ follows [Semantic Versioning 2.0](http://semver.org/)
100
132
 
101
133
  ## Copyright
102
134
 
103
- Copyright 2014 Cyril Wack – Released under [MIT License](LICENSE.md)
135
+ &copy; 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.0.1.pre
1
+ 0.1.0
@@ -0,0 +1,9 @@
1
+ # Duck example
2
+
3
+ ```bash
4
+ $ ./test.rb
5
+ Run options: --seed 122743552393459455928023127107893880649
6
+ ......
7
+ Finished in 0.001181 seconds.
8
+ 6 tests, 0 failures, 0 errors
9
+ ```
@@ -0,0 +1,3 @@
1
+ require_relative 'lib'
2
+
3
+ @app = Duck.new
@@ -0,0 +1,14 @@
1
+ class Duck
2
+ def walks
3
+ "Quaaa... Klop klop!"
4
+ end
5
+
6
+ def swims
7
+ warn " ..."
8
+ "Quaaa.."
9
+ end
10
+
11
+ def quacks
12
+ puts "Quaaaaaack!"
13
+ end
14
+ end
@@ -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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby -w
2
+
3
+ require_relative 'app'
4
+ require_relative 'spec'
5
+
6
+ @spec.test @app
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{Fix and keep the green code.}
7
- spec.description = %q{Minimal and fast BDD framework for Ruby.}
8
- spec.homepage = 'https://github.com/cyril/fix.rb'
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.add_development_dependency 'bundler', '~> 1.7'
17
- spec.add_development_dependency 'rake', '~> 10.0'
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
- %w(set thread).each {|lib| require lib }
2
- %w(
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,10 @@
1
+ require_relative File.join 'helper', 'its_helper'
2
+ require_relative File.join 'helper', 'on_helper'
3
+
4
+ module Fix
5
+ module DSL
6
+ include Helper::ItsHelper
7
+ include Helper::LetWriterHelper
8
+ include Helper::OnHelper
9
+ end
10
+ end
@@ -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