lhs 25.0.0 → 25.1.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/workflows/rubocop.yml +27 -0
- data/.github/workflows/test-active-support-5.yml +27 -0
- data/.github/workflows/test.yml +27 -0
- data/.ruby-version +1 -1
- data/README.md +36 -0
- data/lib/lhs.rb +2 -0
- data/lib/lhs/collection.rb +1 -1
- data/lib/lhs/concerns/autoload_records.rb +4 -2
- data/lib/lhs/concerns/collection/internal_collection.rb +2 -2
- data/lib/lhs/concerns/data/extend.rb +18 -14
- data/lib/lhs/concerns/record/pagination.rb +2 -0
- data/lib/lhs/concerns/record/request.rb +33 -4
- data/lib/lhs/pagination/total_pages.rb +9 -0
- data/lib/lhs/version.rb +1 -1
- data/spec/dummy/app/models/concerns/dummy_customer/some_concern.rb +9 -0
- data/spec/dummy/app/models/dummy_customer.rb +1 -0
- data/spec/pagination/total_pages_spec.rb +52 -0
- data/spec/record/compact_spec.rb +5 -0
- data/spec/record/includes_after_expansion_spec.rb +72 -0
- data/spec/record/includes_missing_spec.rb +59 -0
- metadata +18 -19
- data/Gemfile.activesupport4 +0 -5
- data/cider-ci.yml +0 -6
- data/cider-ci/bin/bundle +0 -51
- data/cider-ci/bin/ruby_install +0 -8
- data/cider-ci/bin/ruby_version +0 -25
- data/cider-ci/jobs/rspec-activesupport-4.yml +0 -27
- data/cider-ci/jobs/rspec-activesupport-5.yml +0 -26
- data/cider-ci/jobs/rspec-activesupport-latest.yml +0 -24
- data/cider-ci/jobs/rubocop.yml +0 -18
- data/cider-ci/task_components/bundle.yml +0 -22
- data/cider-ci/task_components/rspec.yml +0 -37
- data/cider-ci/task_components/rubocop.yml +0 -29
- data/cider-ci/task_components/ruby.yml +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92e9ccdfc62407ecb0d4ba6b6ce18b28628ecaad229586f589eb7167fe8ff0de
|
4
|
+
data.tar.gz: 26924759db03d133fbfc8dee9be190e8238fa0fc3036f7b79b13636e881f785e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4186ce186f51e95872532c943c93a402b1d23160d35b123f2fa4c01a1e589ffc863b5f6345c8071c606545539e91e789d75bed7efefcef0546677fe852a56d3d
|
7
|
+
data.tar.gz: b31b7ab8443d71a735397127f389d8dda1f9add35fa318e92ba0172f65172d21928181120a56c953227d0051778646745c8c510c04967e17ba0c24ddd60723ea
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: Rubocop
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
rubocop:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
|
9
|
+
steps:
|
10
|
+
- uses: actions/checkout@v2
|
11
|
+
- uses: actions/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 2.7.2
|
14
|
+
- name: Cache Ruby Gems
|
15
|
+
uses: actions/cache@v2
|
16
|
+
with:
|
17
|
+
path: /.tmp/vendor/bundle
|
18
|
+
key: ${{ runner.os }}-gems-latest-${{ hashFiles('**/Gemfile.lock') }}
|
19
|
+
restore-keys: |
|
20
|
+
${{ runner.os }}-gems-latest-
|
21
|
+
- name: Bundle Install
|
22
|
+
run: |
|
23
|
+
bundle config path /.tmp/vendor/bundle
|
24
|
+
bundle install --jobs 4 --retry 3
|
25
|
+
- name: Run Rubocop
|
26
|
+
run: |
|
27
|
+
bundle exec rubocop
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: Test ActiveSupport v5
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
rspec:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
|
9
|
+
steps:
|
10
|
+
- uses: actions/checkout@v2
|
11
|
+
- uses: actions/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 2.7.2
|
14
|
+
- name: Cache Ruby Gems
|
15
|
+
uses: actions/cache@v2
|
16
|
+
with:
|
17
|
+
path: /.tmp/vendor/bundle
|
18
|
+
key: ${{ runner.os }}-gems-v5-${{ hashFiles('**/Gemfile.lock') }}
|
19
|
+
restore-keys: |
|
20
|
+
${{ runner.os }}-gems-v5-
|
21
|
+
- name: Bundle Install ActiveSupport v5
|
22
|
+
run: |
|
23
|
+
bundle config path /.tmp/vendor/bundle
|
24
|
+
BUNDLE_GEMFILE=Gemfile.activesupport5 bundle install --jobs 4 --retry 3
|
25
|
+
- name: Run Tests
|
26
|
+
run: |
|
27
|
+
BUNDLE_GEMFILE=Gemfile.activesupport5 bundle exec rspec
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
rspec:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
|
9
|
+
steps:
|
10
|
+
- uses: actions/checkout@v2
|
11
|
+
- uses: actions/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 2.7.2
|
14
|
+
- name: Cache Ruby Gems
|
15
|
+
uses: actions/cache@v2
|
16
|
+
with:
|
17
|
+
path: /.tmp/vendor/bundle
|
18
|
+
key: ${{ runner.os }}-gems-latest-${{ hashFiles('**/Gemfile.lock') }}
|
19
|
+
restore-keys: |
|
20
|
+
${{ runner.os }}-gems-latest-
|
21
|
+
- name: Bundle Install
|
22
|
+
run: |
|
23
|
+
bundle config path /.tmp/vendor/bundle
|
24
|
+
bundle install --jobs 4 --retry 3
|
25
|
+
- name: Run Tests
|
26
|
+
run: |
|
27
|
+
bundle exec rspec
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.7.2
|
data/README.md
CHANGED
@@ -80,6 +80,7 @@ record.review # "Lunch was great
|
|
80
80
|
* [Pagination strategy](#pagination-strategy)
|
81
81
|
* [Pagination strategy: offset (default)](#pagination-strategy-offset-default)
|
82
82
|
* [Pagination strategy: page](#pagination-strategy-page)
|
83
|
+
* [Pagination strategy: total_pages](#pagination-strategy-total-pages)
|
83
84
|
* [Pagination strategy: start](#pagination-strategy-start)
|
84
85
|
* [Pagination strategy: link](#pagination-strategy-link)
|
85
86
|
* [Pagination keys](#pagination-keys)
|
@@ -1253,6 +1254,41 @@ In parallel:
|
|
1253
1254
|
GET https://service.example.com/records?limit=100&page=3
|
1254
1255
|
```
|
1255
1256
|
|
1257
|
+
##### Pagination strategy: total_pages
|
1258
|
+
|
1259
|
+
The `total_pages` strategy is based on the `page` strategy with the only difference
|
1260
|
+
that the responding api provides `total_pages` over `total_items`.
|
1261
|
+
|
1262
|
+
```ruby
|
1263
|
+
# app/models/transaction.rb
|
1264
|
+
|
1265
|
+
class Transaction < LHS::Record
|
1266
|
+
configuration pagination_strategy: 'total_pages', pagination_key: 'page', total_key: 'total_pages'
|
1267
|
+
|
1268
|
+
endpoint '{+service}/transactions'
|
1269
|
+
end
|
1270
|
+
```
|
1271
|
+
|
1272
|
+
```ruby
|
1273
|
+
# app/controllers/some_controller.rb
|
1274
|
+
|
1275
|
+
Record.all
|
1276
|
+
|
1277
|
+
```
|
1278
|
+
```
|
1279
|
+
GET https://service.example.com/transactions?limit=100
|
1280
|
+
{
|
1281
|
+
items: [{...}, ...],
|
1282
|
+
total_pages: 3,
|
1283
|
+
limit: 100,
|
1284
|
+
page: 1
|
1285
|
+
}
|
1286
|
+
In parallel:
|
1287
|
+
GET https://service.example.com/records?limit=100&page=2
|
1288
|
+
GET https://service.example.com/records?limit=100&page=3
|
1289
|
+
```
|
1290
|
+
|
1291
|
+
|
1256
1292
|
##### Pagination strategy: start
|
1257
1293
|
|
1258
1294
|
In comparison to the `offset` strategy, the `start` strategy indicates with which item the current page starts.
|
data/lib/lhs.rb
CHANGED
data/lib/lhs/collection.rb
CHANGED
@@ -14,7 +14,7 @@ class LHS::Collection < LHS::Proxy
|
|
14
14
|
|
15
15
|
METHOD_NAMES_EXLCUDED_FROM_WRAPPING = %w(to_a to_ary map).freeze
|
16
16
|
|
17
|
-
delegate :select, :length, :size, to: :_collection
|
17
|
+
delegate :select, :length, :size, :insert, to: :_collection
|
18
18
|
delegate :_record, :_raw, to: :_data
|
19
19
|
delegate :limit, :count, :total, :offset, :current_page, :start,
|
20
20
|
:next?, :previous?, to: :_pagination
|
@@ -32,7 +32,7 @@ module AutoloadRecords
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def self.require_direct_inheritance
|
35
|
-
model_files.map do |file|
|
35
|
+
model_files.sort.map do |file|
|
36
36
|
next unless File.read(file).match('LHS::Record')
|
37
37
|
require_dependency file
|
38
38
|
file.split('models/').last.gsub('.rb', '').classify
|
@@ -41,7 +41,9 @@ module AutoloadRecords
|
|
41
41
|
|
42
42
|
def self.require_inheriting_records(parents)
|
43
43
|
model_files.each do |file|
|
44
|
-
|
44
|
+
file_content = File.read(file)
|
45
|
+
next if parents.none? { |parent| file_content.match(/\b#{parent}\b/) }
|
46
|
+
next if file_content.match?('extend ActiveSupport::Concern')
|
45
47
|
require_dependency file
|
46
48
|
end
|
47
49
|
end
|
@@ -14,7 +14,7 @@ class LHS::Collection < LHS::Proxy
|
|
14
14
|
|
15
15
|
attr_accessor :raw
|
16
16
|
delegate :length, :size, :first, :last, :sample, :[], :present?, :blank?, :empty?,
|
17
|
-
:<<, :push, to: :raw
|
17
|
+
:<<, :push, :insert, to: :raw
|
18
18
|
|
19
19
|
def initialize(raw, parent, record)
|
20
20
|
self.raw = raw
|
@@ -39,7 +39,7 @@ class LHS::Collection < LHS::Proxy
|
|
39
39
|
def compact
|
40
40
|
dup.tap do |collection|
|
41
41
|
collection.compact! if collection.raw.present?
|
42
|
-
end
|
42
|
+
end.as_json # do not return an internal collection!
|
43
43
|
end
|
44
44
|
|
45
45
|
def compact!
|
@@ -9,11 +9,11 @@ class LHS::Data
|
|
9
9
|
|
10
10
|
# Extends already fetched data (self) with additionally
|
11
11
|
# fetched data (addition) using the given key
|
12
|
-
def extend!(addition, key)
|
12
|
+
def extend!(addition, key = nil)
|
13
13
|
addition = cast_relation_class_for_extension(addition, key)
|
14
14
|
if collection?
|
15
15
|
extend_collection!(addition, key)
|
16
|
-
elsif self[key]._raw.is_a?
|
16
|
+
elsif _raw.is_a?(Array) || self[key]._raw.is_a?(Array)
|
17
17
|
extend_array!(addition, key)
|
18
18
|
elsif item?
|
19
19
|
extend_item!(addition, key)
|
@@ -22,14 +22,14 @@ class LHS::Data
|
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
-
def cast_relation_class_for_extension(addition, key)
|
26
|
-
return addition if _record.nil? || _record._relations.nil? || _record._relations[key].nil?
|
25
|
+
def cast_relation_class_for_extension(addition, key = nil)
|
26
|
+
return addition if _record.nil? || key.nil? || _record._relations.nil? || _record._relations[key].nil?
|
27
27
|
addition.becomes(_record._relations[key][:record_class_name].constantize, errors: addition.errors, warnings: addition.warnings)
|
28
28
|
end
|
29
29
|
|
30
|
-
def extend_collection!(addition, key)
|
30
|
+
def extend_collection!(addition, key = nil)
|
31
31
|
map do |item|
|
32
|
-
item_raw = item._raw[key]
|
32
|
+
item_raw = key ? item._raw[key] : item._raw
|
33
33
|
item_raw.blank? ? [nil] : item_raw
|
34
34
|
end
|
35
35
|
.flatten
|
@@ -45,25 +45,25 @@ class LHS::Data
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
def extend_array!(addition, key)
|
49
|
-
self[key].zip(addition) do |item, additional_item|
|
48
|
+
def extend_array!(addition, key = nil)
|
49
|
+
(key ? self[key] : self).zip(addition) do |item, additional_item|
|
50
50
|
item._raw.merge!(additional_item._raw) if additional_item.present?
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
def extend_item!(addition, key)
|
54
|
+
def extend_item!(addition, key = nil)
|
55
55
|
return if addition.nil?
|
56
56
|
if addition.collection?
|
57
57
|
extend_item_with_collection!(addition, key)
|
58
58
|
else # simple case merges hash into hash
|
59
|
-
_raw[key.to_sym].merge!(addition._raw)
|
59
|
+
(key ? _raw[key.to_sym] : _raw).merge!(addition._raw)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def extend_item_with_collection!(addition, key)
|
64
|
-
target = self[key]
|
63
|
+
def extend_item_with_collection!(addition, key = nil)
|
64
|
+
target = (key ? self[key] : self)
|
65
65
|
if target._raw.is_a? Array
|
66
|
-
self[key] = addition.map(&:_raw)
|
66
|
+
self[key] = addition.map(&:_raw) if key
|
67
67
|
else # hash with items
|
68
68
|
extend_item_with_hash_containing_items!(target, addition)
|
69
69
|
end
|
@@ -72,7 +72,11 @@ class LHS::Data
|
|
72
72
|
def extend_item_with_hash_containing_items!(target, addition)
|
73
73
|
LHS::Collection.nest(input: target._raw, value: [], record: self) # inits the nested collection
|
74
74
|
if LHS::Collection.access(input: target._raw, record: self).empty?
|
75
|
-
LHS::Collection.nest(
|
75
|
+
LHS::Collection.nest(
|
76
|
+
input: target._raw,
|
77
|
+
value: addition.reject { |item| item.nil? },
|
78
|
+
record: self
|
79
|
+
)
|
76
80
|
else
|
77
81
|
LHS::Collection.access(input: target._raw, record: self).each_with_index do |item, index|
|
78
82
|
item.merge!(addition[index])
|
@@ -29,7 +29,10 @@ class LHS::Record
|
|
29
29
|
if options.is_a?(Hash)
|
30
30
|
options.deep_merge(LHS::OptionBlocks::CurrentOptionBlock.options)
|
31
31
|
elsif options.is_a?(Array)
|
32
|
-
options.map
|
32
|
+
options.map do |option|
|
33
|
+
return LHS::OptionBlocks::CurrentOptionBlock.options unless option
|
34
|
+
option.deep_merge(LHS::OptionBlocks::CurrentOptionBlock.options)
|
35
|
+
end
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
@@ -118,7 +121,7 @@ class LHS::Record
|
|
118
121
|
else
|
119
122
|
options = options_for_data(data, included)
|
120
123
|
options = extend_with_reference(options, reference)
|
121
|
-
addition =
|
124
|
+
addition = load_existing_includes(options, data, sub_includes, reference)
|
122
125
|
data.extend!(addition, included)
|
123
126
|
expand_addition!(data, included, reference) unless expanded_data?(addition)
|
124
127
|
end
|
@@ -277,6 +280,21 @@ class LHS::Record
|
|
277
280
|
end
|
278
281
|
end
|
279
282
|
|
283
|
+
def load_existing_includes(options, data, sub_includes, references)
|
284
|
+
if data.collection? && data.any?(&:blank?)
|
285
|
+
# filter only existing items
|
286
|
+
loaded_includes = load_include(options.compact, data.compact, sub_includes, references)
|
287
|
+
# fill up skipped items before returning
|
288
|
+
data.each_with_index do |item, index|
|
289
|
+
next if item.present?
|
290
|
+
loaded_includes.insert(index, {})
|
291
|
+
end
|
292
|
+
loaded_includes
|
293
|
+
else
|
294
|
+
load_include(options, data, sub_includes, references)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
280
298
|
# Load additional resources that are requested with include
|
281
299
|
def load_include(options, _data, sub_includes, references)
|
282
300
|
record = record_for_options(options) || self
|
@@ -303,11 +321,22 @@ class LHS::Record
|
|
303
321
|
end
|
304
322
|
|
305
323
|
# Continues loading included resources after one complete batch/level has been fetched
|
306
|
-
def continue_including(data,
|
307
|
-
|
324
|
+
def continue_including(data, included, reference)
|
325
|
+
return data if included.blank? || data.blank?
|
326
|
+
expand_data!(data, included, reference) unless expanded_data?(data)
|
327
|
+
handle_includes(included, data, reference)
|
308
328
|
data
|
309
329
|
end
|
310
330
|
|
331
|
+
def expand_data!(data, _included, reference)
|
332
|
+
options = options_for_data(data)
|
333
|
+
options = extend_with_reference(options, reference)
|
334
|
+
record = record_for_options(options) || self
|
335
|
+
options = convert_options_to_endpoints(options) if record_for_options(options)
|
336
|
+
expanded_data = record.request(options)
|
337
|
+
data.extend!(expanded_data)
|
338
|
+
end
|
339
|
+
|
311
340
|
# Loads all included/linked resources,
|
312
341
|
# paginates itself to ensure all records are fetched
|
313
342
|
def load_all_included!(record, options)
|
data/lib/lhs/version.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe LHS::Record do
|
6
|
+
context 'pagination' do
|
7
|
+
|
8
|
+
let(:page_1_json) do
|
9
|
+
{
|
10
|
+
items: [1, 2],
|
11
|
+
total_pages: 3,
|
12
|
+
page: 1,
|
13
|
+
limit: 2
|
14
|
+
}.to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:page_2_json) do
|
18
|
+
{
|
19
|
+
items: [3, 4],
|
20
|
+
total_pages: 3,
|
21
|
+
page: 2,
|
22
|
+
limit: 2
|
23
|
+
}.to_json
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:page_3_json) do
|
27
|
+
{
|
28
|
+
items: [5, 6],
|
29
|
+
total_pages: 3,
|
30
|
+
page: 3,
|
31
|
+
limit: 2
|
32
|
+
}.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
before do
|
36
|
+
class Feedback < LHS::Record
|
37
|
+
configuration pagination_strategy: :total_pages, total_key: :total_pages, pagination_key: :page
|
38
|
+
endpoint 'http://local.ch/v2/feedbacks'
|
39
|
+
end
|
40
|
+
stub_request(:get, 'http://local.ch/v2/feedbacks?limit=100').to_return(body: page_1_json)
|
41
|
+
stub_request(:get, 'http://local.ch/v2/feedbacks?limit=2&page=2').to_return(body: page_2_json)
|
42
|
+
stub_request(:get, 'http://local.ch/v2/feedbacks?limit=2&page=3').to_return(body: page_3_json)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'responds to limit_value' do
|
46
|
+
feedbacks = Feedback.all.fetch
|
47
|
+
expect(feedbacks.length).to eq 6
|
48
|
+
expect(feedbacks.count).to eq 6
|
49
|
+
expect(feedbacks.items.as_json).to eq [1, 2, 3, 4, 5, 6]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/record/compact_spec.rb
CHANGED
@@ -66,6 +66,11 @@ describe LHS::Record do
|
|
66
66
|
end
|
67
67
|
|
68
68
|
context '.compact' do
|
69
|
+
|
70
|
+
it 'does NOT return an internal data type, but the Record class' do
|
71
|
+
expect(places.compact.class).to eq User
|
72
|
+
end
|
73
|
+
|
69
74
|
it 'removes linked resouces which could not get fetched' do
|
70
75
|
expect(places.compact.length).to eq 1
|
71
76
|
expect(places.length).not_to eq 1 # leaves the original intact
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe LHS::Record do
|
6
|
+
context 'includes records after expansion' do
|
7
|
+
|
8
|
+
before do
|
9
|
+
class User < LHS::Record
|
10
|
+
endpoint 'http://users/{id}'
|
11
|
+
end
|
12
|
+
|
13
|
+
class Places < LHS::Record
|
14
|
+
endpoint 'http://users/{id}/places'
|
15
|
+
endpoint 'http://places/{id}'
|
16
|
+
end
|
17
|
+
|
18
|
+
class Contracts < LHS::Record
|
19
|
+
endpoint 'http://places/{place_id}/contracts'
|
20
|
+
end
|
21
|
+
|
22
|
+
stub_request(:get, 'http://users/1')
|
23
|
+
.to_return(
|
24
|
+
body: {
|
25
|
+
places: {
|
26
|
+
href: 'http://users/1/places'
|
27
|
+
}
|
28
|
+
}.to_json
|
29
|
+
)
|
30
|
+
|
31
|
+
stub_request(:get, 'http://users/1/places?limit=100')
|
32
|
+
.to_return(
|
33
|
+
body: {
|
34
|
+
items: [
|
35
|
+
{ href: 'http://places/345' }
|
36
|
+
],
|
37
|
+
total: 1,
|
38
|
+
offset: 0,
|
39
|
+
limit: 10
|
40
|
+
}.to_json
|
41
|
+
)
|
42
|
+
|
43
|
+
stub_request(:get, 'http://places/345')
|
44
|
+
.to_return(
|
45
|
+
body: {
|
46
|
+
contracts: {
|
47
|
+
href: "http://places/345/contracts?offset=0&limit=10"
|
48
|
+
}
|
49
|
+
}.to_json
|
50
|
+
)
|
51
|
+
|
52
|
+
stub_request(:get, 'http://places/345/contracts?offset=0&limit=10')
|
53
|
+
.to_return(
|
54
|
+
body: {
|
55
|
+
items: [
|
56
|
+
{
|
57
|
+
product: { name: 'OPL' }
|
58
|
+
}
|
59
|
+
]
|
60
|
+
}.to_json
|
61
|
+
)
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'includes resources after expanding plain links' do
|
66
|
+
user = User.includes(places: :contracts).find(1)
|
67
|
+
expect(
|
68
|
+
user.places.first.contracts.first.product.name
|
69
|
+
).to eq 'OPL'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe LHS::Record do
|
6
|
+
|
7
|
+
context 'merge request options ' do
|
8
|
+
before do
|
9
|
+
class Record < LHS::Record
|
10
|
+
endpoint 'http://records/{id}'
|
11
|
+
end
|
12
|
+
|
13
|
+
stub_request(:get, 'http://records/1')
|
14
|
+
.to_return(body: {
|
15
|
+
place_attributes: [
|
16
|
+
{ href: 'https://attributes/bar' },
|
17
|
+
{ href: 'https://attributes/restaurant' },
|
18
|
+
{ href: 'https://attributes/cafe' }
|
19
|
+
]
|
20
|
+
}.to_json)
|
21
|
+
|
22
|
+
stub_request(:get, "https://attributes/restaurant?limit=100")
|
23
|
+
.to_return(body: {}.to_json)
|
24
|
+
stub_request(:get, "https://attributes/restaurant")
|
25
|
+
.to_return(body: {}.to_json)
|
26
|
+
stub_request(:get, "https://attributes/bar?limit=100")
|
27
|
+
.to_return(body: {
|
28
|
+
group: {
|
29
|
+
href: 'https://group/general'
|
30
|
+
}
|
31
|
+
}.to_json)
|
32
|
+
stub_request(:get, "https://attributes/cafe?limit=100")
|
33
|
+
.to_return(body: {
|
34
|
+
group: {
|
35
|
+
href: 'https://group/general'
|
36
|
+
}
|
37
|
+
}.to_json)
|
38
|
+
stub_request(:get, "https://group/general?limit=100&status=active")
|
39
|
+
.to_return(body: {
|
40
|
+
name: 'General'
|
41
|
+
}.to_json)
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'missing referenced options due to none existance of include' do
|
45
|
+
|
46
|
+
it 'does not raise when trying to merge options with the options block' do
|
47
|
+
LHS.options(throttle: { break: '80%' }) do
|
48
|
+
record = Record
|
49
|
+
.references(place_attributes: { group: { params: { status: 'active' } } })
|
50
|
+
.includes([{ place_attributes: :group }])
|
51
|
+
.find(1)
|
52
|
+
expect(record.place_attributes[0].group.name).to eq 'General'
|
53
|
+
expect(record.place_attributes[1].group).to eq nil
|
54
|
+
expect(record.place_attributes[2].group.name).to eq 'General'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 25.
|
4
|
+
version: 25.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhs/graphs/contributors
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -241,28 +241,18 @@ extensions: []
|
|
241
241
|
extra_rdoc_files: []
|
242
242
|
files:
|
243
243
|
- ".bundler-version"
|
244
|
+
- ".github/workflows/rubocop.yml"
|
245
|
+
- ".github/workflows/test-active-support-5.yml"
|
246
|
+
- ".github/workflows/test.yml"
|
244
247
|
- ".gitignore"
|
245
248
|
- ".rubocop.localch.yml"
|
246
249
|
- ".rubocop.yml"
|
247
250
|
- ".ruby-version"
|
248
251
|
- Gemfile
|
249
|
-
- Gemfile.activesupport4
|
250
252
|
- Gemfile.activesupport5
|
251
253
|
- LICENSE
|
252
254
|
- README.md
|
253
255
|
- Rakefile
|
254
|
-
- cider-ci.yml
|
255
|
-
- cider-ci/bin/bundle
|
256
|
-
- cider-ci/bin/ruby_install
|
257
|
-
- cider-ci/bin/ruby_version
|
258
|
-
- cider-ci/jobs/rspec-activesupport-4.yml
|
259
|
-
- cider-ci/jobs/rspec-activesupport-5.yml
|
260
|
-
- cider-ci/jobs/rspec-activesupport-latest.yml
|
261
|
-
- cider-ci/jobs/rubocop.yml
|
262
|
-
- cider-ci/task_components/bundle.yml
|
263
|
-
- cider-ci/task_components/rspec.yml
|
264
|
-
- cider-ci/task_components/rubocop.yml
|
265
|
-
- cider-ci/task_components/ruby.yml
|
266
256
|
- docs/accessing-data-in-lhs.png
|
267
257
|
- friday.yml
|
268
258
|
- lhs.gemspec
|
@@ -331,6 +321,7 @@ files:
|
|
331
321
|
- lib/lhs/pagination/offset.rb
|
332
322
|
- lib/lhs/pagination/page.rb
|
333
323
|
- lib/lhs/pagination/start.rb
|
324
|
+
- lib/lhs/pagination/total_pages.rb
|
334
325
|
- lib/lhs/problems/base.rb
|
335
326
|
- lib/lhs/problems/errors.rb
|
336
327
|
- lib/lhs/problems/nested/base.rb
|
@@ -389,6 +380,7 @@ files:
|
|
389
380
|
- spec/dummy/app/mailers/.keep
|
390
381
|
- spec/dummy/app/models/.keep
|
391
382
|
- spec/dummy/app/models/concerns/.keep
|
383
|
+
- spec/dummy/app/models/concerns/dummy_customer/some_concern.rb
|
392
384
|
- spec/dummy/app/models/dummy_customer.rb
|
393
385
|
- spec/dummy/app/models/dummy_record.rb
|
394
386
|
- spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb
|
@@ -465,6 +457,7 @@ files:
|
|
465
457
|
- spec/pagination/link/total_spec.rb
|
466
458
|
- spec/pagination/offset/pages_left_spec.rb
|
467
459
|
- spec/pagination/parameters_spec.rb
|
460
|
+
- spec/pagination/total_pages_spec.rb
|
468
461
|
- spec/proxy/create_sub_resource_spec.rb
|
469
462
|
- spec/proxy/load_spec.rb
|
470
463
|
- spec/proxy/record_identification_spec.rb
|
@@ -504,8 +497,10 @@ files:
|
|
504
497
|
- spec/record/href_for_spec.rb
|
505
498
|
- spec/record/ignore_errors_spec.rb
|
506
499
|
- spec/record/immutable_chains_spec.rb
|
500
|
+
- spec/record/includes_after_expansion_spec.rb
|
507
501
|
- spec/record/includes_expanded_spec.rb
|
508
502
|
- spec/record/includes_first_page_spec.rb
|
503
|
+
- spec/record/includes_missing_spec.rb
|
509
504
|
- spec/record/includes_spec.rb
|
510
505
|
- spec/record/includes_warning_spec.rb
|
511
506
|
- spec/record/item_key_spec.rb
|
@@ -554,7 +549,7 @@ homepage: https://github.com/local-ch/lhs
|
|
554
549
|
licenses:
|
555
550
|
- GPL-3.0
|
556
551
|
metadata: {}
|
557
|
-
post_install_message:
|
552
|
+
post_install_message:
|
558
553
|
rdoc_options: []
|
559
554
|
require_paths:
|
560
555
|
- lib
|
@@ -570,8 +565,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
570
565
|
version: '0'
|
571
566
|
requirements:
|
572
567
|
- Ruby >= 2.3.0
|
573
|
-
rubygems_version: 3.
|
574
|
-
signing_key:
|
568
|
+
rubygems_version: 3.1.4
|
569
|
+
signing_key:
|
575
570
|
specification_version: 4
|
576
571
|
summary: 'REST services accelerator: Rails gem providing an easy, active-record-like
|
577
572
|
interface for http (hypermedia) json services'
|
@@ -619,6 +614,7 @@ test_files:
|
|
619
614
|
- spec/dummy/app/mailers/.keep
|
620
615
|
- spec/dummy/app/models/.keep
|
621
616
|
- spec/dummy/app/models/concerns/.keep
|
617
|
+
- spec/dummy/app/models/concerns/dummy_customer/some_concern.rb
|
622
618
|
- spec/dummy/app/models/dummy_customer.rb
|
623
619
|
- spec/dummy/app/models/dummy_record.rb
|
624
620
|
- spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb
|
@@ -695,6 +691,7 @@ test_files:
|
|
695
691
|
- spec/pagination/link/total_spec.rb
|
696
692
|
- spec/pagination/offset/pages_left_spec.rb
|
697
693
|
- spec/pagination/parameters_spec.rb
|
694
|
+
- spec/pagination/total_pages_spec.rb
|
698
695
|
- spec/proxy/create_sub_resource_spec.rb
|
699
696
|
- spec/proxy/load_spec.rb
|
700
697
|
- spec/proxy/record_identification_spec.rb
|
@@ -734,8 +731,10 @@ test_files:
|
|
734
731
|
- spec/record/href_for_spec.rb
|
735
732
|
- spec/record/ignore_errors_spec.rb
|
736
733
|
- spec/record/immutable_chains_spec.rb
|
734
|
+
- spec/record/includes_after_expansion_spec.rb
|
737
735
|
- spec/record/includes_expanded_spec.rb
|
738
736
|
- spec/record/includes_first_page_spec.rb
|
737
|
+
- spec/record/includes_missing_spec.rb
|
739
738
|
- spec/record/includes_spec.rb
|
740
739
|
- spec/record/includes_warning_spec.rb
|
741
740
|
- spec/record/item_key_spec.rb
|
data/Gemfile.activesupport4
DELETED
data/cider-ci.yml
DELETED
data/cider-ci/bin/bundle
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
set -eux
|
3
|
-
|
4
|
-
export PATH=~/.rubies/$RUBY/bin:$PATH
|
5
|
-
rm -f .bundle/config
|
6
|
-
|
7
|
-
if [ ! -f ~/.rubies/$RUBY/bin/bundle ]; then
|
8
|
-
gem install bundler
|
9
|
-
fi
|
10
|
-
|
11
|
-
# install bundler v. 1.17.3 in order to be able to run the tests with
|
12
|
-
# ACTIVESUPPORT=4 because rails (= 4.2.0) depends on bundler (< 2.0, >= 1.3.0)
|
13
|
-
gem install bundler:1.17.3
|
14
|
-
|
15
|
-
sed "s/^source 'https:\/\/rubygems\.intra\.local\.ch'*/source 'http\:\/\/52.29.7.59:9292'/g" Gemfile > Gemfile.tmp
|
16
|
-
mv Gemfile.tmp Gemfile
|
17
|
-
|
18
|
-
DIGEST=$(git ls-tree HEAD --\
|
19
|
-
cider-ci.yml cider-ci Gemfile.lock \
|
20
|
-
| openssl dgst -sha1 | cut -d ' ' -f 2)
|
21
|
-
|
22
|
-
if [ ! -z ${ACTIVESUPPORT:-} ]; then
|
23
|
-
DIGEST=$(echo "$DIGEST $ACTIVESUPPORT")
|
24
|
-
fi
|
25
|
-
|
26
|
-
DIGEST=$(echo "$DIGEST $PATH" \
|
27
|
-
| openssl dgst -sha1 | cut -d ' ' -f 2)
|
28
|
-
|
29
|
-
echo "DIGEST"
|
30
|
-
echo "${DIGEST}"
|
31
|
-
|
32
|
-
CACHE_SIGNATURE_FILE="/tmp/bundle_cache_signature_${DIGEST}"
|
33
|
-
|
34
|
-
if [ ! -f $CACHE_SIGNATURE_FILE ] ; then
|
35
|
-
if [ ! -z ${ACTIVESUPPORT:-} ]; then
|
36
|
-
if [ ! -z ${BUNDLER:-} ]; then
|
37
|
-
echo "BUNDLE_GEMFILE=Gemfile.activesupport$ACTIVESUPPORT bundle $BUNDLER install"
|
38
|
-
BUNDLE_GEMFILE=Gemfile.activesupport$ACTIVESUPPORT bundle $BUNDLER install
|
39
|
-
else
|
40
|
-
echo "BUNDLE_GEMFILE=Gemfile.activesupport$ACTIVESUPPORT bundle install"
|
41
|
-
BUNDLE_GEMFILE=Gemfile.activesupport$ACTIVESUPPORT bundle install
|
42
|
-
fi
|
43
|
-
else
|
44
|
-
echo "bundle install"
|
45
|
-
bundle $BUNDLER install
|
46
|
-
fi
|
47
|
-
touch $CACHE_SIGNATURE_FILE
|
48
|
-
fi
|
49
|
-
|
50
|
-
echo "bundle install"
|
51
|
-
bundle $BUNDLER install
|
data/cider-ci/bin/ruby_install
DELETED
data/cider-ci/bin/ruby_version
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
set -eux
|
3
|
-
|
4
|
-
if [ -f ./.ruby-version ]; then
|
5
|
-
echo ".ruby-version file found"
|
6
|
-
fi
|
7
|
-
|
8
|
-
if [ ! -f ./.ruby-version ]; then
|
9
|
-
echo ".ruby-version file not found"
|
10
|
-
exit 1
|
11
|
-
fi
|
12
|
-
|
13
|
-
IFS='-' read -ra EXPLODED_RUBY <<< "$RUBY"
|
14
|
-
|
15
|
-
if [ "${#EXPLODED_RUBY[@]}" == "1" ]; then
|
16
|
-
echo 'No engine/version separator "-" found in .ruby-version file.'
|
17
|
-
exit 1
|
18
|
-
fi
|
19
|
-
|
20
|
-
if [ "${#EXPLODED_RUBY[@]}" != "1" ] && [ "${#EXPLODED_RUBY[@]}" != "2" ]; then
|
21
|
-
echo "Unknown format of .ruby-version file"
|
22
|
-
exit 1
|
23
|
-
fi
|
24
|
-
|
25
|
-
echo $RUBY
|
@@ -1,27 +0,0 @@
|
|
1
|
-
rspec-active-support-v4:
|
2
|
-
name: 'rspec with ActiveSupport v4'
|
3
|
-
|
4
|
-
run_when:
|
5
|
-
'some HEAD has been updated':
|
6
|
-
type: branch
|
7
|
-
include_match: ^.*$
|
8
|
-
|
9
|
-
context:
|
10
|
-
|
11
|
-
script_defaults:
|
12
|
-
template_environment_variables: true
|
13
|
-
|
14
|
-
task_defaults:
|
15
|
-
environment_variables:
|
16
|
-
ACTIVESUPPORT: '4'
|
17
|
-
BUNDLER: '_1.17.3_'
|
18
|
-
max_trials: 2
|
19
|
-
dispatch_storm_delay_duration: 1 Seconds
|
20
|
-
include:
|
21
|
-
- cider-ci/task_components/ruby.yml
|
22
|
-
- cider-ci/task_components/bundle.yml
|
23
|
-
- cider-ci/task_components/rspec.yml
|
24
|
-
|
25
|
-
tasks:
|
26
|
-
all-rspec:
|
27
|
-
name: All rspec tests, using ActiveSupport v4
|
@@ -1,26 +0,0 @@
|
|
1
|
-
rspec-active-support-v5:
|
2
|
-
name: 'rspec with ActiveSupport v5'
|
3
|
-
|
4
|
-
run_when:
|
5
|
-
'some HEAD has been updated':
|
6
|
-
type: branch
|
7
|
-
include_match: ^.*$
|
8
|
-
|
9
|
-
context:
|
10
|
-
|
11
|
-
script_defaults:
|
12
|
-
template_environment_variables: true
|
13
|
-
|
14
|
-
task_defaults:
|
15
|
-
environment_variables:
|
16
|
-
ACTIVESUPPORT: '5'
|
17
|
-
max_trials: 2
|
18
|
-
dispatch_storm_delay_duration: 1 Seconds
|
19
|
-
include:
|
20
|
-
- cider-ci/task_components/ruby.yml
|
21
|
-
- cider-ci/task_components/bundle.yml
|
22
|
-
- cider-ci/task_components/rspec.yml
|
23
|
-
|
24
|
-
tasks:
|
25
|
-
all-rspec:
|
26
|
-
name: All rspec tests, using ActiveSupport v5
|
@@ -1,24 +0,0 @@
|
|
1
|
-
rspec-active-support-latest:
|
2
|
-
name: 'rspec with ActiveSupport latest'
|
3
|
-
|
4
|
-
run_when:
|
5
|
-
'some HEAD has been updated':
|
6
|
-
type: branch
|
7
|
-
include_match: ^.*$
|
8
|
-
|
9
|
-
context:
|
10
|
-
|
11
|
-
script_defaults:
|
12
|
-
template_environment_variables: true
|
13
|
-
|
14
|
-
task_defaults:
|
15
|
-
max_trials: 2
|
16
|
-
dispatch_storm_delay_duration: 1 Seconds
|
17
|
-
include:
|
18
|
-
- cider-ci/task_components/ruby.yml
|
19
|
-
- cider-ci/task_components/bundle.yml
|
20
|
-
- cider-ci/task_components/rspec.yml
|
21
|
-
|
22
|
-
tasks:
|
23
|
-
all-rspec:
|
24
|
-
name: All rspec tests, using ActiveSupport latest
|
data/cider-ci/jobs/rubocop.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
rubocop:
|
2
|
-
name: 'Rubocop'
|
3
|
-
|
4
|
-
run_when:
|
5
|
-
'some HEAD has been updated':
|
6
|
-
type: branch
|
7
|
-
include_match: ^.*$
|
8
|
-
|
9
|
-
context:
|
10
|
-
|
11
|
-
tasks:
|
12
|
-
|
13
|
-
rubocop:
|
14
|
-
|
15
|
-
include:
|
16
|
-
- cider-ci/task_components/ruby.yml
|
17
|
-
- cider-ci/task_components/bundle.yml
|
18
|
-
- cider-ci/task_components/rubocop.yml
|
@@ -1,22 +0,0 @@
|
|
1
|
-
traits:
|
2
|
-
ruby-install: true
|
3
|
-
Bash: true
|
4
|
-
|
5
|
-
trial_attachments:
|
6
|
-
gemfile:
|
7
|
-
include_match: Gemfile
|
8
|
-
content_type: text/plain
|
9
|
-
|
10
|
-
environment_variables:
|
11
|
-
BUNDLER:
|
12
|
-
read_and_replace_with: .bundler-version
|
13
|
-
|
14
|
-
scripts:
|
15
|
-
|
16
|
-
bundle:
|
17
|
-
exclusive_executor_resource: ruby-install_{{$RUBY}}
|
18
|
-
timeout: 20 Minutes
|
19
|
-
body: cider-ci/bin/bundle
|
20
|
-
start_when:
|
21
|
-
'ruby installed':
|
22
|
-
script_key: ruby-install
|
@@ -1,37 +0,0 @@
|
|
1
|
-
ports:
|
2
|
-
CAPYBARA_PORT:
|
3
|
-
min: 8000
|
4
|
-
max: 8999
|
5
|
-
PHANTOMJS_PORT:
|
6
|
-
min: 44600
|
7
|
-
max: 44999
|
8
|
-
|
9
|
-
environment_variables:
|
10
|
-
RUBY:
|
11
|
-
read_and_replace_with: .ruby-version
|
12
|
-
BUNDLER:
|
13
|
-
read_and_replace_with: .bundler-version
|
14
|
-
|
15
|
-
scripts:
|
16
|
-
rspec:
|
17
|
-
body: |
|
18
|
-
#!/usr/bin/env bash
|
19
|
-
set -eux
|
20
|
-
mkdir -p tmp/cache
|
21
|
-
export PATH=~/.rubies/$RUBY/bin:$PATH
|
22
|
-
if [ ! -z ${ACTIVESUPPORT:-} ]; then BUNDLE_GEMFILE=Gemfile.activesupport$ACTIVESUPPORT bundle $BUNDLER exec rspec; else bundle exec rspec; fi
|
23
|
-
|
24
|
-
start_when:
|
25
|
-
'bundled':
|
26
|
-
script_key: bundle
|
27
|
-
|
28
|
-
trial_attachments:
|
29
|
-
logs:
|
30
|
-
include_match: log\/.*\.log$
|
31
|
-
content_type: text/plain
|
32
|
-
image-screenshots:
|
33
|
-
include_match: tmp\/capybara\/.*\.png$
|
34
|
-
content_type: image/png
|
35
|
-
html-screenshots:
|
36
|
-
include_match: tmp\/capybara\/.*\.html$
|
37
|
-
content_type: text/html
|
@@ -1,29 +0,0 @@
|
|
1
|
-
trial_attachments:
|
2
|
-
logs:
|
3
|
-
include_match: tmp\/checkstyle.json$
|
4
|
-
content_type: application/json
|
5
|
-
|
6
|
-
tree_attachments:
|
7
|
-
logs:
|
8
|
-
include_match: tmp\/checkstyle.json$
|
9
|
-
content_type: application/json
|
10
|
-
|
11
|
-
environment_variables:
|
12
|
-
RUBY:
|
13
|
-
read_and_replace_with: .ruby-version
|
14
|
-
RESULT_PATH: 'tmp/checkstyle.json'
|
15
|
-
|
16
|
-
max_trials: 1
|
17
|
-
|
18
|
-
scripts:
|
19
|
-
rubocop:
|
20
|
-
start_when:
|
21
|
-
'bundled':
|
22
|
-
script_key: bundle
|
23
|
-
body: |
|
24
|
-
#!/usr/bin/env bash
|
25
|
-
set -eux
|
26
|
-
mkdir -p tmp/cache
|
27
|
-
export PATH=~/.rubies/$RUBY/bin:$PATH
|
28
|
-
bundle exec rubocop --config .rubocop.yml \
|
29
|
-
--format json --out $RESULT_PATH --format progress
|
@@ -1,15 +0,0 @@
|
|
1
|
-
environment_variables:
|
2
|
-
RUBY:
|
3
|
-
read_and_replace_with: .ruby-version
|
4
|
-
|
5
|
-
scripts:
|
6
|
-
ruby-version:
|
7
|
-
body: cider-ci/bin/ruby_version
|
8
|
-
ruby-install:
|
9
|
-
exclusive_executor_resource: ruby-install_{{$RUBY}}
|
10
|
-
timeout: 20 Minutes
|
11
|
-
body: cider-ci/bin/ruby_install
|
12
|
-
start_when:
|
13
|
-
'ruby version checked':
|
14
|
-
script_key: ruby-version
|
15
|
-
|