Skip to content

Commit

Permalink
initial release of 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
yuroyoro committed Feb 24, 2012
1 parent e67d2d8 commit f850d6b
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 7 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ source "http://rubygems.org"

# Specify your gem's dependencies in named_let.gemspec
gemspec
gem 'rspec'
20 changes: 20 additions & 0 deletions LICENSE
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.
122 changes: 122 additions & 0 deletions README.md
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".
69 changes: 68 additions & 1 deletion lib/named_let.rb
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
2 changes: 1 addition & 1 deletion lib/named_let/version.rb
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
10 changes: 5 additions & 5 deletions named_let.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Gem::Specification.new do |s|
s.authors = ["Tomohito Ozaki"]
s.email = ["ozaki@yuroyoro.com"]
s.homepage = ""
s.summary = %q{TODO: Write a gem summary}
s.description = %q{TODO: Write a gem description}
s.summary = %q{named_let can be used to make the rspec's output easier to read.}
s.description = %q{`named_let(:name){ obj }` changes the value which returns 'obj#to_s' and 'obj#inspect' to :name, then output of 'rspec -format d' be improved more readable.}

s.rubyforge_project = "named_let"

Expand All @@ -18,7 +18,7 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

# specify any dependencies here; for example:
# s.add_development_dependency "rspec"
# s.add_runtime_dependency "rest-client"
# dependencies
s.add_development_dependency "rspec"
s.add_runtime_dependency "rspec-core"
end

0 comments on commit f850d6b

Please sign in to comment.