look_like 0.1.6 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1baeea6bcba7b7808e9c2544b26ebc63d9385c8f
4
- data.tar.gz: b56daa0e4153b0b65c90b55d3b71fd8eb5531740
3
+ metadata.gz: d9c585287d41ac062e6f2ae3b1198487761aaa39
4
+ data.tar.gz: 494d617b9a9f152a8ddb45b0b50c2c820d408afd
5
5
  SHA512:
6
- metadata.gz: 2cb721b150dd6e5fbe0573d28631140eea679de1743a338c5fc3a293f72acd9f852f2877b2ca85168ea16f72db9be3bc606af4bd9e0c3541e1e6bbb2d1740284
7
- data.tar.gz: 7c5048f7c6e056c825a36b4b6a2aba9695d58c5ba7d83ac1c8f81fd11861b3cd43c8f4058b76f6f85a9b5ad44b9b535da2305814d3b41315ebcbccaf82e1b014
6
+ metadata.gz: 32af77c7ea96abdd0739f64bd77a0f1506bcea1f10b44a01948829050634f6c628ac0f40fc6d35d6ca7e57652b31c9860316a7b661329888958bd1cf49419c22
7
+ data.tar.gz: 88ec374c3dcf61b73ba4564e0a5efb098a61ea4e7d7d6c50ec57f20dec4d139383a71c0a176f8455587b60f5a56f0280e87f38cd0cdd5d0442c113922ddecf73
data/.gitignore CHANGED
@@ -8,4 +8,5 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  .idea
11
- *.iml
11
+ *.iml
12
+ coverage
data/Gemfile CHANGED
@@ -3,3 +3,4 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in look_like.gemspec
4
4
  gem "rspec"
5
5
  gem "rake"
6
+ gem 'coveralls', require: false
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
- # look_like matcher
2
- This gem is a collection of rspec matchers, for writing wireframe tests.
3
- These are useful for writing sanity tests in higher environments where we cannot control the data consumed by an app.
4
- This can also be used in a production environment.
5
- You can reuse your code/specs for regression tests.
1
+ # look_like matcher [![Build Status](https://travis-ci.org/nishants/look_like.svg?branch=master)](https://travis-ci.org/nishants/look_like) [![Coverage Status](https://coveralls.io/repos/github/nishants/look_like/badge.svg)](https://coveralls.io/github/nishants/look_like) [![Gem Version](https://badge.fury.io/rb/look_like.svg)](https://badge.fury.io/rb/look_like)
2
+
3
+ - This gem is a collection of rspec matchers, for writing wireframe tests.
4
+ - Such tests search for visual clues for detecting presence of a bug.
5
+ - Useful for writing sanity tests in higher environments, e.g. testing your fresh deploy to production.
6
+ - These can reuse your code for regression tests.
7
+ - Meaningful assertion reports help in quick diagnosis of faults.
8
+ - For example you can write test for fresh deployments to make sure the currency and language are correct by domain/user.
6
9
 
7
10
  ## Installation
8
11
 
@@ -14,10 +17,11 @@ gem 'look_like'
14
17
 
15
18
  And then execute:
16
19
 
17
- $ bundle install
20
+ ```bash
21
+ $ bundle install
22
+ ```
18
23
 
19
24
  ## Usage
20
- Following will result in error :
21
25
  ```ruby
22
26
  it "single word is different than two words" do
23
27
  expect("Sam").to look_like("Sam Dam")
@@ -34,25 +38,44 @@ end
34
38
  LookLike::Matchers.define({
35
39
  :name => :single_word,
36
40
  :desc => "single word",
37
- :priority => 7,
38
- :select => lambda{|keyword|},
41
+ :select => lambda{|expected|},
39
42
  :match => lambda{|actual, expected|}
40
43
  })
41
44
  ```
42
45
 
43
46
 
44
- ## Development
47
+ ## Writing wireframe tests
48
+ In your feature file, define how your table should look like (visually) :
49
+ ```gherkin
50
+ Scenario: View employees detail table
51
+ Given I am an admin
52
+ Then I should see employees table like
53
+ |FirstName |LastName | Salary |Email |
54
+ |Magan |Sharma | $200,00 |a@b.com|
55
+ ```
45
56
 
46
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
57
+ In your steps, get table rows as array of array
58
+ ```ruby
59
+ Then(/^I should see employees table like:$/) do |table_definition|
60
+ table = homepage.open.employee_table
61
+ expect(table).to look_like(table_definition)
62
+ end
63
+ ```
47
64
 
48
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
65
+ ## Development
66
+ - After checking out the repo, run `bin/setup` to install dependencies.
67
+ - Then, run `rake spec` to run the tests.
68
+ - You can also run `bin/console` for an interactive prompt that will allow you to experiment.
69
+ - To install this gem locally, run `bundle exec rake install`.
70
+ - To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`
71
+ - Release task will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
72
+ - Build report : https://travis-ci.org/nishants/look_like
73
+ - Coverage Repoprt : https://coveralls.io/github/nishants/look_like
49
74
 
50
75
  ## Contributing
51
-
52
- Bug reports and pull requests are welcome on GitHub at https://github.com/[nishants]/look_like.
53
-
76
+ - Report bugs or suggest improvements at https://github.com/nishants/look_like/issues.
77
+ - Pull requests are highly welcome at at https://github.com/nishants/look_like.
54
78
 
55
79
  ## License
56
-
57
80
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
58
81
 
@@ -0,0 +1,60 @@
1
+ module LookLike
2
+ class ArrayMatcher < Matcher
3
+
4
+ def initialize(matchers)
5
+ @matchers = matchers
6
+ end
7
+
8
+
9
+ def element_error(actual, expected)
10
+ @matchers.find { |matcher| matcher.select(expected) }.error(actual, expected)
11
+ end
12
+
13
+
14
+ def match_element(actual, expected)
15
+ @matchers.find { |matcher| matcher.select(expected) }.match(actual, expected)
16
+ end
17
+
18
+ def match(actual_array, expected_array)
19
+ match_array(actual_array, expected_array)
20
+ end
21
+
22
+ def match_array(actual_array, expected_array)
23
+ matches = expected_array.length == actual_array.length
24
+ actual_array.each_with_index { |actual, index|
25
+ expected = expected_array[index]
26
+ matches = matches && match_element(actual, expected)
27
+ }
28
+ matches
29
+ end
30
+
31
+ def select(expected)
32
+ expected.is_a? Array
33
+ end
34
+
35
+ def error(actual_array, expected_array)
36
+ array_error(actual_array, expected_array)
37
+ end
38
+
39
+ def array_error(actual_array, expected_array)
40
+ message = []
41
+ if (expected_array.length > actual_array.length)
42
+ message.push("Expected #{ expected_array.length } elements, but found #{actual_array.length}.")
43
+ message.push("Expected : [#{ expected_array.join(", ") }]")
44
+ message.push("Found : [#{ actual_array.join(", ") }]")
45
+ return message.join(". ")
46
+ end
47
+ actual_array.each_with_index { |actual, index|
48
+ expected = expected_array[index]
49
+ message.push(match_element(actual, expected) ? "✓" : "x [#{element_error(actual, expected)}]")
50
+ }
51
+ "[#{message.join(", ")}]"
52
+ end
53
+
54
+ def negate_error(actual, expected)
55
+ "#{"Expected not to match." + error(actual, expected)}"
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -1,27 +1,36 @@
1
-
2
1
  module LookLike
3
2
  class Matcher
4
3
  attr_accessor :name
5
4
  attr_accessor :desc
6
- attr_accessor :priority
7
5
  attr_accessor :select
8
6
  attr_accessor :match
7
+ attr_accessor :error
9
8
 
10
9
  def initialize(config)
11
10
  @name = config[:name]
12
11
  @desc = config[:desc]
13
- @priority = config[:priority]
14
12
  @selector = config[:select]
15
13
  @matcher = config[:match]
16
14
  end
17
15
 
16
+ def error(actual, expected)
17
+ "\"#{actual}\" does not look like \"#{expected}\" (#{@desc})"
18
+ end
19
+
20
+ def negate_error(actual, expected)
21
+ "Did not expect :\"#{actual}\" to look like : \"#{expected}\" (#{@desc})"
22
+ end
23
+
18
24
  def match(actual, expected)
19
- @matcher.call(actual, expected)
25
+ optionally_empty = expected.is_a?(String) && expected.end_with?("*") && (actual.nil? || actual.strip.eql?(""))
26
+ expected = expected.is_a?(String) ? expected.sub("*", "").strip : expected
27
+ optionally_empty || !actual.nil? && (@matcher.parameters.length == 2 ? @matcher.call(actual, expected) : @matcher.call(actual))
20
28
  end
21
29
 
22
- def apply(key)
23
- @selector.call(key)
30
+ def select(expected)
31
+ @selector.call(expected.sub("*", "").strip)
24
32
  end
25
33
 
26
34
  end
27
- end
35
+
36
+ end
@@ -0,0 +1,12 @@
1
+ LookLike::Matchers.define(
2
+ {
3
+ :name => :any_value,
4
+ :desc => "any value",
5
+ :select => lambda{|expected|
6
+ expected.strip.eql?("") || expected.strip.eql?("*")
7
+ },
8
+ :match => lambda{|actual, expected|
9
+ true
10
+ }
11
+ })
12
+
@@ -0,0 +1,12 @@
1
+ LookLike::Matchers.define(
2
+ {
3
+ :name => :email,
4
+ :desc => "email",
5
+ :select => lambda{|expected|
6
+ expected.eql?("email") || LookLike::Support.email?(expected)
7
+ },
8
+ :match => lambda{|actual|
9
+ LookLike::Support.email?(actual)
10
+ }
11
+ })
12
+
@@ -0,0 +1,8 @@
1
+ LookLike::Matchers.define(
2
+ {
3
+ :name => :enum,
4
+ :desc => "enum",
5
+ :select => lambda{|expected| LookLike::Support.enum?(expected) },
6
+ :match => lambda{|actual, expected| LookLike::Support.enum_values(expected).include?(actual) }
7
+ })
8
+
@@ -0,0 +1,16 @@
1
+ LookLike::Matchers.define(
2
+ {
3
+ :name => :amount,
4
+ :desc => "amount",
5
+ :select => lambda{|expected|
6
+ expected.end_with?("amount") || LookLike::Support.amount?(expected)
7
+ },
8
+ :match => lambda{|actual, expected|
9
+ currency = LookLike::Support.currency_of(expected)
10
+ unless currency == "$"
11
+ actual = actual.sub("$", "x").sub(currency, "$")
12
+ end
13
+ LookLike::Support.amount?(actual)
14
+ }
15
+ })
16
+
@@ -0,0 +1,8 @@
1
+ format = /^[\d,]+\d$/
2
+ LookLike::Matchers.define(
3
+ {
4
+ :name => :fomatted_number,
5
+ :desc => "formatted number",
6
+ :select => lambda{|expected| format === expected },
7
+ :match => lambda{|actual| format === actual }
8
+ })
@@ -0,0 +1,9 @@
1
+ format = /^[\d]+$/
2
+ LookLike::Matchers.define(
3
+ {
4
+ :name => :number,
5
+ :desc => "number",
6
+ :select => lambda{|expected| format === expected },
7
+ :match => lambda{|actual| format === actual }
8
+ })
9
+
@@ -0,0 +1,12 @@
1
+ LookLike::Matchers.define(
2
+ {
3
+ :name => :regex,
4
+ :desc => "regex ",
5
+ :select => lambda{|expected|
6
+ expected.start_with?("/") && expected.end_with?("/")
7
+ },
8
+ :match => lambda{|actual, expected|
9
+ Regexp.new(expected.tr("/", "").strip) === actual
10
+ }
11
+ })
12
+
@@ -0,0 +1,12 @@
1
+ LookLike::Matchers.define(
2
+ {
3
+ :name => :string,
4
+ :desc => "string",
5
+ :select => lambda{|expected|
6
+ expected.strip.length > 0
7
+ },
8
+ :match => lambda{ |actual|
9
+ actual.strip.length > 0
10
+ }
11
+ })
12
+
@@ -0,0 +1,13 @@
1
+ require("uri")
2
+
3
+ LookLike::Matchers.define(
4
+ {
5
+ :name => :url,
6
+ :desc => "url",
7
+ :select => lambda { |expected|
8
+ expected.eql?("url") || LookLike::Support.url?(expected)
9
+ },
10
+ :match => lambda { |actual|
11
+ LookLike::Support.url?(actual) || LookLike::Support.loose_url?(actual)
12
+ }
13
+ })
@@ -0,0 +1,27 @@
1
+ module LookLike
2
+ class Matchers
3
+ @@matchers = []
4
+
5
+ def self.define(config)
6
+ @@matchers.unshift(LookLike::Matcher.new(config))
7
+ end
8
+
9
+ def self.find(expected)
10
+ matchers = [LookLike::NestedArrayMatcher.new(@@matchers), LookLike::ArrayMatcher.new(@@matchers)] + @@matchers
11
+ matchers.find { |matcher| matcher.select(expected) }
12
+ end
13
+
14
+ def self.match(actual, expected)
15
+ find(expected).match(actual, expected)
16
+ end
17
+
18
+ def self.error(actual, expected)
19
+ find(expected).error(actual, expected)
20
+ end
21
+
22
+ def self.negate_error(actual, expected)
23
+ find(expected).negate_error(actual, expected)
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,26 @@
1
+ module LookLike
2
+ class NestedArrayMatcher < ArrayMatcher
3
+ def match(actual, expected)
4
+ matches = true
5
+ expected_array = expected[0]
6
+ actual.each { |actual_array|
7
+ matches &&= match_array(actual_array, expected_array)
8
+ }
9
+ matches
10
+ end
11
+
12
+ def select(expected)
13
+ expected.is_a?(Array) && expected.length > 0 && expected[0].is_a?(Array)
14
+ end
15
+
16
+ def error(actual, expected)
17
+ message = []
18
+ expected_array = expected[0]
19
+ actual.each { |actual_array|
20
+ message.push(match_array(actual_array, expected_array) ? "✓" : "x [#{array_error(actual_array, expected_array)}]")
21
+ }
22
+ "[#{message.join(", ")}]"
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ require 'rspec/expectations'
2
+
3
+ RSpec::Matchers.define :look_like do |expected|
4
+
5
+ match do |actual|
6
+ LookLike::Matchers.match(actual, expected)
7
+ end
8
+
9
+ failure_message do |actual|
10
+ LookLike::Matchers.error(actual, expected)
11
+ end
12
+
13
+ failure_message_when_negated do |actual|
14
+ LookLike::Matchers.negate_error(actual, expected)
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ require "uri"
2
+ module LookLike
3
+ class Support
4
+
5
+ def self.url?(string)
6
+ !!(string =~ /\A#{URI::regexp}\z/)
7
+ end
8
+
9
+ def self.amount?(string)
10
+ rounded = string.sub(".", ",").strip
11
+ /^\$[\s]*[\d,]+\d$/ === rounded
12
+ end
13
+
14
+ def self.enum?(string)
15
+ /^[^\/]+[\/][^\/]/ === string
16
+ end
17
+
18
+ def self.loose_url?(string)
19
+ if(string.strip.length && string.include?("."))
20
+ string = "http://" + string
21
+ end
22
+ !!(string =~ /\A#{URI::regexp}\z/)
23
+ end
24
+
25
+ def self.currency_of(amount)
26
+ amount.end_with?("amount") ? amount.split("amount")[0].strip : amount[/^[^\d]+/].strip
27
+ end
28
+
29
+ def self.enum_values(list)
30
+ list.split("/").map{|value| value.strip()}
31
+ end
32
+
33
+ def self.email?(string)
34
+ string.include?("@") && !string.include?("/") && loose_url?(string)
35
+ end
36
+
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module LookLike
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/look_like.rb CHANGED
@@ -1,24 +1,18 @@
1
1
  require "look_like/version"
2
2
  require "look_like/matcher"
3
+ require "look_like/array-matcher"
4
+ require "look_like/nested-array-matcher"
5
+ require "look_like/matchers"
6
+ require "look_like/rspec-matcher"
7
+ require "look_like/support"
3
8
 
4
- module LookLike
5
- class Matchers
6
- @@matchers = []
7
- def self.define(config)
8
- @@matchers.push(LookLike::Matcher.new(config))
9
- end
9
+ require "look_like/matchers/any-value"
10
+ require "look_like/matchers/string"
11
+ require "look_like/matchers/email"
12
+ require "look_like/matchers/enum"
13
+ require "look_like/matchers/url"
14
+ require "look_like/matchers/regex"
15
+ require "look_like/matchers/formatted-number"
16
+ require "look_like/matchers/formatted-amount"
17
+ require "look_like/matchers/number"
10
18
 
11
- def self.find(keyword)
12
- @@matchers.find { |matcher|
13
- matcher.apply(keyword)
14
- }
15
- end
16
-
17
- def self.load
18
- Dir[File.expand_path(File.join(File.dirname(File.absolute_path(__FILE__)), "matchers")) + "/**/*.rb"].each { |file| require file }
19
- end
20
-
21
- end
22
- end
23
-
24
- LookLike::Matchers.load()
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: look_like
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nishant
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-18 00:00:00.000000000 Z
11
+ date: 2016-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -71,12 +71,23 @@ files:
71
71
  - bin/console
72
72
  - bin/setup
73
73
  - lib/look_like.rb
74
+ - lib/look_like/array-matcher.rb
74
75
  - lib/look_like/matcher.rb
76
+ - lib/look_like/matchers.rb
77
+ - lib/look_like/matchers/any-value.rb
78
+ - lib/look_like/matchers/email.rb
79
+ - lib/look_like/matchers/enum.rb
80
+ - lib/look_like/matchers/formatted-amount.rb
81
+ - lib/look_like/matchers/formatted-number.rb
82
+ - lib/look_like/matchers/number.rb
83
+ - lib/look_like/matchers/regex.rb
84
+ - lib/look_like/matchers/string.rb
85
+ - lib/look_like/matchers/url.rb
86
+ - lib/look_like/nested-array-matcher.rb
87
+ - lib/look_like/rspec-matcher.rb
88
+ - lib/look_like/support.rb
75
89
  - lib/look_like/version.rb
76
- - lib/matchers/equality.rb
77
- - lib/matchers/rspec-matcher.rb
78
90
  - look_like.gemspec
79
- - look_like.iml
80
91
  homepage: http://amoeba.social
81
92
  licenses:
82
93
  - MIT
@@ -1,12 +0,0 @@
1
- LookLike::Matchers.define({
2
- :name => :equality,
3
- :desc => "",
4
- :priority => 6,
5
- :select => lambda{|keyword|
6
- true
7
- },
8
- :match => lambda{|actual, expected|
9
- actual == expected
10
- }
11
- })
12
-
@@ -1,17 +0,0 @@
1
- require 'rspec/expectations'
2
-
3
- RSpec::Matchers.define :look_like do |expected|
4
- messages = {}
5
-
6
- match do |actual|
7
- messages[actual] = LookLike::Matchers.find(expected).match(actual, expected)
8
- end
9
-
10
- def method_name(actual, actual_desc, expected, expected_desc)
11
- "expected \"#{actual}\" (#{actual_desc}), \nto look like \"#{expected}\" (#{expected_desc})"
12
- end
13
-
14
- failure_message do |actual|
15
- messages[actual]
16
- end
17
- end
data/look_like.iml DELETED
@@ -1,28 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="RUBY_MODULE" version="4">
3
- <component name="FacetManager">
4
- <facet type="gem" name="Ruby Gem">
5
- <configuration>
6
- <option name="GEM_APP_ROOT_PATH" value="$MODULE_DIR$" />
7
- <option name="GEM_APP_TEST_PATH" value="$MODULE_DIR$/test" />
8
- <option name="GEM_APP_LIB_PATH" value="$MODULE_DIR$/lib" />
9
- </configuration>
10
- </facet>
11
- </component>
12
- <component name="NewModuleRootManager" inherit-compiler-output="true">
13
- <exclude-output />
14
- <content url="file://$MODULE_DIR$">
15
- <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
16
- </content>
17
- <orderEntry type="jdk" jdkName="rbenv: 2.1.4" jdkType="RUBY_SDK" />
18
- <orderEntry type="sourceFolder" forTests="false" />
19
- <orderEntry type="library" scope="PROVIDED" name="bundler (v1.13.0.rc.1, rbenv: 2.1.4) [gem]" level="application" />
20
- <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, rbenv: 2.1.4) [gem]" level="application" />
21
- <orderEntry type="library" scope="PROVIDED" name="rake (v11.2.2, rbenv: 2.1.4) [gem]" level="application" />
22
- <orderEntry type="library" scope="PROVIDED" name="rspec (v3.5.0, rbenv: 2.1.4) [gem]" level="application" />
23
- <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.5.3, rbenv: 2.1.4) [gem]" level="application" />
24
- <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.5.0, rbenv: 2.1.4) [gem]" level="application" />
25
- <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.5.0, rbenv: 2.1.4) [gem]" level="application" />
26
- <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.5.0, rbenv: 2.1.4) [gem]" level="application" />
27
- </component>
28
- </module>