truenames 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.swp
19
+ *.swo
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in truenames.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jason Morrison
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Truenames
2
+
3
+ Improve test failure output by introspecting variable names.
4
+
5
+ Sometimes this is hard to read:
6
+
7
+ ```
8
+ 1) User when looked up with a GitHub OAuth callback hash updates with the most recent information
9
+ Failure/Error: expect(lookup_user).to eq(existing_user)
10
+
11
+ expected: #<User id: 684, uid: 74387, oauth_token: "oldtoken", nickname: "oldnick", email: "old@email.com", name: "Old Name", created_at: "2012-10-13 06:26:11", updated_at: "2012-10-13 06:26:11">
12
+ got: #<User id: 685, uid: 12345, oauth_token: "token-abc123", nickname: "jasonm", email: "jason@example.com", name: "Jason Morrison", created_at: "2012-10-13 06:26:11", updated_at: "2012-10-13 06:26:11">
13
+ ```
14
+
15
+ and something like this might be easier:
16
+
17
+ ```
18
+ 1) User when looked up with a GitHub OAuth callback hash updates with the most recent information
19
+ Failure/Error: expect(lookup_user).to eq(existing_user)
20
+
21
+ expected: lookup_user
22
+ got: unrelated_user
23
+ ```
24
+
25
+ ## Installation
26
+
27
+ Add this line to your application's Gemfile:
28
+
29
+ gem 'truenames'
30
+
31
+ And then execute:
32
+
33
+ $ bundle
34
+
35
+ Or install it yourself as:
36
+
37
+ $ gem install truenames
38
+
39
+ ## Usage
40
+
41
+ For RSpec usage, add `require 'truenames/rspec'` to `spec/spec_helper.rb`.
42
+
43
+ ## Contributing
44
+
45
+ 1. Fork it
46
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
47
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
48
+ 4. Push to the branch (`git push origin my-new-feature`)
49
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/truenames.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'truenames/version'
2
+ require 'rspec-expectations'
3
+ require "truenames/matchers/expr_eq"
4
+
5
+ module Truenames
6
+ end
@@ -0,0 +1,71 @@
1
+ require 'rspec/matchers/built_in/eq'
2
+ require 'binding_of_caller'
3
+
4
+ module Truenames
5
+ module Matchers
6
+ def expr_eq(other)
7
+ Truenames::Matchers::ExprEq.new(other)
8
+ end
9
+
10
+ class ExprEq < RSpec::Matchers::BuiltIn::Eq
11
+ def initialize(expected = nil)
12
+ @expected = expected
13
+
14
+ # One to escape this binding, one to escape the Truenames::Matchers#expr_eq wrapper method
15
+ @binding = binding.of_caller(2)
16
+ end
17
+
18
+ def name
19
+ "eq"
20
+ end
21
+
22
+ def failure_message_for_should
23
+ "\nexpected: #{expected.inspect}#{inspect_references_for(expected)}\n" +
24
+ " got: #{actual.inspect}#{inspect_references_for(actual)}\n\n(compared using ==)\n"
25
+ end
26
+
27
+ private
28
+
29
+ def inspect_references_for(value)
30
+ references = reference_names_for(value)
31
+
32
+ if references.empty?
33
+ ''
34
+ else
35
+ " (#{references})"
36
+ end
37
+ end
38
+
39
+ def reference_names_for(value)
40
+ if value.is_a?(Array)
41
+ "[" + value.map { |each_value| [reference_names_for(each_value)].flatten.first }.join(', ') + "]"
42
+ else
43
+ (matching_locals(value) + matching_ivars(value)).join(' or ')
44
+ end
45
+ end
46
+
47
+ def matching_locals(value)
48
+ binding_locals.select { |local| useful_match?(@binding.eval(local.to_s), value) }
49
+ end
50
+
51
+ def matching_ivars(value)
52
+ binding_ivars.select { |ivar| useful_match?(@binding.eval(ivar.to_s), value) }
53
+ end
54
+
55
+ def useful_match?(candidate, value)
56
+ # exclude the matcher itself
57
+ return false if candidate.is_a?(RSpec::Matchers::BuiltIn::Eq)
58
+
59
+ candidate == value
60
+ end
61
+
62
+ def binding_locals
63
+ @binding.eval("local_variables")
64
+ end
65
+
66
+ def binding_ivars
67
+ @binding.eval("instance_variables")
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ module RSpec::Matchers
2
+ include Truenames::Matchers
3
+ end
@@ -0,0 +1,3 @@
1
+ module Truenames
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'truenames'
2
+ require 'truenames/rspec'
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe Truenames::Matchers::ExprEq do
4
+ it "matches when actual == expected" do
5
+ 1.should expr_eq(1)
6
+ end
7
+
8
+ it "does not match when actual != expected" do
9
+ 1.should_not expr_eq(2)
10
+ end
11
+
12
+ it "compares by sending == to actual (not expected)" do
13
+ called = false
14
+ actual = Class.new do
15
+ define_method :== do |other|
16
+ called = true
17
+ end
18
+ end.new
19
+
20
+ actual.should expr_eq :anything # to trigger the matches? method
21
+ called.should be_true
22
+ end
23
+
24
+ it "describes itself" do
25
+ matcher = expr_eq(1)
26
+ matcher.matches?(1)
27
+ matcher.description.should eq "eq 1"
28
+ end
29
+
30
+ it "provides message, expected and actual on #failure_message" do
31
+ matcher = expr_eq("1")
32
+ matcher.matches?(1)
33
+ matcher.failure_message_for_should.should eq "\nexpected: \"1\"\n got: 1\n\n(compared using ==)\n"
34
+ end
35
+
36
+ it "provides message, expected and actual on #negative_failure_message" do
37
+ matcher = expr_eq(1)
38
+ matcher.matches?(1)
39
+ matcher.failure_message_for_should_not.should eq "\nexpected: value != 1\n got: 1\n\n(compared using ==)\n"
40
+ end
41
+
42
+ it "provides local variable reference when available" do
43
+ abc = 123
44
+ bcd = 234
45
+
46
+ matcher = expr_eq(abc)
47
+ matcher.matches?(bcd)
48
+ matcher.failure_message_for_should.should eq "\nexpected: 123 (abc)\n got: 234 (bcd)\n\n(compared using ==)\n"
49
+ end
50
+
51
+ it "provides multiple local variable references when they exist" do
52
+ zab = 123
53
+ abc = 123
54
+ bcd = 234
55
+ cde = 234
56
+
57
+ matcher = expr_eq(abc)
58
+ matcher.matches?(bcd)
59
+ matcher.failure_message_for_should.should eq "\nexpected: 123 (zab or abc)\n got: 234 (bcd or cde)\n\n(compared using ==)\n"
60
+ end
61
+
62
+ it "provides instance variable reference when available" do
63
+ @abc = 123
64
+ @bcd = 234
65
+
66
+ matcher = expr_eq(@abc)
67
+ matcher.matches?(@bcd)
68
+ matcher.failure_message_for_should.should eq "\nexpected: 123 (@abc)\n got: 234 (@bcd)\n\n(compared using ==)\n"
69
+ end
70
+
71
+ it "provides local variable references inside arrays" do
72
+ a = 1
73
+ b = 2
74
+ c = 3
75
+ d = 4
76
+ e = 5
77
+
78
+ matcher = expr_eq([a,b,c])
79
+ matcher.matches?([c,d,e])
80
+ matcher.failure_message_for_should.should eq "\nexpected: [1, 2, 3] ([a, b, c])\n got: [3, 4, 5] ([c, d, e])\n\n(compared using ==)\n"
81
+ end
82
+
83
+ it "displays ambiguous matches inside arrays " do
84
+ z = 1
85
+ a = 1
86
+ b = 2
87
+ c = 3
88
+ d = 4
89
+ e = 5
90
+ f = 5
91
+
92
+ matcher = expr_eq([a,b,c])
93
+ matcher.matches?([c,d,e])
94
+ matcher.failure_message_for_should.should eq "\nexpected: [1, 2, 3] ([z or a, b, c])\n got: [3, 4, 5] ([c, d, e or f])\n\n(compared using ==)\n"
95
+ end
96
+ end
data/truenames.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'truenames/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "truenames"
8
+ gem.version = Truenames::VERSION
9
+ gem.authors = ["Jason Morrison"]
10
+ gem.email = ["jason.p.morrison@gmail.com"]
11
+ gem.description = %q{Improve test failure output by introspecting variable names.}
12
+ gem.summary = %q{Use local variables and expressions to give more information about assertion failures.}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency 'rspec'
21
+ gem.add_development_dependency 'binding_of_caller'
22
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: truenames
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jason Morrison
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: binding_of_caller
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Improve test failure output by introspecting variable names.
47
+ email:
48
+ - jason.p.morrison@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .rspec
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - lib/truenames.rb
60
+ - lib/truenames/matchers/expr_eq.rb
61
+ - lib/truenames/rspec.rb
62
+ - lib/truenames/version.rb
63
+ - spec/spec_helper.rb
64
+ - spec/truenames/matchers/expr_eq_spec.rb
65
+ - truenames.gemspec
66
+ homepage: ''
67
+ licenses: []
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.24
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Use local variables and expressions to give more information about assertion
90
+ failures.
91
+ test_files:
92
+ - spec/spec_helper.rb
93
+ - spec/truenames/matchers/expr_eq_spec.rb
94
+ has_rdoc: