mortadella 1.0.0 → 1.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 +5 -5
- data/.github/workflows/ruby.yml +28 -0
- data/.rubocop.yml +8 -27
- data/CHANGELOG.md +36 -0
- data/DEVELOPMENT.md +16 -0
- data/Gemfile +11 -1
- data/Gemfile.lock +84 -74
- data/LICENSE.txt +1 -1
- data/README.md +47 -36
- data/Rakefile +20 -8
- data/cucumber.yml +1 -0
- data/documentation/ingredients.png +0 -0
- data/dprint.json +13 -0
- data/features/horizontal_tables/basic_usage.feature +3 -11
- data/features/horizontal_tables/drying_up_fields.feature +11 -24
- data/features/horizontal_tables/emptiness.feature +5 -11
- data/features/horizontal_tables/keep_matching_columns.feature +12 -0
- data/features/step_definitions/steps.rb +6 -7
- data/features/support/env.rb +8 -5
- data/features/vertical_tables/basic_usage.feature +5 -13
- data/features/vertical_tables/emptiness.feature +5 -9
- data/git-town.toml +7 -0
- data/lib/mortadella/horizontal.rb +63 -31
- data/lib/mortadella/vertical.rb +23 -8
- data/lib/mortadella.rb +18 -4
- data/mortadella.gemspec +21 -18
- metadata +24 -99
- data/.ruby-version +0 -1
- data/circle.yml +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 89f81d195a7c95dc3c7a9481087b7b82a8e099c86db2245da940233ff2c0a76f
|
|
4
|
+
data.tar.gz: 38a0f7e70a8fd87234b71b09fe2b622262c024fedf9be2ebc1f8e0e663a3f72f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '083bbf046a76c7f6ea292b6705f899fcd6f79f44a4905aed0d2f84da806d92c9dd7758c448b5a6712c6ea9729ef1ac3fff0b9aa0b00787f7452a7688f0b5d314'
|
|
7
|
+
data.tar.gz: 44ffd063b09507b25f49f8c4164cea2b1a1b974f5311511c85882b73d4c444fe302e740bca5db681c6fcce53a2528e267b0b88fef9d84b833013058c7cdb490b
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["main"]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
matrix:
|
|
17
|
+
ruby-version: ["3.4"]
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
- uses: dprint/check@v2.2
|
|
21
|
+
- uses: ruby/setup-ruby@v1
|
|
22
|
+
with:
|
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
24
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
25
|
+
- run: bundle exec rake
|
|
26
|
+
- run: bundle exec rake fix
|
|
27
|
+
- run: git diff HEAD --exit-code --color
|
|
28
|
+
- uses: coverallsapp/github-action@v2
|
data/.rubocop.yml
CHANGED
|
@@ -1,35 +1,16 @@
|
|
|
1
1
|
AllCops:
|
|
2
|
-
|
|
2
|
+
NewCops: enable
|
|
3
3
|
DisplayCopNames: true
|
|
4
|
-
|
|
5
4
|
DisplayStyleGuide: true
|
|
6
|
-
|
|
7
5
|
Include:
|
|
8
|
-
-
|
|
9
|
-
|
|
6
|
+
- "**/Rakefile"
|
|
7
|
+
SuggestExtensions: false
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
Enabled: false
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Metrics/LineLength:
|
|
9
|
+
Layout/LineLength:
|
|
16
10
|
Max: 100
|
|
17
11
|
|
|
12
|
+
Style/StringLiterals:
|
|
13
|
+
EnforcedStyle: double_quotes
|
|
18
14
|
|
|
19
|
-
Style/
|
|
20
|
-
EnforcedStyle:
|
|
21
|
-
|
|
22
|
-
Style/EmptyLines:
|
|
23
|
-
Enabled: false
|
|
24
|
-
|
|
25
|
-
Style/EmptyLinesAroundClassBody:
|
|
26
|
-
EnforcedStyle: empty_lines
|
|
27
|
-
|
|
28
|
-
Style/EmptyLinesAroundModuleBody:
|
|
29
|
-
EnforcedStyle: empty_lines
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Style/MethodDefParentheses:
|
|
34
|
-
EnforcedStyle: require_no_parentheses
|
|
35
|
-
|
|
15
|
+
Style/SymbolArray:
|
|
16
|
+
EnforcedStyle: brackets
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
## 1.2.0 (2025-11-04)
|
|
4
|
+
|
|
5
|
+
- Add ability to hash tables
|
|
6
|
+
- Verify argument types
|
|
7
|
+
- Add YARD type signatures
|
|
8
|
+
- Improved dry-up algorithm
|
|
9
|
+
- Validate the length of added rows
|
|
10
|
+
|
|
11
|
+
## 1.1.0 (2016-08-25)
|
|
12
|
+
|
|
13
|
+
- Keep matching columns functionality to filter tables
|
|
14
|
+
|
|
15
|
+
## 1.0.0 (2015-12-22)
|
|
16
|
+
|
|
17
|
+
- Stable release with improved API stability
|
|
18
|
+
- Emptiness checking for vertical tables
|
|
19
|
+
|
|
20
|
+
## 0.2.2 (2015-12-09)
|
|
21
|
+
|
|
22
|
+
- Limited visibility of internal methods
|
|
23
|
+
|
|
24
|
+
## 0.2.1 (2015-10-18)
|
|
25
|
+
|
|
26
|
+
- Better require support for easier gem loading
|
|
27
|
+
|
|
28
|
+
## 0.2.0 (2022-10-18)
|
|
29
|
+
|
|
30
|
+
- Vertical tables
|
|
31
|
+
|
|
32
|
+
## 0.1.0 (2015-06-02)
|
|
33
|
+
|
|
34
|
+
- Horizontal table support with headers and rows
|
|
35
|
+
- Dry-up functionality for repeated values
|
|
36
|
+
- Cucumber table compatibility
|
data/DEVELOPMENT.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Developer guidelines
|
|
2
|
+
|
|
3
|
+
- set up local environment: `bundle install`
|
|
4
|
+
- run all tests: `rake` (or `rake default`)
|
|
5
|
+
- run linters: `rake lint`
|
|
6
|
+
- auto-fix all issues: `rake fix`
|
|
7
|
+
- run tests only: `rake features`
|
|
8
|
+
|
|
9
|
+
## Release a new version to RubyGems
|
|
10
|
+
|
|
11
|
+
- in a branch:
|
|
12
|
+
- update CHANGELOG.md
|
|
13
|
+
- search and replace all occurrences of `1.2.0`
|
|
14
|
+
- run `bundle install`
|
|
15
|
+
- ship this branch
|
|
16
|
+
- push a new version to Rubygems: `rake release`
|
data/Gemfile
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
2
4
|
|
|
3
5
|
# Specify your gem's dependencies in mortadella.gemspec
|
|
4
6
|
gemspec
|
|
7
|
+
|
|
8
|
+
gem "bundler"
|
|
9
|
+
gem "cucumber"
|
|
10
|
+
gem "logger"
|
|
11
|
+
gem "rake"
|
|
12
|
+
gem "rspec"
|
|
13
|
+
gem "rubocop"
|
|
14
|
+
gem "simplecov"
|
data/Gemfile.lock
CHANGED
|
@@ -1,97 +1,107 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
mortadella (1.
|
|
4
|
+
mortadella (1.2.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
-
ast (2.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
rspec
|
|
55
|
-
rspec-
|
|
56
|
-
|
|
9
|
+
ast (2.4.3)
|
|
10
|
+
bigdecimal (3.1.9)
|
|
11
|
+
builder (3.3.0)
|
|
12
|
+
cucumber (9.2.1)
|
|
13
|
+
builder (~> 3.2)
|
|
14
|
+
cucumber-ci-environment (> 9, < 11)
|
|
15
|
+
cucumber-core (> 13, < 14)
|
|
16
|
+
cucumber-cucumber-expressions (~> 17.0)
|
|
17
|
+
cucumber-gherkin (> 24, < 28)
|
|
18
|
+
cucumber-html-formatter (> 20.3, < 22)
|
|
19
|
+
cucumber-messages (> 19, < 25)
|
|
20
|
+
diff-lcs (~> 1.5)
|
|
21
|
+
mini_mime (~> 1.1)
|
|
22
|
+
multi_test (~> 1.1)
|
|
23
|
+
sys-uname (~> 1.2)
|
|
24
|
+
cucumber-ci-environment (10.0.1)
|
|
25
|
+
cucumber-core (13.0.3)
|
|
26
|
+
cucumber-gherkin (>= 27, < 28)
|
|
27
|
+
cucumber-messages (>= 20, < 23)
|
|
28
|
+
cucumber-tag-expressions (> 5, < 7)
|
|
29
|
+
cucumber-cucumber-expressions (17.1.0)
|
|
30
|
+
bigdecimal
|
|
31
|
+
cucumber-gherkin (27.0.0)
|
|
32
|
+
cucumber-messages (>= 19.1.4, < 23)
|
|
33
|
+
cucumber-html-formatter (21.9.0)
|
|
34
|
+
cucumber-messages (> 19, < 28)
|
|
35
|
+
cucumber-messages (22.0.0)
|
|
36
|
+
cucumber-tag-expressions (6.1.2)
|
|
37
|
+
diff-lcs (1.6.0)
|
|
38
|
+
docile (1.4.1)
|
|
39
|
+
ffi (1.17.1)
|
|
40
|
+
json (2.10.2)
|
|
41
|
+
language_server-protocol (3.17.0.4)
|
|
42
|
+
lint_roller (1.1.0)
|
|
43
|
+
logger (1.6.6)
|
|
44
|
+
mini_mime (1.1.5)
|
|
45
|
+
multi_test (1.1.0)
|
|
46
|
+
parallel (1.26.3)
|
|
47
|
+
parser (3.3.7.1)
|
|
48
|
+
ast (~> 2.4.1)
|
|
49
|
+
racc
|
|
50
|
+
racc (1.8.1)
|
|
51
|
+
rainbow (3.1.1)
|
|
52
|
+
rake (13.2.1)
|
|
53
|
+
regexp_parser (2.10.0)
|
|
54
|
+
rspec (3.13.0)
|
|
55
|
+
rspec-core (~> 3.13.0)
|
|
56
|
+
rspec-expectations (~> 3.13.0)
|
|
57
|
+
rspec-mocks (~> 3.13.0)
|
|
58
|
+
rspec-core (3.13.3)
|
|
59
|
+
rspec-support (~> 3.13.0)
|
|
60
|
+
rspec-expectations (3.13.3)
|
|
57
61
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
58
|
-
rspec-support (~> 3.
|
|
59
|
-
rspec-mocks (3.
|
|
62
|
+
rspec-support (~> 3.13.0)
|
|
63
|
+
rspec-mocks (3.13.2)
|
|
60
64
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
61
|
-
rspec-support (~> 3.
|
|
62
|
-
rspec-support (3.
|
|
63
|
-
rubocop (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
rspec-support (~> 3.13.0)
|
|
66
|
+
rspec-support (3.13.2)
|
|
67
|
+
rubocop (1.74.0)
|
|
68
|
+
json (~> 2.3)
|
|
69
|
+
language_server-protocol (~> 3.17.0.2)
|
|
70
|
+
lint_roller (~> 1.1.0)
|
|
71
|
+
parallel (~> 1.10)
|
|
72
|
+
parser (>= 3.3.0.2)
|
|
73
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
74
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
75
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
|
68
76
|
ruby-progressbar (~> 1.7)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
78
|
+
rubocop-ast (1.40.0)
|
|
79
|
+
parser (>= 3.3.1.0)
|
|
80
|
+
ruby-progressbar (1.13.0)
|
|
81
|
+
simplecov (0.22.0)
|
|
82
|
+
docile (~> 1.1)
|
|
83
|
+
simplecov-html (~> 0.11)
|
|
84
|
+
simplecov_json_formatter (~> 0.1)
|
|
85
|
+
simplecov-html (0.13.1)
|
|
86
|
+
simplecov_json_formatter (0.1.4)
|
|
87
|
+
sys-uname (1.3.1)
|
|
88
|
+
ffi (~> 1.1)
|
|
89
|
+
unicode-display_width (3.1.4)
|
|
90
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
|
91
|
+
unicode-emoji (4.0.4)
|
|
83
92
|
|
|
84
93
|
PLATFORMS
|
|
85
94
|
ruby
|
|
86
95
|
|
|
87
96
|
DEPENDENCIES
|
|
88
97
|
bundler
|
|
89
|
-
coveralls
|
|
90
98
|
cucumber
|
|
99
|
+
logger
|
|
91
100
|
mortadella!
|
|
92
101
|
rake
|
|
93
102
|
rspec
|
|
94
103
|
rubocop
|
|
104
|
+
simplecov
|
|
95
105
|
|
|
96
106
|
BUNDLED WITH
|
|
97
|
-
|
|
107
|
+
2.6.6
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,37 +1,30 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Mortadella for Ruby
|
|
2
2
|
|
|
3
|
-
[](https://coveralls.io/github/Originate/mortadella?branch=master)
|
|
6
|
-
[](https://gemnasium.com/Originate/mortadella)
|
|
3
|
+
[](https://github.com/kevgo/mortadella-ruby/actions/workflows/ruby.yml)
|
|
4
|
+
[](https://coveralls.io/github/kevgo/mortadella-ruby?branch=main)
|
|
7
5
|
|
|
6
|
+
Mortadella for Ruby makes it easy to programmatically build data tables that can
|
|
7
|
+
be compared to [Cucumber for Ruby](https://github.com/cucumber/cucumber-ruby)
|
|
8
|
+
tables through `cucumber_table.diff! mortadella_table`.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
through `cucumber_table.diff! mortadella_table`.
|
|
12
|
-
|
|
13
|
-
You want to do this as much as possible.
|
|
14
|
-
Cucumber has very powerful built-in facilities
|
|
15
|
-
to visualize where and how two tables differ.
|
|
16
|
-
|
|
17
|
-
<img src="http://blog.originate.com/mortadella/ingredients2.png" >
|
|
18
|
-
_Oh no, our algorithm selected too many apples!_
|
|
10
|
+
You want to do this as much as possible. Cucumber for Ruby has very powerful
|
|
11
|
+
built-in facilities to visualize where and how two tables differ:
|
|
19
12
|
|
|
13
|
+
<img src="https://raw.githubusercontent.com/kevgo/mortadella/master/documentation/ingredients.png" width="292" height="139">
|
|
14
|
+
<i>Oh no, our algorithm selected too many apples!</i>
|
|
20
15
|
|
|
21
16
|
## Installation
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
- add `gem 'mortadella'` to your `Gemfile`
|
|
19
|
+
- run `bundle install`
|
|
26
20
|
|
|
27
21
|
## Usage
|
|
28
22
|
|
|
29
23
|
Mortadella supports horizontal and vertical Cucumber tables.
|
|
30
24
|
|
|
31
|
-
|
|
32
25
|
### Horizontal Tables
|
|
33
26
|
|
|
34
|
-
|
|
27
|
+
- In your cucumber spec, define the expected data in table form
|
|
35
28
|
|
|
36
29
|
```cucumber
|
|
37
30
|
Then I have these ingredients
|
|
@@ -41,8 +34,8 @@ Mortadella supports horizontal and vertical Cucumber tables.
|
|
|
41
34
|
| apples | 3 pc |
|
|
42
35
|
```
|
|
43
36
|
|
|
44
|
-
|
|
45
|
-
and diff the Cucumber table with the expected data against it.
|
|
37
|
+
- in the step definition for this, build an equivalent Mortadella table with the
|
|
38
|
+
actual data, and diff the Cucumber table with the expected data against it.
|
|
46
39
|
|
|
47
40
|
```ruby
|
|
48
41
|
Then /^I have these ingredients$/ do |expected_ingredients|
|
|
@@ -54,14 +47,24 @@ Mortadella supports horizontal and vertical Cucumber tables.
|
|
|
54
47
|
end
|
|
55
48
|
```
|
|
56
49
|
|
|
57
|
-
|
|
58
|
-
[dry up repetitive fields](https://github.com/
|
|
59
|
-
for better readability
|
|
50
|
+
- you can also
|
|
51
|
+
[dry up repetitive fields](https://github.com/kevgo/mortadella/blob/master/features/horizontal_tables/drying_up_fields.feature)
|
|
52
|
+
for better readability:
|
|
60
53
|
|
|
54
|
+
```cucumber
|
|
55
|
+
| DAY | ACTIVITY |
|
|
56
|
+
| Monday | mowing |
|
|
57
|
+
| | musing |
|
|
58
|
+
| Tuesday | typing |
|
|
59
|
+
| | tutoring |
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- or filter the columns of your finished table by calling
|
|
63
|
+
[keep_matching_columns](features/horizontal_tables/keep_matching_columns.feature)
|
|
61
64
|
|
|
62
65
|
### Vertical Tables
|
|
63
66
|
|
|
64
|
-
|
|
67
|
+
- In your cucumber spec, define the expected data in table form
|
|
65
68
|
|
|
66
69
|
```cucumber
|
|
67
70
|
Then my pie conforms to these specs:
|
|
@@ -70,8 +73,8 @@ Mortadella supports horizontal and vertical Cucumber tables.
|
|
|
70
73
|
| CALORIES | 500 |
|
|
71
74
|
```
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
and diff the Cucumber table with the expected data against it.
|
|
76
|
+
- in the step definition for this, build an equivalent Mortadella table with the
|
|
77
|
+
actual data, and diff the Cucumber table with the expected data against it.
|
|
75
78
|
|
|
76
79
|
```ruby
|
|
77
80
|
Then /^My pie has these metrics:$/ do |expected_metrics|
|
|
@@ -83,13 +86,21 @@ Mortadella supports horizontal and vertical Cucumber tables.
|
|
|
83
86
|
end
|
|
84
87
|
```
|
|
85
88
|
|
|
89
|
+
## API Reference
|
|
90
|
+
|
|
91
|
+
### Horizontal Tables
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
- `new(headers:, dry: [])` - Create a new horizontal table with column headers
|
|
94
|
+
- `<<(row)` - Add a row to the table
|
|
95
|
+
- `empty?` - Check if the table has no data rows
|
|
96
|
+
- `keep_matching_columns(columns)` - Filter table to only keep specified columns
|
|
97
|
+
- `table` - Access the raw Cucumber-compatible table array
|
|
98
|
+
|
|
99
|
+
### Vertical Tables
|
|
88
100
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
* `rake release`
|
|
101
|
+
- `new` - Create a new empty vertical table
|
|
102
|
+
- `[key] = value` - Add a key-value pair to the table
|
|
103
|
+
- `empty?` - Check if the table has no rows
|
|
104
|
+
- `key?(header)` - Check if a header exists in the table
|
|
105
|
+
- `to_h` - Convert the table to a Ruby hash
|
|
106
|
+
- `table` - Access the raw Cucumber-compatible table array
|
data/Rakefile
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler"
|
|
4
|
+
require "bundler/gem_tasks"
|
|
5
|
+
require "cucumber"
|
|
6
|
+
require "cucumber/rake/task"
|
|
7
|
+
|
|
8
|
+
# Files to lint and format
|
|
9
|
+
RUBY_FILES = "lib/*.rb lib/**/*.rb mortadella.gemspec Rakefile"
|
|
5
10
|
|
|
6
11
|
Cucumber::Rake::Task.new :features
|
|
7
|
-
task default:
|
|
12
|
+
task default: [:lint, :features]
|
|
13
|
+
|
|
14
|
+
desc "Fix all auto-fixable issues"
|
|
15
|
+
task "fix" do
|
|
16
|
+
sh "bundle exec rubocop -A #{RUBY_FILES}"
|
|
17
|
+
sh "dprint fmt"
|
|
18
|
+
end
|
|
8
19
|
|
|
9
|
-
desc
|
|
10
|
-
task
|
|
11
|
-
sh
|
|
20
|
+
desc "Run linters"
|
|
21
|
+
task "lint" do
|
|
22
|
+
sh "bundle exec rubocop #{RUBY_FILES}"
|
|
23
|
+
sh "dprint check"
|
|
12
24
|
end
|
data/cucumber.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
default: --publish-quiet
|
|
Binary file
|
data/dprint.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"markdown": {
|
|
3
|
+
"textWrap": "always"
|
|
4
|
+
},
|
|
5
|
+
"toml": {},
|
|
6
|
+
"yaml": {},
|
|
7
|
+
"excludes": ["vendor"],
|
|
8
|
+
"plugins": [
|
|
9
|
+
"https://plugins.dprint.dev/markdown-0.20.0.wasm",
|
|
10
|
+
"https://plugins.dprint.dev/toml-0.7.0.wasm",
|
|
11
|
+
"https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.1.wasm"
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
Feature: Creating mock data tables
|
|
2
2
|
|
|
3
|
-
As a Cucumber user
|
|
4
|
-
I want to programmatically create horizontal mock data tables from application data
|
|
5
|
-
So that I can use Cucumber's built-in table diffing to verify my application data ergonomically.
|
|
6
|
-
|
|
7
|
-
|
|
8
3
|
Scenario: Creating a simple data table
|
|
9
4
|
Given I create a horizontal Mortadella instance: "m = Mortadella::Horizontal.new headers: ['DAY', 'ACTIVITY']"
|
|
10
5
|
And I add a data row: "m << ['Monday', 'mowing']"
|
|
11
6
|
And I add another data row: "m << ['Tuesday', 'tutoring']"
|
|
12
|
-
And I add another data row: "m << ['Wednesday', 'welcoming']"
|
|
13
7
|
When I request the instance data table "m.table"
|
|
14
8
|
Then Mortadella returns an object that matches this Cucumber table
|
|
15
|
-
| DAY
|
|
16
|
-
| Monday
|
|
17
|
-
| Tuesday
|
|
18
|
-
| Wednesday | welcoming |
|
|
19
|
-
|
|
9
|
+
| DAY | ACTIVITY |
|
|
10
|
+
| Monday | mowing |
|
|
11
|
+
| Tuesday | tutoring |
|
|
@@ -1,28 +1,15 @@
|
|
|
1
1
|
Feature: Drying up repetitive fields
|
|
2
2
|
|
|
3
|
-
As a developer with a lot of repetitive data in my Cucumber tables
|
|
4
|
-
I want that redundant elements are omitted from my table
|
|
5
|
-
So that I can see better how data in my table is grouped and where it changes.
|
|
6
|
-
|
|
7
|
-
|
|
8
3
|
Scenario: drying up repetitive columns
|
|
9
|
-
Given I have a Mortadella instance with a DRY column:
|
|
10
|
-
|
|
11
|
-
And I add
|
|
12
|
-
And I add
|
|
13
|
-
And I add another activity for
|
|
14
|
-
|
|
15
|
-
And I add an activity for Tuesday: "m << ['Tuesday', 'typing']"
|
|
16
|
-
And I add another activity for Tuesday: "m << ['Tuesday', 'tutoring']"
|
|
17
|
-
And I add another activity for Tuesday: "m << ['Tuesday', 'throwing']"
|
|
18
|
-
|
|
19
|
-
When I request the instance data table "m.table"
|
|
4
|
+
Given I have a Mortadella instance with a DRY column: "m = Mortadella::Horizontal.new headers: ['DAY', 'ACTIVITY'], dry: ['DAY']"
|
|
5
|
+
And I add an activity for Monday: "m << ['Monday', 'mowing']"
|
|
6
|
+
And I add another activity for Monday: "m << ['Monday', 'musing']"
|
|
7
|
+
And I add an activity for Tuesday: "m << ['Tuesday', 'typing']"
|
|
8
|
+
And I add another activity for Tuesday: "m << ['Tuesday', 'tutoring']"
|
|
9
|
+
When I request the instance data table "m.table"
|
|
20
10
|
Then Mortadella returns a table with repeated day names cleared out for better readability
|
|
21
|
-
| DAY | ACTIVITY
|
|
22
|
-
| Monday | mowing
|
|
23
|
-
| | musing
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
| | tutoring |
|
|
27
|
-
| | throwing |
|
|
28
|
-
|
|
11
|
+
| DAY | ACTIVITY |
|
|
12
|
+
| Monday | mowing |
|
|
13
|
+
| | musing |
|
|
14
|
+
| Tuesday | typing |
|
|
15
|
+
| | tutoring |
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
Feature: Verifying emptiness
|
|
2
2
|
|
|
3
|
-
As a Cucumber user
|
|
4
|
-
I want a programmatic way to verify emptiness of a Mortadella instance
|
|
5
|
-
So that I can verify the absence of data in comfortable ways.
|
|
6
|
-
|
|
7
|
-
|
|
8
3
|
Scenario: an empty table
|
|
9
|
-
Given I have a Mortadella instance:
|
|
10
|
-
When I ask it whether it is empty:
|
|
4
|
+
Given I have a Mortadella instance: "m = Mortadella::Horizontal.new headers: ['foo']"
|
|
5
|
+
When I ask it whether it is empty: "m.empty?"
|
|
11
6
|
Then it responds with true
|
|
12
7
|
|
|
13
|
-
|
|
14
8
|
Scenario: a non-empty table
|
|
15
|
-
Given I have a Mortadella instance:
|
|
16
|
-
And I add a data row:
|
|
17
|
-
When I ask it whether it is empty:
|
|
9
|
+
Given I have a Mortadella instance: "m = Mortadella::Horizontal.new headers: ['foo']"
|
|
10
|
+
And I add a data row: "m << ['bar']"
|
|
11
|
+
When I ask it whether it is empty: "m.empty?"
|
|
18
12
|
Then it responds with false
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Feature: removing empty rows
|
|
2
|
+
|
|
3
|
+
Scenario: filtering multiple columns
|
|
4
|
+
Given I create a horizontal Mortadella instance: "m = Mortadella::Horizontal.new headers: ['DAY', 'ACTIVITY', 'HIGH-SCORE', 'AVERAGE']"
|
|
5
|
+
And I add a data row: "m << ['Monday', 'mowing', '1.0', '0.5']"
|
|
6
|
+
And I add another data row: "m << ['Tuesday', 'tutoring', '2.0', '1.1']"
|
|
7
|
+
When I filter column names: "m.keep_matching_columns ['DAY', 'HIGH-SCORE']"
|
|
8
|
+
And I request the instance data table "m.table"
|
|
9
|
+
Then Mortadella returns an object that matches this Cucumber table
|
|
10
|
+
| DAY | HIGH-SCORE |
|
|
11
|
+
| Monday | 1.0 |
|
|
12
|
+
| Tuesday | 2.0 |
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
@result = eval "@#{code}"
|
|
3
|
-
end
|
|
4
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
5
2
|
|
|
3
|
+
Given(/^I (?:add|ask|create|filter|have|request) .+? "(.+?)"$/) do |code|
|
|
4
|
+
@result = eval("@#{code}")
|
|
5
|
+
end
|
|
6
6
|
|
|
7
7
|
Then(/^Mortadella returns/) do |table|
|
|
8
|
-
table.diff!
|
|
8
|
+
table.diff!(@result)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
Then(/^it responds with (.+?)$/) do |code|
|
|
13
|
-
@result = eval
|
|
12
|
+
@result = eval("@#{code}")
|
|
14
13
|
end
|
data/features/support/env.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "simplecov"
|
|
4
|
+
SimpleCov.start do
|
|
5
|
+
enable_coverage :branch
|
|
6
|
+
add_filter "/features/"
|
|
4
7
|
end
|
|
5
8
|
|
|
6
|
-
require
|
|
9
|
+
require "bundler/setup"
|
|
7
10
|
Bundler.setup
|
|
8
|
-
require
|
|
11
|
+
require "mortadella"
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
Feature: Creating vertical mock data tables
|
|
2
2
|
|
|
3
|
-
As a Cucumber user
|
|
4
|
-
I want to programmatically create vertical mock data tables from application data
|
|
5
|
-
So that I can use Cucumber's built-in table diffing to verify my application data ergonomically.
|
|
6
|
-
|
|
7
|
-
|
|
8
3
|
Scenario: Creating a simple data table
|
|
9
4
|
Given I create a vertical Mortadella instance: "m = Mortadella::Vertical.new"
|
|
10
|
-
And I add a data row:
|
|
11
|
-
And I add another data row:
|
|
12
|
-
|
|
13
|
-
When I request the instance data table "m.table"
|
|
5
|
+
And I add a data row: "m['NAME'] = 'Mortadella'"
|
|
6
|
+
And I add another data row: "m['TYPE'] = 'Ruby Gem'"
|
|
7
|
+
When I request the instance data table "m.table"
|
|
14
8
|
Then Mortadella returns an object that matches this Cucumber table
|
|
15
|
-
| NAME
|
|
16
|
-
| TYPE
|
|
17
|
-
| AUTHOR | Kevin Goslar |
|
|
18
|
-
|
|
9
|
+
| NAME | Mortadella |
|
|
10
|
+
| TYPE | Ruby Gem |
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
Feature: Verifying emptiness
|
|
2
2
|
|
|
3
|
-
(see ../horizontal_tables/emptiness.feature)
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
Scenario: an empty table
|
|
7
|
-
Given I have a Mortadella instance:
|
|
8
|
-
When I ask it whether it is empty:
|
|
4
|
+
Given I have a Mortadella instance: "m = Mortadella::Vertical.new"
|
|
5
|
+
When I ask it whether it is empty: "m.empty?"
|
|
9
6
|
Then it responds with true
|
|
10
7
|
|
|
11
|
-
|
|
12
8
|
Scenario: a non-empty table
|
|
13
|
-
Given I have a Mortadella instance:
|
|
14
|
-
And I add a data row:
|
|
15
|
-
When I ask it whether it is empty:
|
|
9
|
+
Given I have a Mortadella instance: "m = Mortadella::Vertical.new"
|
|
10
|
+
And I add a data row: "m['NAME'] = 'Mortadella'"
|
|
11
|
+
When I ask it whether it is empty: "m.empty?"
|
|
16
12
|
Then it responds with false
|
data/git-town.toml
ADDED
|
@@ -1,65 +1,97 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
module Mortadella
|
|
4
|
+
# Horizontal makes it easy to build horizontal Cucumber-compatible tables.
|
|
4
5
|
class Horizontal
|
|
5
|
-
|
|
6
|
+
# @return [Array<Array<String>>] The resulting Cucumber-compatible table structure.
|
|
6
7
|
attr_reader :table
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
# @param headers [Array<String>] The column headers for the table.
|
|
10
|
+
# @param dry [Array<String>] Column names for which repeated values can be removed.
|
|
11
|
+
# @return [void]
|
|
12
|
+
def initialize(headers:, dry: [])
|
|
10
13
|
@headers = headers
|
|
11
|
-
|
|
12
14
|
@dry = dry
|
|
13
15
|
|
|
14
|
-
# The resulting Cucumber-compatible table structure
|
|
16
|
+
# The resulting Cucumber-compatible table structure.
|
|
15
17
|
@table = [headers]
|
|
16
18
|
|
|
17
19
|
# The previously added row
|
|
18
20
|
@previous_row = nil
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
#
|
|
23
|
-
|
|
23
|
+
# Adds the given row to the table.
|
|
24
|
+
# @param row [Array<String>] The row data to add.
|
|
25
|
+
# @return [void]
|
|
26
|
+
def <<(row)
|
|
27
|
+
validate_row_length!(row)
|
|
24
28
|
@table << dry_up(row)
|
|
25
29
|
@previous_row = row
|
|
26
30
|
end
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
# Indicates whether the table contains no data rows (only a header row).
|
|
33
|
+
# @return [Boolean]
|
|
29
34
|
def empty?
|
|
30
35
|
@table.size == 1
|
|
31
36
|
end
|
|
32
37
|
|
|
38
|
+
# Filters the table to keep only the specified columns.
|
|
39
|
+
# @param columns [Array<String>] Names of the columns to keep.
|
|
40
|
+
# @return [void]
|
|
41
|
+
def keep_matching_columns(columns)
|
|
42
|
+
column_indices_to_drop(columns).sort.reverse_each do |column_index|
|
|
43
|
+
@table.each do |row|
|
|
44
|
+
row.delete_at column_index
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
33
48
|
|
|
49
|
+
private
|
|
34
50
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def can_dry? column_name
|
|
51
|
+
# Returns whether the column with the given name can be dried up.
|
|
52
|
+
# @param column_name [String]
|
|
53
|
+
# @return [Boolean]
|
|
54
|
+
def can_dry?(column_name)
|
|
40
55
|
@dry.include? column_name
|
|
41
56
|
end
|
|
42
57
|
|
|
58
|
+
# Returns the column indices to drop to make this table have the given columns.
|
|
59
|
+
# @param columns [Array<String>] The column names to keep.
|
|
60
|
+
# @return [Array<Integer>] Indices of columns to drop.
|
|
61
|
+
def column_indices_to_drop(columns)
|
|
62
|
+
result = []
|
|
63
|
+
headers = @table[0]
|
|
64
|
+
headers.each_with_index do |header, i|
|
|
65
|
+
result << i unless columns.include? header
|
|
66
|
+
end
|
|
67
|
+
result
|
|
68
|
+
end
|
|
43
69
|
|
|
44
|
-
# Returns a dried up version of the given row
|
|
45
|
-
# based on the row that came before in the table
|
|
46
|
-
#
|
|
70
|
+
# Returns a dried up version of the given row based on the row that came before.
|
|
47
71
|
# In a dried up row, any values that match the previous row are removed,
|
|
48
|
-
# stopping on the first difference
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
72
|
+
# stopping on the first difference. Only columns marked as "dry" are affected.
|
|
73
|
+
# @param row [Array<String>] The row to dry up.
|
|
74
|
+
# @return [Array<String>] The dried up row.
|
|
75
|
+
def dry_up(row)
|
|
76
|
+
result = row.clone
|
|
77
|
+
return result unless @previous_row
|
|
78
|
+
|
|
79
|
+
result.length.times do |i|
|
|
80
|
+
break unless can_dry?(@headers[i]) && result[i] == @previous_row[i]
|
|
81
|
+
|
|
82
|
+
result[i] = ""
|
|
59
83
|
end
|
|
84
|
+
result
|
|
60
85
|
end
|
|
61
86
|
|
|
87
|
+
# Validates that the row has the correct number of elements.
|
|
88
|
+
# @param row [Array<String>] The row to validate.
|
|
89
|
+
# @return [void]
|
|
90
|
+
# @raise [ArgumentError] If the row length doesn't match the headers length.
|
|
91
|
+
def validate_row_length!(row)
|
|
92
|
+
return if row.length == @headers.length
|
|
62
93
|
|
|
94
|
+
raise ArgumentError, "Row length (#{row.length}) doesn't match headers (#{@headers.length})"
|
|
95
|
+
end
|
|
63
96
|
end
|
|
64
|
-
|
|
65
97
|
end
|
data/lib/mortadella/vertical.rb
CHANGED
|
@@ -1,26 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
module Mortadella
|
|
4
|
+
# Vertical makes it easy to build vertical Cucumber-compatible tables.
|
|
5
|
+
# Vertical tables display data as key-value pairs, with headers in the first column
|
|
6
|
+
# and corresponding values in the second column.
|
|
4
7
|
class Vertical
|
|
5
|
-
|
|
8
|
+
# @return [Array<Array<String>>] The Cucumber-compatible table.
|
|
6
9
|
attr_reader :table
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
# Creates a new empty vertical table.
|
|
12
|
+
# @return [void]
|
|
9
13
|
def initialize
|
|
10
14
|
@table = []
|
|
11
15
|
end
|
|
12
16
|
|
|
17
|
+
# Adds a new row to the table with the given header and value.
|
|
18
|
+
# @param header [String] The header (key) for the row.
|
|
19
|
+
# @param row [String] The data (value) for the given header.
|
|
20
|
+
# @return [void]
|
|
21
|
+
# @raise [ArgumentError] If header or row is nil.
|
|
22
|
+
def []=(header, row)
|
|
23
|
+
raise ArgumentError, "Header cannot be nil" if header.nil?
|
|
24
|
+
raise ArgumentError, "Row value cannot be nil" if row.nil?
|
|
13
25
|
|
|
14
|
-
# Adds the given row to the table
|
|
15
|
-
def []= header, row
|
|
16
26
|
@table << [header, row]
|
|
17
27
|
end
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
# Indicates whether the table contains no rows.
|
|
30
|
+
# @return [Boolean]
|
|
20
31
|
def empty?
|
|
21
32
|
@table.empty?
|
|
22
33
|
end
|
|
23
34
|
|
|
35
|
+
# Converts the table to a hash.
|
|
36
|
+
# @return [Hash<String, String>] Hash representation of the table.
|
|
37
|
+
def to_h
|
|
38
|
+
@table.to_h
|
|
39
|
+
end
|
|
24
40
|
end
|
|
25
|
-
|
|
26
41
|
end
|
data/lib/mortadella.rb
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
require 'mortadella/vertical'
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
3
|
+
require "mortadella/horizontal"
|
|
4
|
+
require "mortadella/vertical"
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
# Mortadella makes it easy to programmatically build data tables for Cucumber testing.
|
|
7
|
+
#
|
|
8
|
+
# This module provides two main classes:
|
|
9
|
+
# - {Horizontal}: Build horizontal tables with column headers and data rows
|
|
10
|
+
# - {Vertical}: Build vertical tables with key-value pairs
|
|
11
|
+
#
|
|
12
|
+
# @example Using Horizontal tables
|
|
13
|
+
# table = Mortadella::Horizontal.new(headers: ['NAME', 'AGE'])
|
|
14
|
+
# table << ['Alice', '30']
|
|
15
|
+
# table << ['Bob', '25']
|
|
16
|
+
#
|
|
17
|
+
# @example Using Vertical tables
|
|
18
|
+
# table = Mortadella::Vertical.new
|
|
19
|
+
# table['NAME'] = 'Alice'
|
|
20
|
+
# table['AGE'] = '30'
|
|
6
21
|
module Mortadella
|
|
7
|
-
|
|
8
22
|
end
|
data/mortadella.gemspec
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
5
|
|
|
5
6
|
Gem::Specification.new do |s|
|
|
6
|
-
s.name =
|
|
7
|
-
s.version =
|
|
8
|
-
s.authors = [
|
|
9
|
-
s.email = [
|
|
10
|
-
s.summary =
|
|
11
|
-
s.description =
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
s.name = "mortadella"
|
|
8
|
+
s.version = "1.2.0"
|
|
9
|
+
s.authors = ["Kevin Goslar"]
|
|
10
|
+
s.email = ["kevin.goslar@gmail.com"]
|
|
11
|
+
s.summary = "Build Cucumber-compatible data tables programmatically"
|
|
12
|
+
s.description = "Mortadella makes it easy to programmatically build data tables for " \
|
|
13
|
+
"Cucumber testing. Supports both horizontal (row-based) and vertical " \
|
|
14
|
+
"(key-value) table formats with powerful features like column filtering " \
|
|
15
|
+
"and field deduplication."
|
|
16
|
+
s.homepage = "https://github.com/kevgo/mortadella-ruby"
|
|
17
|
+
s.license = "MIT"
|
|
14
18
|
|
|
15
19
|
s.files = `git ls-files -z`.split("\x0")
|
|
16
|
-
s.
|
|
17
|
-
s.
|
|
20
|
+
s.require_paths = ["lib"]
|
|
21
|
+
s.required_ruby_version = ">= 2.7"
|
|
18
22
|
|
|
19
|
-
s.
|
|
20
|
-
s.
|
|
21
|
-
s.
|
|
22
|
-
s.
|
|
23
|
-
s.
|
|
24
|
-
s.add_development_dependency 'rspec'
|
|
23
|
+
s.metadata["rubygems_mfa_required"] = "true"
|
|
24
|
+
s.metadata["homepage_uri"] = s.homepage
|
|
25
|
+
s.metadata["source_code_uri"] = "https://github.com/kevgo/mortadella-ruby"
|
|
26
|
+
s.metadata["changelog_uri"] = "https://github.com/kevgo/mortadella-ruby/blob/main/CHANGELOG.md"
|
|
27
|
+
s.metadata["bug_tracker_uri"] = "https://github.com/kevgo/mortadella-ruby/issues"
|
|
25
28
|
end
|
metadata
CHANGED
|
@@ -1,100 +1,17 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mortadella
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kevin Goslar
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
-
dependencies:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
requirements:
|
|
17
|
-
- - ">="
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
20
|
-
type: :development
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - ">="
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: coveralls
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: cucumber
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ">="
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: rake
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - ">="
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - ">="
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: rubocop
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: rspec
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - ">="
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '0'
|
|
90
|
-
type: :development
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - ">="
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: '0'
|
|
97
|
-
description: A tool to create Ruby table object to be used for Cucumber comparisons
|
|
10
|
+
date: 2025-11-04 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Mortadella makes it easy to programmatically build data tables for Cucumber
|
|
13
|
+
testing. Supports both horizontal (row-based) and vertical (key-value) table formats
|
|
14
|
+
with powerful features like column filtering and field deduplication.
|
|
98
15
|
email:
|
|
99
16
|
- kevin.goslar@gmail.com
|
|
100
17
|
executables: []
|
|
@@ -102,31 +19,41 @@ extensions: []
|
|
|
102
19
|
extra_rdoc_files: []
|
|
103
20
|
files:
|
|
104
21
|
- ".coveralls.yml"
|
|
22
|
+
- ".github/workflows/ruby.yml"
|
|
105
23
|
- ".gitignore"
|
|
106
24
|
- ".rubocop.yml"
|
|
107
|
-
-
|
|
25
|
+
- CHANGELOG.md
|
|
26
|
+
- DEVELOPMENT.md
|
|
108
27
|
- Gemfile
|
|
109
28
|
- Gemfile.lock
|
|
110
29
|
- LICENSE.txt
|
|
111
30
|
- README.md
|
|
112
31
|
- Rakefile
|
|
113
|
-
-
|
|
32
|
+
- cucumber.yml
|
|
33
|
+
- documentation/ingredients.png
|
|
34
|
+
- dprint.json
|
|
114
35
|
- features/horizontal_tables/basic_usage.feature
|
|
115
36
|
- features/horizontal_tables/drying_up_fields.feature
|
|
116
37
|
- features/horizontal_tables/emptiness.feature
|
|
38
|
+
- features/horizontal_tables/keep_matching_columns.feature
|
|
117
39
|
- features/step_definitions/steps.rb
|
|
118
40
|
- features/support/env.rb
|
|
119
41
|
- features/vertical_tables/basic_usage.feature
|
|
120
42
|
- features/vertical_tables/emptiness.feature
|
|
43
|
+
- git-town.toml
|
|
121
44
|
- lib/mortadella.rb
|
|
122
45
|
- lib/mortadella/horizontal.rb
|
|
123
46
|
- lib/mortadella/vertical.rb
|
|
124
47
|
- mortadella.gemspec
|
|
125
|
-
homepage: https://github.com/
|
|
48
|
+
homepage: https://github.com/kevgo/mortadella-ruby
|
|
126
49
|
licenses:
|
|
127
50
|
- MIT
|
|
128
|
-
metadata:
|
|
129
|
-
|
|
51
|
+
metadata:
|
|
52
|
+
rubygems_mfa_required: 'true'
|
|
53
|
+
homepage_uri: https://github.com/kevgo/mortadella-ruby
|
|
54
|
+
source_code_uri: https://github.com/kevgo/mortadella-ruby
|
|
55
|
+
changelog_uri: https://github.com/kevgo/mortadella-ruby/blob/main/CHANGELOG.md
|
|
56
|
+
bug_tracker_uri: https://github.com/kevgo/mortadella-ruby/issues
|
|
130
57
|
rdoc_options: []
|
|
131
58
|
require_paths:
|
|
132
59
|
- lib
|
|
@@ -134,16 +61,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
134
61
|
requirements:
|
|
135
62
|
- - ">="
|
|
136
63
|
- !ruby/object:Gem::Version
|
|
137
|
-
version: '
|
|
64
|
+
version: '2.7'
|
|
138
65
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
66
|
requirements:
|
|
140
67
|
- - ">="
|
|
141
68
|
- !ruby/object:Gem::Version
|
|
142
69
|
version: '0'
|
|
143
70
|
requirements: []
|
|
144
|
-
|
|
145
|
-
rubygems_version: 2.4.5.1
|
|
146
|
-
signing_key:
|
|
71
|
+
rubygems_version: 3.6.2
|
|
147
72
|
specification_version: 4
|
|
148
|
-
summary:
|
|
73
|
+
summary: Build Cucumber-compatible data tables programmatically
|
|
149
74
|
test_files: []
|
data/.ruby-version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.2.3
|
data/circle.yml
DELETED