-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
217 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ source "http://rubygems.org" | |
|
||
# Specify your gem's dependencies in named_let.gemspec | ||
gemspec | ||
gem 'rspec' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright (c) 2012 Tomohito Ozaki | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
named_let | ||
================================== | ||
|
||
The `named_let can be used to make the rspec's output easier to read. | ||
It's wrapper function of `let`. | ||
|
||
`named_let(:name){ obj }` changes the value which returns 'obj#to_s' and | ||
'obj#inspect' to :name, then output message of 'rspec -format d' be improved more readable. | ||
|
||
# Usage | ||
|
||
describe 'named_let' do | ||
context 'symbol only' do | ||
named_let(:foo) { Object.new } | ||
it { foo.to_s should == "foo" } | ||
it { foo.inspect.should == "foo" } | ||
end | ||
|
||
context 'with label strings' do | ||
named_let(:foo,"label for display"){ Object.new } | ||
it { foo.to_s should == "label for display" } | ||
it { foo.inspect.should == "label for display" } | ||
end | ||
end | ||
|
||
You can use `name_let!` to force the method's invocation before each example, like original `let!`. | ||
|
||
# Why named_let? | ||
|
||
RSpec uses 'Object#inspect' for generating output message from value of specified by `let`. | ||
This will generates unexpected output like 'should == #<Object:0x2aaaaf8a0870A>', it's not human readable. | ||
|
||
Now let's use `named_let` instead of `let`.The generaed output will be more readable like 'should == "label for display'. | ||
|
||
# Example | ||
|
||
For Example, now writing specs for CanCan like bellow, | ||
|
||
require 'spec_helper' | ||
require "cancan/matchers" | ||
|
||
describe Ability do | ||
context 'an user' do | ||
let(:user) { Factory.create(:user) } | ||
|
||
let(:article) { Factory.create(:article) } | ||
let(:own_article) { Factory.create(:article, :user => user) } | ||
|
||
subject { Ability.new(user) } | ||
|
||
it { should be_able_to(:read, article) } | ||
it { should be_able_to(:update, own_article) } | ||
end | ||
end | ||
|
||
|
||
This specs generates outputs is ... | ||
|
||
|
||
$ bundle exec rspec -c --format d spec/models/ability_spec.rb | ||
|
||
Ability | ||
an user | ||
should be able to :read #<Article id: 44, title: "The Test Article 1", body: "This is test article!!", created_at: "2012-02-23 14:19:26", updated_at: "2012-02-23 14:19:26", user_id: nil> | ||
should be able to :update #<Article id: 45, title: "The Test Article 2", body: "This is test article!!", created_at: "2012-02-23 14:19:26", updated_at: "2012-02-23 14:19:26", user_id: 31> | ||
|
||
Finished in 0.26158 seconds | ||
2 examples, 0 failures | ||
|
||
|
||
OMG, It's not human readable. so,let's change `let` to `named_let`. | ||
|
||
named_let(:article) { Factory.create(:article) } | ||
named_let(:own_article) { Factory.create(:article, :user => user) } | ||
|
||
|
||
again, execute `rspec --format d ...` | ||
|
||
|
||
$ bundle exec rspec -c --format d spec/models/ability_spec.rb | ||
|
||
Ability | ||
an user | ||
should be able to :read article | ||
should be able to :update own article | ||
|
||
Finished in 0.25375 seconds | ||
2 examples, 0 failures | ||
|
||
|
||
okay, it's readable!!! | ||
|
||
# For debugging | ||
|
||
If the specs is fail, You will want to know original outputs of 'Object#inspect'. | ||
But named_let hides actual outputs of "Object#inspect". | ||
|
||
Failures: | ||
|
||
1) Ability an user | ||
Failure/Error: it { should_not be_able_to(:update, own_article) } | ||
expected not to be able to :update own article | ||
|
||
|
||
For debugging spec, if given `-d` option to rspec command or `$DEBUG` flag is true, | ||
named_let append orignal result of `Object#inspect` to returns value. | ||
|
||
|
||
given `-d` option, then... | ||
|
||
Failures: | ||
|
||
1) Ability an user | ||
Failure/Error: it { should_not be_able_to(:update, own_article) } | ||
expected not to be able to :update own article (#<Article id: 113, title: "The Test Article 3", body: "This is test article!!", created_at: "2012-02-24 05:53:17", updated_at: "2012-02-24 05:53:17", user_id: 90>) | ||
|
||
|
||
NOTE: | ||
|
||
Requires `ruby-debug` to using `-d` option. | ||
run `gem install ruby-debug`. | ||
If your Ruby-Runtime is 1.9+, see "https://github.com/mark-moseley/ruby-debug". |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,72 @@ | ||
# ------------------------------------------------------------------------------------------------- | ||
# | ||
# named_let can be used to make the rspec's output easier to read. | ||
# | ||
# `named_let(:name){ obj }` changes the value which returns 'obj#to_s' and | ||
# 'obj#inspect' to givne :name, | ||
# then output of 'rspec -format d' will be improved more readable. | ||
# | ||
# ------------------------------------------------------------------------------------------------- | ||
# | ||
# rspecのlet(:name)で定義したオブジェクトのto_sとinspectの値を、:nameに変更する | ||
# | ||
# named_let(:foo){ Object.new } ってやると、 | ||
# foo.to_sが"foo"になる | ||
# | ||
# named_let(:foo,"label for display"){ ... } って第二引数に別名を渡すと、 | ||
# その別名が、to_s/inspectの値になる | ||
# | ||
# subject should == fooとか書いたときの出力が | ||
# ふつうは | ||
# should == #<Object:0x2aaaaf8a0870> | ||
# とかで汚いけど、これをつかうと | ||
# should == "label for display" | ||
# のようにキレイになる | ||
# | ||
# ------------------------------------------------------------------------------------------------- | ||
|
||
require "named_let/version" | ||
|
||
module NamedLet | ||
# Your code goes here... | ||
# In RSpec 2.8, RSpec::Core::Let::ExampleGroupMethods | ||
if RSpec::Core::Version::STRING < "2.8.0" | ||
klass = RSpec::Core::Let::ClassMethods | ||
else | ||
klass = RSpec::Core::Let::ExampleGroupMethods | ||
end | ||
|
||
klass.class_eval do | ||
def named_let(name, label = nil, &block) | ||
define_method(name) do | ||
__memoized.fetch(name) {|k| __memoized[k] = instance_eval(&block).tap{|o| | ||
return o if o.nil? | ||
|
||
the_name = label || name | ||
|
||
# if given -d/--debug option, append calling original ones.(ruby-debug required) | ||
call_super = begin ;$DEBUG or Debugger.started? rescue LoadError; nil; end | ||
|
||
inject_code = lambda{|obj, code| begin; obj.instance_eval code; rescue TypeError; end } | ||
escape = lambda{|str| str.gsub(/\"/, '\\"')} | ||
|
||
genereate_wrapper_code = lambda{|obj, method| | ||
original_result = escape.call(obj.send(method)) if call_super | ||
code = "def #{method}; \"#{the_name}\" #{call_super ? " + \" (#{original_result})\"" : ''} ;end" | ||
} | ||
|
||
to_s_code = genereate_wrapper_code.call(o, :to_s) | ||
inspect_code = genereate_wrapper_code.call(o, :inspect) | ||
|
||
inject_code.call(o, to_s_code) | ||
inject_code.call(o, inspect_code) | ||
o | ||
}} | ||
end | ||
end | ||
|
||
def named_let!(name, label = nil, &block) | ||
named_let(name, label, &block) | ||
before { __send__(name) } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
module NamedLet | ||
VERSION = "0.0.1" | ||
VERSION = "0.1.0" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters