burgundy 0.6.0 โ 2.0.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 +4 -4
- data/.github/CODEOWNERS +4 -0
- data/.github/FUNDING.yml +4 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
- data/.github/ISSUE_TEMPLATE/config.yml +5 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +38 -0
- data/.github/dependabot.yml +15 -0
- data/.github/workflows/ruby-tests.yml +52 -0
- data/.rubocop.yml +8 -2
- data/CHANGELOG.md +11 -16
- data/README.md +54 -32
- data/Rakefile +4 -1
- data/burgundy.gemspec +2 -2
- data/lib/burgundy/collection.rb +11 -9
- data/lib/burgundy/guard.rb +2 -3
- data/lib/burgundy/item.rb +4 -8
- data/lib/burgundy/version.rb +1 -1
- data/test/dummy/app/controllers/users_controller.rb +16 -0
- data/test/dummy/app/views/layouts/application.html.erb +1 -1
- data/test/dummy/app/views/users/_profile.html.erb +1 -0
- data/test/dummy/app/views/users/index.html.erb +1 -0
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/routes.rb +2 -1
- data/test/integration/burgundy_test.rb +33 -0
- data/test/test_helper.rb +11 -0
- data/test/unit/burgundy_test.rb +23 -19
- metadata +22 -66
- data/.travis.yml +0 -17
- data/test/dummy/app/views/site/contact.html.erb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a521c6e40d1a119eb6c3cc6b9ae0070950b9433a9effec03c943148539e2d32f
|
|
4
|
+
data.tar.gz: 5a3f16227bd62cab1113f468407db65ab84bff8e9c90b41fef92b2012d19f5a2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9b99049de31f71b2e0351998910ced6d78c6433a8c18ba3b870f4a237d92d391a32bb1d17a0ddb322a7c742b8dc066411a7e7be481f979703b2ec55df3b1d73d
|
|
7
|
+
data.tar.gz: 60b25a4ccedc319ad03a8590bd98b0f3f5081ab505cc0bda8e418e1c104739fcd85a1b6ccf611b91429ac546db25106a277db748a0de9f7b1dbc3d4068527a2a
|
data/.github/CODEOWNERS
ADDED
data/.github/FUNDING.yml
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "๐ Bug Report"
|
|
3
|
+
about: Report a reproducible bug or regression.
|
|
4
|
+
title: 'Bug: '
|
|
5
|
+
labels: 'Status: Unconfirmed'
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!--
|
|
10
|
+
- Please provide a clear and concise description of what the bug is.
|
|
11
|
+
- If possible, add an example reproducing your issue.
|
|
12
|
+
- Please test using the latest version of starlight
|
|
13
|
+
to make sure your issue has not already been fixed.
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
## Description
|
|
17
|
+
|
|
18
|
+
[Add bug description here]
|
|
19
|
+
|
|
20
|
+
## How to reproduce
|
|
21
|
+
|
|
22
|
+
[Add steps on how to reproduce this issue]
|
|
23
|
+
|
|
24
|
+
## What do you expect
|
|
25
|
+
|
|
26
|
+
[Describe what do you expect to happen]
|
|
27
|
+
|
|
28
|
+
## What happened instead
|
|
29
|
+
|
|
30
|
+
[Describe the actual results]
|
|
31
|
+
|
|
32
|
+
## Software:
|
|
33
|
+
|
|
34
|
+
- Gem version: [Add gem version here]
|
|
35
|
+
- Ruby version: [Add version here]
|
|
36
|
+
|
|
37
|
+
## Full backtrace
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
[Paste full backtrace here]
|
|
41
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "๐ก Feature request"
|
|
3
|
+
about: Have an idea that may be useful? Make a suggestion!
|
|
4
|
+
title: 'Feature Request: '
|
|
5
|
+
labels: 'Feature request'
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
_A clear and concise description of what the problem is._
|
|
12
|
+
|
|
13
|
+
## Describe the solution
|
|
14
|
+
|
|
15
|
+
_A clear and concise description of what you want to happen._
|
|
16
|
+
|
|
17
|
+
## Alternatives you considered
|
|
18
|
+
|
|
19
|
+
_A clear and concise description of any alternative solutions or features you've considered._
|
|
20
|
+
|
|
21
|
+
## Additional context
|
|
22
|
+
|
|
23
|
+
_Add any other context, screenshots, links, etc about the feature request here._
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
If you're making a doc PR or something tiny where the below is irrelevant,
|
|
3
|
+
delete this template and use a short description, but in your description aim to
|
|
4
|
+
include both what the change is, and why it is being made, with enough context
|
|
5
|
+
for anyone to understand.
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
<details>
|
|
9
|
+
<summary>PR Checklist</summary>
|
|
10
|
+
|
|
11
|
+
### PR Structure
|
|
12
|
+
|
|
13
|
+
- [ ] This PR has reasonably narrow scope (if not, break it down into smaller
|
|
14
|
+
PRs).
|
|
15
|
+
- [ ] This PR avoids mixing refactoring changes with feature changes (split into
|
|
16
|
+
two PRs otherwise).
|
|
17
|
+
- [ ] This PR's title starts is concise and descriptive.
|
|
18
|
+
|
|
19
|
+
### Thoroughness
|
|
20
|
+
|
|
21
|
+
- [ ] This PR adds tests for the most critical parts of the new functionality or
|
|
22
|
+
fixes.
|
|
23
|
+
- [ ] I've updated any docs, `.md` files, etcโฆ affected by this change.
|
|
24
|
+
|
|
25
|
+
</details>
|
|
26
|
+
|
|
27
|
+
### What
|
|
28
|
+
|
|
29
|
+
[TODO: Short statement about what is changing.]
|
|
30
|
+
|
|
31
|
+
### Why
|
|
32
|
+
|
|
33
|
+
[TODO: Why this change is being made. Include any context required to understand
|
|
34
|
+
the why.]
|
|
35
|
+
|
|
36
|
+
### Known limitations
|
|
37
|
+
|
|
38
|
+
[TODO or N/A]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Documentation:
|
|
3
|
+
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
updates:
|
|
7
|
+
- package-ecosystem: "github-actions"
|
|
8
|
+
directory: "/"
|
|
9
|
+
schedule:
|
|
10
|
+
interval: "daily"
|
|
11
|
+
|
|
12
|
+
- package-ecosystem: bundler
|
|
13
|
+
directory: "/"
|
|
14
|
+
schedule:
|
|
15
|
+
interval: "daily"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ruby-tests
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
pull_request_target:
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
inputs: {}
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
name: Tests with Ruby ${{ matrix.ruby }} and ${{ matrix.gemfile }}
|
|
15
|
+
runs-on: "ubuntu-latest"
|
|
16
|
+
if: |
|
|
17
|
+
github.actor == 'dependabot[bot]' && github.event_name == 'pull_request_target' ||
|
|
18
|
+
github.actor != 'dependabot[bot]'
|
|
19
|
+
strategy:
|
|
20
|
+
fail-fast: false
|
|
21
|
+
matrix:
|
|
22
|
+
ruby: ["3.2", "3.3"]
|
|
23
|
+
gemfile:
|
|
24
|
+
- Gemfile
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- uses: actions/cache@v4
|
|
30
|
+
with:
|
|
31
|
+
path: vendor/bundle
|
|
32
|
+
key: >
|
|
33
|
+
${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles(matrix.gemfile) }}
|
|
34
|
+
|
|
35
|
+
- name: Set up Ruby
|
|
36
|
+
uses: ruby/setup-ruby@v1
|
|
37
|
+
with:
|
|
38
|
+
ruby-version: ${{ matrix.ruby }}
|
|
39
|
+
|
|
40
|
+
- name: Install gem dependencies
|
|
41
|
+
env:
|
|
42
|
+
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
|
43
|
+
run: |
|
|
44
|
+
gem install bundler
|
|
45
|
+
bundle config path vendor/bundle
|
|
46
|
+
bundle update --jobs 4 --retry 3
|
|
47
|
+
|
|
48
|
+
- name: Run Tests
|
|
49
|
+
env:
|
|
50
|
+
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
|
51
|
+
run: |
|
|
52
|
+
bundle exec rake
|
data/.rubocop.yml
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
2
|
inherit_gem:
|
|
4
3
|
rubocop-fnando: .rubocop.yml
|
|
5
4
|
|
|
6
5
|
AllCops:
|
|
7
|
-
TargetRubyVersion: 2
|
|
6
|
+
TargetRubyVersion: 3.2
|
|
7
|
+
NewCops: enable
|
|
8
8
|
Exclude:
|
|
9
9
|
- test/dummy/**/*
|
|
10
|
+
- gemfiles/**/*
|
|
11
|
+
- vendor/**/*
|
|
10
12
|
|
|
11
13
|
Metrics/ClassLength:
|
|
12
14
|
Exclude:
|
|
13
15
|
- test/**/*
|
|
16
|
+
|
|
17
|
+
Style/OpenStructUse:
|
|
18
|
+
Exclude:
|
|
19
|
+
- test/**/*
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [2.0.0] - 2024-05-16
|
|
4
|
+
|
|
5
|
+
- Modernize code and require ruby-3.2 or newer.
|
|
6
|
+
- Allow using keyword arguments as the additional parameters.
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2020-02-24
|
|
9
|
+
|
|
10
|
+
- Remove `Burgundy::Item.map`.
|
|
11
|
+
|
|
1
12
|
## [0.6.0] - 2020-02-08
|
|
2
13
|
|
|
3
14
|
- Allow initializing `Burgundy::Item` without passing a delegating object.
|
|
@@ -16,42 +27,26 @@
|
|
|
16
27
|
|
|
17
28
|
## [0.2.0] - 2015-10-14
|
|
18
29
|
|
|
19
|
-
### Added
|
|
20
|
-
|
|
21
30
|
- `Burgundy::Collection` and `Burgundy::Item.wrap` now delegates additional
|
|
22
31
|
arguments to `Burgundy::Item#initialize`.
|
|
23
32
|
|
|
24
33
|
## [0.1.0] - 2015-02-20
|
|
25
34
|
|
|
26
|
-
### Added
|
|
27
|
-
|
|
28
35
|
- Add `Burgundy::Item#attributes`. Now is possible to easily collect attributes
|
|
29
36
|
as a hash.
|
|
30
|
-
|
|
31
|
-
### Changed
|
|
32
|
-
|
|
33
37
|
- Required Ruby version is now 2.1+.
|
|
34
38
|
|
|
35
39
|
## [0.0.4] - 2015-01-29
|
|
36
40
|
|
|
37
|
-
### Added
|
|
38
|
-
|
|
39
41
|
- `Burgundy::Collection` now includes `Enumerable`.
|
|
40
42
|
|
|
41
43
|
## [0.0.3] - 2014-07-05
|
|
42
44
|
|
|
43
|
-
### Changed
|
|
44
|
-
|
|
45
45
|
- `Burgundy::Item.wrap` always return a `Burgundy::Collection` instance.
|
|
46
46
|
|
|
47
47
|
## [0.0.2] - 2014-07-05 [YANKED]
|
|
48
48
|
|
|
49
|
-
### Added
|
|
50
|
-
|
|
51
49
|
- Add `Burgundy::Collection#empty?`.
|
|
52
|
-
|
|
53
|
-
### Changed
|
|
54
|
-
|
|
55
50
|
- `Burgundy::Collection#initialize` doesn't require a wrapping class anymore.
|
|
56
51
|
This makes ActiveRecord collections easier to work.
|
|
57
52
|
|
data/README.md
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
# Burgundy
|
|
2
2
|
|
|
3
|
-
[](https://codeclimate.com/github/fnando/burgundy)
|
|
5
|
-
[](https://codeclimate.com/github/fnando/burgundy/coverage)
|
|
3
|
+
[](https://github.com/fnando/burgundy)
|
|
6
4
|
[](https://rubygems.org/gems/burgundy)
|
|
7
5
|
[](https://rubygems.org/gems/burgundy)
|
|
6
|
+
[](https://tldrlegal.com/license/mit-license)
|
|
8
7
|
|
|
9
8
|
A simple wrapper for objects (think of Burgundy as a decorator/presenter) in
|
|
10
9
|
less than 150 lines.
|
|
@@ -14,7 +13,7 @@ less than 150 lines.
|
|
|
14
13
|
Add this line to your application's Gemfile:
|
|
15
14
|
|
|
16
15
|
```ruby
|
|
17
|
-
gem
|
|
16
|
+
gem "burgundy"
|
|
18
17
|
```
|
|
19
18
|
|
|
20
19
|
And then execute:
|
|
@@ -58,22 +57,29 @@ end
|
|
|
58
57
|
You don't have to expose attributes; everything is delegated to the wrapped
|
|
59
58
|
item.
|
|
60
59
|
|
|
61
|
-
To wrap an entire collection, just use the `Burgundy::
|
|
60
|
+
To wrap an entire collection, just use the `Burgundy::Item.wrap` class.
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
class WorkshopsController < ApplicationController
|
|
64
|
+
def index
|
|
65
|
+
@workshops = WorkshopPresenter.wrap(Workshop.sorted_by_name)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Alternatively, you can also use the `Burgundy::Collection` class.
|
|
62
71
|
|
|
63
72
|
```ruby
|
|
64
73
|
class WorkshopsController < ApplicationController
|
|
65
74
|
def index
|
|
66
75
|
@workshops = Burgundy::Collection.new(
|
|
67
|
-
|
|
68
|
-
|
|
76
|
+
WorkshopPresenter,
|
|
77
|
+
Workshop.sorted_by_name
|
|
69
78
|
)
|
|
70
79
|
end
|
|
71
80
|
end
|
|
72
81
|
```
|
|
73
82
|
|
|
74
|
-
or just call `WorkshopPresenter.wrap(Workshop.sorted_by_name)`. Both ways return
|
|
75
|
-
a `Burgundy::Collection` instance.
|
|
76
|
-
|
|
77
83
|
You may need to provide additional arguments to the item class. On your
|
|
78
84
|
collection, all additional arguments will be delegated to the item classe, like
|
|
79
85
|
the following example:
|
|
@@ -90,6 +96,24 @@ class WorkshopPresenter < Burgundy::Item
|
|
|
90
96
|
end
|
|
91
97
|
```
|
|
92
98
|
|
|
99
|
+
You can also use keyword arguments to pass in additional objects.
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
WorkshopPresenter.wrap(Workshop.all, current_user:)
|
|
103
|
+
Burgundy::Collection.new(Workshop.all, WorkshopPresenter, current_user:)
|
|
104
|
+
|
|
105
|
+
class WorkshopPresenter < Burgundy::Item
|
|
106
|
+
def initialize(workshop, current_user:)
|
|
107
|
+
super(workshop)
|
|
108
|
+
@current_user = current_user
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
> [!NOTE]
|
|
114
|
+
>
|
|
115
|
+
> The target object will always be a positional argument.
|
|
116
|
+
|
|
93
117
|
The query will be performed only when needed, usually on the view (easier to
|
|
94
118
|
cache). The collection is an enumerable object and can be passed directly to the
|
|
95
119
|
`render` method. Each item will be wrapped by the provided class.
|
|
@@ -101,8 +125,8 @@ cache). The collection is an enumerable object and can be passed directly to the
|
|
|
101
125
|
Route URLs may require the default url options. Burgundy try to get them from
|
|
102
126
|
the following objects:
|
|
103
127
|
|
|
104
|
-
|
|
105
|
-
|
|
128
|
+
- `Rails.configuration.action_mailer.default_url_options`
|
|
129
|
+
- `Rails.application.routes.default_url_options`
|
|
106
130
|
|
|
107
131
|
So you can just put this on your environment file
|
|
108
132
|
|
|
@@ -113,7 +137,7 @@ config.action_controller.default_url_options = {
|
|
|
113
137
|
```
|
|
114
138
|
|
|
115
139
|
You can map attributes into a hash; I use this strategy for using presenters on
|
|
116
|
-
API responses (so
|
|
140
|
+
API responses (so you can skip adding yet another dependency to your projects).
|
|
117
141
|
|
|
118
142
|
```ruby
|
|
119
143
|
class UserPresenter < Burgundy::Item
|
|
@@ -143,7 +167,7 @@ If you want to remap an attribute, provide a hash.
|
|
|
143
167
|
|
|
144
168
|
```ruby
|
|
145
169
|
class UserPresenter < Burgundy::Item
|
|
146
|
-
attributes :name, :email, :
|
|
170
|
+
attributes :name, :email, username: :login
|
|
147
171
|
|
|
148
172
|
def profile_url
|
|
149
173
|
routes.profile_url(item.username)
|
|
@@ -168,21 +192,19 @@ Copyright (c) 2013 Nando Vieira
|
|
|
168
192
|
|
|
169
193
|
MIT License
|
|
170
194
|
|
|
171
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
188
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
195
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
196
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
197
|
+
the Software without restriction, including without limitation the rights to
|
|
198
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
199
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
200
|
+
subject to the following conditions:
|
|
201
|
+
|
|
202
|
+
The above copyright notice and this permission notice shall be included in all
|
|
203
|
+
copies or substantial portions of the Software.
|
|
204
|
+
|
|
205
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
206
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
207
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
208
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
209
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
210
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "bundler/gem_tasks"
|
|
4
4
|
require "rake/testtask"
|
|
5
|
+
require "rubocop/rake_task"
|
|
5
6
|
|
|
6
7
|
Rake::TestTask.new(:test) do |t|
|
|
7
8
|
t.libs << "test"
|
|
@@ -9,4 +10,6 @@ Rake::TestTask.new(:test) do |t|
|
|
|
9
10
|
t.warning = false
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
RuboCop::RakeTask.new
|
|
14
|
+
|
|
15
|
+
task default: %i[test rubocop]
|
data/burgundy.gemspec
CHANGED
|
@@ -11,15 +11,15 @@ Gem::Specification.new do |spec|
|
|
|
11
11
|
spec.summary = spec.description
|
|
12
12
|
spec.homepage = "http://github.com/fnando/burgundy"
|
|
13
13
|
spec.license = "MIT"
|
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.2.0")
|
|
15
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
14
16
|
|
|
15
17
|
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
|
16
18
|
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
|
|
17
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
19
|
spec.require_paths = ["lib"]
|
|
19
20
|
|
|
20
21
|
spec.add_development_dependency "bundler"
|
|
21
22
|
spec.add_development_dependency "minitest-utils"
|
|
22
|
-
spec.add_development_dependency "pry-meta"
|
|
23
23
|
spec.add_development_dependency "rails"
|
|
24
24
|
spec.add_development_dependency "rake"
|
|
25
25
|
spec.add_development_dependency "rubocop"
|
data/lib/burgundy/collection.rb
CHANGED
|
@@ -2,26 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
module Burgundy
|
|
4
4
|
class Collection
|
|
5
|
-
def initialize(items, wrapping_class = nil, *args)
|
|
5
|
+
def initialize(items, wrapping_class = nil, *args, **kwargs)
|
|
6
6
|
@items = items
|
|
7
7
|
@wrapping_class = wrapping_class
|
|
8
8
|
@args = args
|
|
9
|
+
@kwargs = kwargs
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
def method_missing(name,
|
|
12
|
-
to_ary.send(name,
|
|
12
|
+
def method_missing(name, *, &) # rubocop:disable Style/MissingRespondToMissing
|
|
13
|
+
to_ary.send(name, *, &)
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
def respond_to?(name, include_all = false)
|
|
16
|
+
def respond_to?(name, include_all = false) # rubocop:disable Style/OptionalBooleanParameter
|
|
16
17
|
to_ary.respond_to?(name, include_all)
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def to_ary
|
|
20
|
-
@to_ary ||=
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
@to_ary ||=
|
|
22
|
+
if @wrapping_class
|
|
23
|
+
@items.map {|item| @wrapping_class.new(item, *@args, **@kwargs) }
|
|
24
|
+
else
|
|
25
|
+
@items.to_a
|
|
26
|
+
end
|
|
25
27
|
end
|
|
26
28
|
alias to_a to_ary
|
|
27
29
|
end
|
data/lib/burgundy/guard.rb
CHANGED
|
@@ -6,15 +6,14 @@ module Burgundy
|
|
|
6
6
|
@item = item
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def method_missing(name, *)
|
|
9
|
+
def method_missing(name, *)
|
|
10
10
|
class_name = @item.class.name || @item.class.inspect
|
|
11
|
-
|
|
12
11
|
error_message = %W[
|
|
13
12
|
#{class_name} was initialized without a delegating object and
|
|
14
13
|
didn't implement #{class_name}##{name}
|
|
15
14
|
].join(" ")
|
|
16
15
|
|
|
17
|
-
raise ArgumentError, "#{error_message}\n#{caller
|
|
16
|
+
raise ArgumentError, "#{error_message}\n#{caller(2..2).first}"
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def respond_to_missing?(*)
|
data/lib/burgundy/item.rb
CHANGED
|
@@ -5,16 +5,12 @@ module Burgundy
|
|
|
5
5
|
attr_reader :item
|
|
6
6
|
|
|
7
7
|
def self.inherited(child)
|
|
8
|
+
super
|
|
8
9
|
child.attributes(attributes)
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
def self.wrap(collection,
|
|
12
|
-
Collection.new(collection, self,
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def self.map(collection)
|
|
16
|
-
warn "Burgundy::Item.map is deprecated; use Burgundy::Item.wrap instead."
|
|
17
|
-
wrap(collection)
|
|
12
|
+
def self.wrap(collection, *, **)
|
|
13
|
+
Collection.new(collection, self, *, **)
|
|
18
14
|
end
|
|
19
15
|
|
|
20
16
|
def self.attributes(*args)
|
|
@@ -29,7 +25,7 @@ module Burgundy
|
|
|
29
25
|
@attributes
|
|
30
26
|
end
|
|
31
27
|
|
|
32
|
-
def initialize(item = nil)
|
|
28
|
+
def initialize(item = nil) # rubocop:disable Lint/MissingSuper
|
|
33
29
|
@item = item || Guard.new(self)
|
|
34
30
|
__setobj__(@item)
|
|
35
31
|
end
|
data/lib/burgundy/version.rb
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class UsersController < ApplicationController
|
|
4
|
+
def index
|
|
5
|
+
presenter = Class.new(Burgundy::Item) do
|
|
6
|
+
def to_partial_path
|
|
7
|
+
"users/profile"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
@users = presenter.wrap([
|
|
12
|
+
OpenStruct.new(name: "John"),
|
|
13
|
+
OpenStruct.new(name: "Mary")
|
|
14
|
+
])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
|
-
<title
|
|
4
|
+
<title>Burgundy</title>
|
|
5
5
|
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
|
|
6
6
|
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
|
|
7
7
|
<%= csrf_meta_tags %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<h1><%= profile.name %></h1>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= render @users, as: :profile %>
|
data/test/dummy/config/routes.rb
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class BurgundyTest < Minitest::Test
|
|
6
|
+
include Rack::Test::Methods
|
|
7
|
+
|
|
8
|
+
def app
|
|
9
|
+
Rails.application
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
test "renders collection with custom partial path" do
|
|
13
|
+
get "/users"
|
|
14
|
+
html = Nokogiri(last_response.body)
|
|
15
|
+
h1s = html.css("h1")
|
|
16
|
+
|
|
17
|
+
assert_equal 2, h1s.size
|
|
18
|
+
assert_equal "John", h1s[0].text
|
|
19
|
+
assert_equal "Mary", h1s[1].text
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test "wrapped object is the same as the unwrapped object" do
|
|
23
|
+
model = Class.new do
|
|
24
|
+
include ActiveModel::Model
|
|
25
|
+
attr_accessor :name
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
presenter = Class.new(Burgundy::Item)
|
|
29
|
+
instance = model.new(name: "John")
|
|
30
|
+
|
|
31
|
+
assert presenter.new(instance).eql?(instance)
|
|
32
|
+
end
|
|
33
|
+
end
|
data/test/test_helper.rb
CHANGED
|
@@ -10,6 +10,7 @@ Bundler.setup
|
|
|
10
10
|
|
|
11
11
|
require "minitest/utils"
|
|
12
12
|
require "minitest/autorun"
|
|
13
|
+
require "ostruct"
|
|
13
14
|
|
|
14
15
|
ENV["RAILS_ENV"] = "test"
|
|
15
16
|
|
|
@@ -26,3 +27,13 @@ class ItemWithAdditionalArgs < Burgundy::Item
|
|
|
26
27
|
@args = args
|
|
27
28
|
end
|
|
28
29
|
end
|
|
30
|
+
|
|
31
|
+
class ItemWithKeywordArgs < Burgundy::Item
|
|
32
|
+
attr_reader :kwargs, :a, :b
|
|
33
|
+
|
|
34
|
+
def initialize(target, a:, b:)
|
|
35
|
+
super(target)
|
|
36
|
+
@a = a
|
|
37
|
+
@b = b
|
|
38
|
+
end
|
|
39
|
+
end
|
data/test/unit/burgundy_test.rb
CHANGED
|
@@ -5,9 +5,11 @@ require "test_helper"
|
|
|
5
5
|
class BurgundyTest < Minitest::Test
|
|
6
6
|
let(:wrapper) { Class.new(Burgundy::Item) }
|
|
7
7
|
let(:wrapper_with_args) { ItemWithAdditionalArgs }
|
|
8
|
+
let(:wrapper_with_kwargs) { ItemWithKeywordArgs }
|
|
8
9
|
|
|
9
10
|
test "delegates everything" do
|
|
10
11
|
item = wrapper.new("hello")
|
|
12
|
+
|
|
11
13
|
assert_equal "HELLO", item.upcase
|
|
12
14
|
end
|
|
13
15
|
|
|
@@ -34,49 +36,49 @@ class BurgundyTest < Minitest::Test
|
|
|
34
36
|
].join(" ")
|
|
35
37
|
|
|
36
38
|
line_reference =
|
|
37
|
-
"#{__FILE__}:
|
|
39
|
+
"#{__FILE__}:31:in `block (2 levels) in <class:BurgundyTest>'"
|
|
38
40
|
|
|
39
41
|
error_message = "#{error_message}\n#{line_reference}"
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
assert_instance_of ArgumentError, error
|
|
42
44
|
assert_equal error_message, error.message
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
test "wraps items" do
|
|
46
48
|
items = wrapper.wrap([1, 2, 3])
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
assert_instance_of Burgundy::Collection, items
|
|
49
51
|
assert_kind_of wrapper, items.first
|
|
50
52
|
assert_equal 1, items.first.to_i
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
test "wraps items with keyword args" do
|
|
56
|
+
items = wrapper_with_kwargs.wrap([1, 2, 3], a: "a", b: "b")
|
|
57
|
+
|
|
58
|
+
assert_instance_of Burgundy::Collection, items
|
|
59
|
+
assert_kind_of wrapper_with_kwargs, items.first
|
|
60
|
+
assert_equal "a", items.first.a
|
|
61
|
+
assert_equal "b", items.first.b
|
|
62
|
+
end
|
|
63
|
+
|
|
53
64
|
test "wraps items with additional arguments" do
|
|
54
65
|
items = wrapper_with_args.wrap([1], 2, 3)
|
|
55
66
|
|
|
56
|
-
|
|
67
|
+
assert_instance_of Burgundy::Collection, items
|
|
57
68
|
assert_kind_of wrapper_with_args, items.first
|
|
58
69
|
assert_equal 1, items.first.item
|
|
59
70
|
assert_equal [2, 3], items.first.args
|
|
60
71
|
end
|
|
61
72
|
|
|
62
|
-
test "deprecates Burgundy::Item.map" do
|
|
63
|
-
message =
|
|
64
|
-
"Burgundy::Item.map is deprecated; use Burgundy::Item.wrap instead."
|
|
65
|
-
|
|
66
|
-
_, err = capture_io do
|
|
67
|
-
wrapper.map([1, 2, 3])
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
assert err.include?(message)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
73
|
test "wraps items in collection" do
|
|
74
74
|
collection = Burgundy::Collection.new([1, 2, 3], wrapper)
|
|
75
|
+
|
|
75
76
|
assert_equal 1, collection.first
|
|
76
77
|
end
|
|
77
78
|
|
|
78
79
|
test "delegates collection calls" do
|
|
79
80
|
collection = Burgundy::Collection.new([1, 2, 3], wrapper)
|
|
81
|
+
|
|
80
82
|
assert_equal 3, collection.size
|
|
81
83
|
end
|
|
82
84
|
|
|
@@ -94,10 +96,12 @@ class BurgundyTest < Minitest::Test
|
|
|
94
96
|
|
|
95
97
|
test "implements #empty?" do
|
|
96
98
|
collection = Burgundy::Collection.new([1, 2, 3])
|
|
97
|
-
|
|
99
|
+
|
|
100
|
+
refute_empty collection
|
|
98
101
|
|
|
99
102
|
collection = Burgundy::Collection.new([])
|
|
100
|
-
|
|
103
|
+
|
|
104
|
+
assert_empty collection
|
|
101
105
|
end
|
|
102
106
|
|
|
103
107
|
test "responds to the routes method" do
|
|
@@ -262,7 +266,7 @@ class BurgundyTest < Minitest::Test
|
|
|
262
266
|
wrapper = Class.new(Burgundy::Item)
|
|
263
267
|
collection = wrapper.wrap([1])
|
|
264
268
|
|
|
265
|
-
|
|
266
|
-
|
|
269
|
+
assert_respond_to collection, :first
|
|
270
|
+
refute_respond_to collection, :missing
|
|
267
271
|
end
|
|
268
272
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: burgundy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nando Vieira
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-05-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -38,20 +38,6 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: pry-meta
|
|
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
41
|
- !ruby/object:Gem::Dependency
|
|
56
42
|
name: rails
|
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -129,9 +115,16 @@ executables: []
|
|
|
129
115
|
extensions: []
|
|
130
116
|
extra_rdoc_files: []
|
|
131
117
|
files:
|
|
118
|
+
- ".github/CODEOWNERS"
|
|
119
|
+
- ".github/FUNDING.yml"
|
|
120
|
+
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
|
121
|
+
- ".github/ISSUE_TEMPLATE/config.yml"
|
|
122
|
+
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
|
123
|
+
- ".github/PULL_REQUEST_TEMPLATE.md"
|
|
124
|
+
- ".github/dependabot.yml"
|
|
125
|
+
- ".github/workflows/ruby-tests.yml"
|
|
132
126
|
- ".gitignore"
|
|
133
127
|
- ".rubocop.yml"
|
|
134
|
-
- ".travis.yml"
|
|
135
128
|
- CHANGELOG.md
|
|
136
129
|
- CODE_OF_CONDUCT.md
|
|
137
130
|
- Gemfile
|
|
@@ -152,12 +145,14 @@ files:
|
|
|
152
145
|
- test/dummy/app/assets/stylesheets/application.css
|
|
153
146
|
- test/dummy/app/controllers/application_controller.rb
|
|
154
147
|
- test/dummy/app/controllers/concerns/.keep
|
|
148
|
+
- test/dummy/app/controllers/users_controller.rb
|
|
155
149
|
- test/dummy/app/helpers/application_helper.rb
|
|
156
150
|
- test/dummy/app/mailers/.keep
|
|
157
151
|
- test/dummy/app/models/.keep
|
|
158
152
|
- test/dummy/app/models/concerns/.keep
|
|
159
153
|
- test/dummy/app/views/layouts/application.html.erb
|
|
160
|
-
- test/dummy/app/views/
|
|
154
|
+
- test/dummy/app/views/users/_profile.html.erb
|
|
155
|
+
- test/dummy/app/views/users/index.html.erb
|
|
161
156
|
- test/dummy/bin/bundle
|
|
162
157
|
- test/dummy/bin/rails
|
|
163
158
|
- test/dummy/bin/rake
|
|
@@ -184,13 +179,15 @@ files:
|
|
|
184
179
|
- test/dummy/public/422.html
|
|
185
180
|
- test/dummy/public/500.html
|
|
186
181
|
- test/dummy/public/favicon.ico
|
|
182
|
+
- test/integration/burgundy_test.rb
|
|
187
183
|
- test/test_helper.rb
|
|
188
184
|
- test/unit/burgundy_test.rb
|
|
189
185
|
homepage: http://github.com/fnando/burgundy
|
|
190
186
|
licenses:
|
|
191
187
|
- MIT
|
|
192
|
-
metadata:
|
|
193
|
-
|
|
188
|
+
metadata:
|
|
189
|
+
rubygems_mfa_required: 'true'
|
|
190
|
+
post_install_message:
|
|
194
191
|
rdoc_options: []
|
|
195
192
|
require_paths:
|
|
196
193
|
- lib
|
|
@@ -198,56 +195,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
198
195
|
requirements:
|
|
199
196
|
- - ">="
|
|
200
197
|
- !ruby/object:Gem::Version
|
|
201
|
-
version:
|
|
198
|
+
version: 3.2.0
|
|
202
199
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
203
200
|
requirements:
|
|
204
201
|
- - ">="
|
|
205
202
|
- !ruby/object:Gem::Version
|
|
206
203
|
version: '0'
|
|
207
204
|
requirements: []
|
|
208
|
-
rubygems_version: 3.
|
|
209
|
-
signing_key:
|
|
205
|
+
rubygems_version: 3.5.9
|
|
206
|
+
signing_key:
|
|
210
207
|
specification_version: 4
|
|
211
208
|
summary: A simple wrapper for objects in less than 100 lines.
|
|
212
|
-
test_files:
|
|
213
|
-
- test/dummy/README.rdoc
|
|
214
|
-
- test/dummy/Rakefile
|
|
215
|
-
- test/dummy/app/assets/images/.keep
|
|
216
|
-
- test/dummy/app/assets/javascripts/application.js
|
|
217
|
-
- test/dummy/app/assets/stylesheets/application.css
|
|
218
|
-
- test/dummy/app/controllers/application_controller.rb
|
|
219
|
-
- test/dummy/app/controllers/concerns/.keep
|
|
220
|
-
- test/dummy/app/helpers/application_helper.rb
|
|
221
|
-
- test/dummy/app/mailers/.keep
|
|
222
|
-
- test/dummy/app/models/.keep
|
|
223
|
-
- test/dummy/app/models/concerns/.keep
|
|
224
|
-
- test/dummy/app/views/layouts/application.html.erb
|
|
225
|
-
- test/dummy/app/views/site/contact.html.erb
|
|
226
|
-
- test/dummy/bin/bundle
|
|
227
|
-
- test/dummy/bin/rails
|
|
228
|
-
- test/dummy/bin/rake
|
|
229
|
-
- test/dummy/config.ru
|
|
230
|
-
- test/dummy/config/application.rb
|
|
231
|
-
- test/dummy/config/boot.rb
|
|
232
|
-
- test/dummy/config/database.yml
|
|
233
|
-
- test/dummy/config/environment.rb
|
|
234
|
-
- test/dummy/config/environments/development.rb
|
|
235
|
-
- test/dummy/config/environments/production.rb
|
|
236
|
-
- test/dummy/config/environments/test.rb
|
|
237
|
-
- test/dummy/config/initializers/backtrace_silencers.rb
|
|
238
|
-
- test/dummy/config/initializers/filter_parameter_logging.rb
|
|
239
|
-
- test/dummy/config/initializers/inflections.rb
|
|
240
|
-
- test/dummy/config/initializers/mime_types.rb
|
|
241
|
-
- test/dummy/config/initializers/secret_token.rb
|
|
242
|
-
- test/dummy/config/initializers/session_store.rb
|
|
243
|
-
- test/dummy/config/initializers/wrap_parameters.rb
|
|
244
|
-
- test/dummy/config/locales/en.yml
|
|
245
|
-
- test/dummy/config/routes.rb
|
|
246
|
-
- test/dummy/lib/assets/.keep
|
|
247
|
-
- test/dummy/log/.keep
|
|
248
|
-
- test/dummy/public/404.html
|
|
249
|
-
- test/dummy/public/422.html
|
|
250
|
-
- test/dummy/public/500.html
|
|
251
|
-
- test/dummy/public/favicon.ico
|
|
252
|
-
- test/test_helper.rb
|
|
253
|
-
- test/unit/burgundy_test.rb
|
|
209
|
+
test_files: []
|
data/.travis.yml
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
language: ruby
|
|
3
|
-
sudo: false
|
|
4
|
-
cache: bundler
|
|
5
|
-
notifications:
|
|
6
|
-
email: false
|
|
7
|
-
rvm:
|
|
8
|
-
- 2.5.2
|
|
9
|
-
before_script:
|
|
10
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
|
11
|
-
- chmod +x ./cc-test-reporter
|
|
12
|
-
- "./cc-test-reporter before-build"
|
|
13
|
-
after_script:
|
|
14
|
-
- "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
|
|
15
|
-
env:
|
|
16
|
-
global:
|
|
17
|
-
secure: LIU2voUl12O5yOXGTwOFOJgdv49YOpFN4FyH3Eqvc48tvy3cRypMuqvFiG/KL4jQvE2IydZZmG+DtsgTsi6kOe5cYlxeU2fTiK9dflNqBIV7+CfwXqguUAcwJLW1dt6Gtmis2VuOffJDBqpojTpFDrUosDdISc1gkOXh4+8yHQA=
|
|
File without changes
|