respectable 0.2.0 → 0.3.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: 9573aa714bfb9221aa80b0632f9547861aaf776d
4
- data.tar.gz: 2141a67cdce9d1fd0411b6ef4d001c951edeea79
3
+ metadata.gz: b3c0bcc9e014d61f695000c265275561c737bf59
4
+ data.tar.gz: ef138f804d1cc905ef53f143d302f221c7a464fd
5
5
  SHA512:
6
- metadata.gz: e586552b082fe3f98b57fb3530acd17a8187f612de7f286119796d5a938a1a52cf6eb1d314674db3c5bad73dc6a9d1dc13e5039b3336a17caddcbf13a759661d
7
- data.tar.gz: ed908a57599cb0aa8b9e71358da923d6a585eb303f8355b55c35e69541dc7946dea41e112743936060f7d21e58be27e2e9787b4260702719081efd1a4bf9111b
6
+ metadata.gz: c0cfc6d9d96d0d983c2bfa203a82275137ce6d2e0cd0858167a2a1fa3b9e7043a6faaab2d274f67e4083849725034098c34937f162fbcd8605c8a8f5811d920a
7
+ data.tar.gz: 9f4f27dc30d5efc6893f9a507cd6939067e20c3d4fcb71c36e7e1f00e39f13fc17045a27a60876e5363c44b9e5f19189e4a55b352d468ef0abc1500081811460
data/.gitlab-ci.yml CHANGED
@@ -1,8 +1,18 @@
1
- image: ruby:2.3
2
-
3
- spec:
1
+ .spec: &spec
4
2
  tags:
5
3
  - docker
6
4
  script:
7
5
  - bundle install --path vendor --without production --jobs $(nproc) > /dev/null
8
- - bin/rspec
6
+ - bin/rspec
7
+
8
+ spec2.0:
9
+ image: ruby:2.0
10
+ <<: *spec
11
+
12
+ spec2.1:
13
+ image: ruby:2.1
14
+ <<: *spec
15
+
16
+ spec2.3:
17
+ image: ruby:2.3
18
+ <<: *spec
data/CHANGELOG.md ADDED
@@ -0,0 +1,24 @@
1
+ ## unreleased
2
+
3
+ ### Fixed/Added/Deprecated/Removed
4
+
5
+ * ...
6
+
7
+ ## 0.3.0 / 2016-10-26
8
+
9
+ ### Added
10
+
11
+ * `specify_each` replaces `each_row`
12
+ * **BREAKING**: the block you pass to `specify_each` will be wrapped in an it-block.
13
+
14
+ This means that an error will occur if your block contains an it-block **or** specify_each is wrapped in an it-block (i.e. in all cases ;).
15
+ Solution: remove any it-block surrounding or contained in the specify_each-block.
16
+
17
+ * Have a default description
18
+
19
+ The format is `first: "Foo", last: "Bar" yields "Foo Bar"`.
20
+ Customize this by passing `desc: "full_name(%{first}, %{last}) => %{result}"` to `specify_each`
21
+
22
+ ### Deprecated
23
+
24
+ * `each_row`. Use `specify_each` instead.
data/README.md CHANGED
@@ -11,19 +11,19 @@ So instead of:
11
11
  ```ruby
12
12
  describe '#full_name' do
13
13
  it 'concats first and last' do
14
- expect(build(:user, first: 'Foo', last: 'Bar').full_name).to eq 'Foo Bar'
14
+ expect(User.new(first: 'Foo', last: 'Bar').full_name).to eq 'Foo Bar'
15
15
  end
16
16
 
17
17
  it 'does smart casing stuff' do
18
- expect(build(:user, first: 'Foo', last: 'Van Bar').full_name).to eq 'Foo van Bar'
18
+ expect(User.new(first: 'Foo', last: 'Van Bar').full_name).to eq 'Foo van Bar'
19
19
  end
20
20
 
21
21
  it 'handles last being nil' do
22
- expect(build(:user, first: 'First', last: nil).full_name).to eq 'Foo'
22
+ expect(User.new(first: 'First', last: nil).full_name).to eq 'Foo'
23
23
  end
24
24
 
25
25
  it 'handles first being nil' do
26
- expect(build(:user, first: nil, last: 'Bar').full_name).to eq 'Bar'
26
+ expect(User.new(first: nil, last: 'Bar').full_name).to eq 'Bar'
27
27
  end
28
28
  end
29
29
  ```
@@ -32,23 +32,67 @@ end
32
32
 
33
33
  ```ruby
34
34
  describe '#full_name' do
35
- it 'concats first and last' do
36
- each_row(<<-TABLE) do |first, last, expected|
37
- #| first | last | expected |
38
- | Foo | Bar | Foo Bar |
39
- | Foo | Van Bar | Foo van Bar |
40
- | Foo | `nil` | Foo |
41
- | `nil` | Bar | Bar |
42
- TABLE
43
-
44
- expect(build(:user, first: first, last: last).full_name).to eq expected
45
- end
35
+ specify_each(<<-TABLE) do |first, last, expected|
36
+ #| first | last | expected |
37
+ | Foo | Bar | Foo Bar |
38
+ | Foo | Van Bar | Foo van Bar |
39
+ | Foo | `nil` | Foo |
40
+ | `nil` | Bar | Bar |
41
+ TABLE
42
+
43
+ expect(User.new(first: first, last: last).full_name).to eq expected
46
44
  end
47
45
  end
48
46
  ```
49
47
 
50
48
  You just got yourself a *table* in your *rspec*! (who told you naming was hard?)
51
49
 
50
+ ## Details
51
+
52
+ ### Literal values
53
+
54
+ By default values from the table are passed to the block as stripped strings. For more expressiveness you can use backticks; this allows you to pass literal values (e.g. \`nil\`, \`:some_symbol\`, \`true\`, \`1 + 1\`) to the block.
55
+
56
+ ### Description
57
+
58
+ For every row in the table an it-block is created. The description of this block will be of the format:
59
+ `column1-name: "cell-value", column2-name: "cell-value" yields "value of last column"`.
60
+ So for the full_name-example above the full RSpec-output (using `--format documentation`) is:
61
+ ```
62
+ #full_name
63
+ first: "Foo", last: "Bar" yields "Foo Bar"
64
+ first: "Foo", last: "Van Bar" yields "Foo van Bar"
65
+ first: "Foo", last: "`nil`" yields "Foo"
66
+ first: "`nil`", last: "Bar" yields "Bar"
67
+ ```
68
+
69
+ You can customize the description by passing a template to `specify_each` in which you can use the block parameters, e.g.:
70
+ ```ruby
71
+ specify_each(<<-TABLE, desc: 'full_name(%{first}, %{last}) => %{expected}') do |first, last, expected|
72
+ ```
73
+
74
+ If you want the standard RSpec-description you can pass `desc: nil` to `specify_each`.
75
+
76
+ ### Comments
77
+
78
+ Just like in Ruby, you can comment (the remainder of) a line by using `#`. This helps to document the table:
79
+ ```ruby
80
+ specify_each(<<-TABLE) do |arg1, arg2, result|
81
+ # | arg1 (never negative) | arg2 | + |
82
+ | 1 | 2 | 3 |
83
+ | 10 | 2 | 12 | # <= important edge-case
84
+ TABLE
85
+ expect(...)
86
+ end
87
+ ```
88
+
89
+ ### Various
90
+
91
+ You can escape the pipe character (`|`) by prefixing it with `\\`:
92
+ ```
93
+ | This table has one cell with a \\| |
94
+ ```
95
+
52
96
  ## Installation
53
97
 
54
98
  Add this line to your application's Gemfile:
data/lib/respectable.rb CHANGED
@@ -1,23 +1,56 @@
1
- require "respectable/version"
2
- require 'csv'
1
+ require 'respectable/version'
3
2
 
4
3
  module Respectable
5
4
  def self.included(base)
6
- base.extend Meat
5
+ base.extend Interface
7
6
  base.class_eval do
8
- include Meat
7
+ include Interface
9
8
  end
10
9
  end
11
10
 
12
- module Meat
13
- def each_row(string, &block)
14
- string.split(/\n */).reject {|line| line[/^ *#/] }.map do |line|
15
- yield(*line.split(/ *(?<!\\)\| */)[1..-1].map do |i|
16
- i = i.sub(/\\(?=|)/, '') # remove escapes for '|'
17
- # handle `...`
18
- r = i[/\A`([^`]+)`\z/, 1]
19
- r ? eval(r) : i
20
- end)
11
+ module Interface
12
+ def specify_each(table, **options, &block)
13
+ desc_template = options.has_key?(:desc) ? options[:desc] : Util.desc_template(block.parameters)
14
+
15
+ define_method(:specify_each) do |*, &block|
16
+ block.call(*@args) if @args
17
+ end
18
+
19
+ Util.table_data(table).each do |row|
20
+ # TODO: can we use raw row-value? (for outline)
21
+ desc_data = Hash[block.parameters.map(&:last).zip(row.map(&:inspect))]
22
+ description = desc_template % desc_data if desc_template
23
+ instance_eval(<<-IT, *block.source_location)
24
+ it(description) do
25
+ @args = Util.eval_row_items(row, binding)
26
+ eval(block.source, binding, *block.source_location)
27
+ end
28
+ IT
29
+ end
30
+ end
31
+ end
32
+
33
+ module Util
34
+ def self.desc_template(block_params)
35
+ *desc_args, desc_result = *block_params.map(&:last)
36
+ desc_args.map {|arg| "#{arg}: %{#{arg}}" }.join(', ') + " yields %{#{desc_result}}"
37
+ end
38
+
39
+ def self.table_data(table)
40
+ table.split(/\n */).reject {|line| line[/^ *#/] }.map do |line|
41
+ cols = line.split(/ *(?<!\\)\| */)[1..-1]
42
+ comment_col = cols.size
43
+ cols.each_with_index {|col, ix| comment_col = ix if col[/^ *#/] }
44
+ cols[0, comment_col]
45
+ end
46
+ end
47
+
48
+ def self.eval_row_items(row, binding)
49
+ row.map do |i|
50
+ i = i.sub(/\\(?=|)/, '') # remove escapes for '|'
51
+ # handle `...`
52
+ r = i[/\A`([^`]+)`\z/, 1]
53
+ r ? binding.eval(r) : i
21
54
  end
22
55
  end
23
56
  end
@@ -1,3 +1,3 @@
1
1
  module Respectable
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: respectable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gert Goet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-09 00:00:00.000000000 Z
11
+ date: 2016-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -77,6 +77,7 @@ files:
77
77
  - ".gitlab-ci.yml"
78
78
  - ".rspec"
79
79
  - ".travis.yml"
80
+ - CHANGELOG.md
80
81
  - Gemfile
81
82
  - LICENSE.txt
82
83
  - README.md
@@ -111,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
112
  version: '0'
112
113
  requirements: []
113
114
  rubyforge_project:
114
- rubygems_version: 2.4.5
115
+ rubygems_version: 2.2.2
115
116
  signing_key:
116
117
  specification_version: 4
117
118
  summary: Scenario outlines for rspec