lhs 25.0.1 → 25.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rubocop.yml +16 -0
  3. data/.github/workflows/test-active-support-5.yml +20 -0
  4. data/.github/workflows/test.yml +16 -0
  5. data/.ruby-version +1 -1
  6. data/lib/lhs/collection.rb +1 -1
  7. data/lib/lhs/concerns/autoload_records.rb +4 -2
  8. data/lib/lhs/concerns/collection/internal_collection.rb +2 -2
  9. data/lib/lhs/concerns/data/extend.rb +18 -14
  10. data/lib/lhs/concerns/item/save.rb +1 -1
  11. data/lib/lhs/concerns/record/request.rb +33 -4
  12. data/lib/lhs/version.rb +1 -1
  13. data/spec/dummy/app/controllers/request_cycle_cache_controller.rb +4 -4
  14. data/spec/dummy/app/models/concerns/dummy_customer/some_concern.rb +9 -0
  15. data/spec/dummy/app/models/dummy_customer.rb +1 -0
  16. data/spec/dummy/config/initializers/lhs.rb +5 -0
  17. data/spec/dummy/config/routes.rb +1 -1
  18. data/spec/record/compact_spec.rb +5 -0
  19. data/spec/record/create_spec.rb +53 -13
  20. data/spec/record/includes_after_expansion_spec.rb +72 -0
  21. data/spec/record/includes_missing_spec.rb +59 -0
  22. data/spec/request_cycle_cache_spec.rb +1 -1
  23. metadata +14 -16
  24. data/Gemfile.activesupport4 +0 -5
  25. data/cider-ci.yml +0 -6
  26. data/cider-ci/bin/bundle +0 -51
  27. data/cider-ci/bin/ruby_install +0 -8
  28. data/cider-ci/bin/ruby_version +0 -25
  29. data/cider-ci/jobs/rspec-activesupport-4.yml +0 -27
  30. data/cider-ci/jobs/rspec-activesupport-5.yml +0 -26
  31. data/cider-ci/jobs/rspec-activesupport-latest.yml +0 -24
  32. data/cider-ci/jobs/rubocop.yml +0 -18
  33. data/cider-ci/task_components/bundle.yml +0 -22
  34. data/cider-ci/task_components/rspec.yml +0 -37
  35. data/cider-ci/task_components/rubocop.yml +0 -29
  36. data/cider-ci/task_components/ruby.yml +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca4c950dd6c2640b9bc05fc571ab0e54c06c2a796a1f004cd5fdb1898f186785
4
- data.tar.gz: 0ce0b9625865a63398334af094e9aa13abe7659c1a973e46bd60256c4ae5e343
3
+ metadata.gz: 22ba3545c4f37d2becb37fbe7efb328a942af240d6a4d03e64fea4890e766969
4
+ data.tar.gz: 9cd64f9e1222e7f0f4cb041bdf967c257a2f0fd3ef1564618a65650e23a07ec1
5
5
  SHA512:
6
- metadata.gz: a4333ef227de49a40508d2ae4a91ef25f3b4b40f94853b285099c8bd3e5a14104d2cd939aa058690a72bdd67c320bd6c21f93bb311ba001c5ec859d18a959d81
7
- data.tar.gz: 0c0f9fb7860dd1787a0c206068f51ef757d49943b607395993d0b0f0547424c00722fb7fd35b3e3d234fae736e984e84749e5ed9d679a1dd7169715806d28a14
6
+ metadata.gz: a9c87bfbc21370b89591c0b7a58bf30a24d8123ccbd41280f418afd69a5ebae47d05e0367fabdc7b7a0441a3cdf9729da8fee97b1c2fd5c39fbc757a7c1a0e6e
7
+ data.tar.gz: 4ef0c1857ba4983df1c567ea3ffee56ef5348e195e000beed34b4d91d7d372effc9c7fcbeb0d59419aebad7477926ece0e8938b9dfab936827603a8488f051a8
@@ -0,0 +1,16 @@
1
+ name: Rubocop
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ rubocop:
7
+ runs-on: ubuntu-18.04
8
+
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - uses: ruby/setup-ruby@v1
12
+ with:
13
+ bundler-cache: true
14
+ - name: Run Rubocop
15
+ run: |
16
+ bundle exec rubocop
@@ -0,0 +1,20 @@
1
+ name: Test ActiveSupport v5
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ rspec:
7
+ runs-on: ubuntu-18.04
8
+
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - uses: ruby/setup-ruby@v1
12
+ with:
13
+ bundler-cache: true
14
+ env:
15
+ BUNDLE_GEMFILE: Gemfile.activesupport5
16
+ - name: Run Tests
17
+ env:
18
+ BUNDLE_GEMFILE: Gemfile.activesupport5
19
+ run: |
20
+ bundle exec rspec
@@ -0,0 +1,16 @@
1
+ name: Test
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ rspec:
7
+ runs-on: ubuntu-18.04
8
+
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - uses: ruby/setup-ruby@v1
12
+ with:
13
+ bundler-cache: true
14
+ - name: Run Tests
15
+ run: |
16
+ bundle exec rspec
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.6.5
1
+ ruby-2.7.2
@@ -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
- next if parents.none? { |parent| File.read(file).match(/\b#{parent}\b/) }
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? Array
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(input: target._raw, value: addition.reject { |item| item.nil? }, record: self)
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])
@@ -45,7 +45,7 @@ class LHS::Item < LHS::Proxy
45
45
  _data.merge_raw!(response_data.unwrap(:item_created_key))
46
46
  response_headers = response_data._request.response.headers
47
47
  end
48
- if response_headers && response_headers['Location']
48
+ if options.fetch(:followlocation, true) && response_headers && response_headers['Location']
49
49
  location_data = record.request(options.merge(url: response_headers['Location'], method: :get, body: nil))
50
50
  _data.merge_raw!(location_data.unwrap(:item_created_key))
51
51
  end
@@ -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 { |option| option.deep_merge(LHS::OptionBlocks::CurrentOptionBlock.options) }
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 = load_include(options, data, sub_includes, reference)
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, including, referencing)
307
- handle_includes(including, data, referencing) if including.present? && data.present?
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHS
4
- VERSION = '25.0.1'
4
+ VERSION = '25.2.0'
5
5
  end
@@ -3,7 +3,7 @@
3
3
  class RequestCycleCacheController < ApplicationController
4
4
  def simple
5
5
  User.find(1) # first request
6
- user = User.find(1) # second request that should be serverd from request cycle cache
6
+ user = User.find(1) # second request that should be served from request cycle cache
7
7
  render json: user.to_json
8
8
  end
9
9
 
@@ -15,13 +15,13 @@ class RequestCycleCacheController < ApplicationController
15
15
 
16
16
  def parallel
17
17
  User.find(1, 2) # first request
18
- users = User.find(1, 2) # second request that should be serverd from request cycle cache
18
+ users = User.find(1, 2) # second request that should be served from request cycle cache
19
19
  render json: users.to_json
20
20
  end
21
21
 
22
- def headers
22
+ def different_headers
23
23
  User.find(1) # first request
24
- user = User.options(headers: { 'Authentication' => 'Bearer 123' }).find(1) # second request that should NOT be serverd from request cycle cache as the headers are different
24
+ user = User.options(headers: { 'Authentication' => 'Bearer 123' }).find(1) # second request that should NOT be served from request cycle cache as the headers are different
25
25
  render json: user.to_json
26
26
  end
27
27
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DummyCustomer < Providers::CustomerSystem
4
+ module SomeConcern
5
+ extend ActiveSupport::Concern
6
+
7
+ # dont auto load this again with LHS as it would raise an exception
8
+ end
9
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class DummyCustomer < Providers::CustomerSystem
4
+ include SomeConcern
4
5
  endpoint 'http://customers'
5
6
  endpoint 'http://customers/{id}'
6
7
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ LHS.configure do |config|
4
+ config.auto_oauth = -> { access_token }
5
+ end
@@ -12,7 +12,7 @@ Rails.application.routes.draw do
12
12
  get 'request_cycle_cache/simple' => 'request_cycle_cache#simple'
13
13
  get 'request_cycle_cache/no_caching_interceptor' => 'request_cycle_cache#no_caching_interceptor'
14
14
  get 'request_cycle_cache/parallel' => 'request_cycle_cache#parallel'
15
- get 'request_cycle_cache/headers' => 'request_cycle_cache#headers'
15
+ get 'request_cycle_cache/different_headers' => 'request_cycle_cache#different_headers'
16
16
 
17
17
  # Error handling with chains
18
18
  get 'error_handling_with_chains/fetch_in_controller' => 'error_handling_with_chains#fetch_in_controller'
@@ -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
@@ -135,25 +135,65 @@ describe LHS::Record do
135
135
  end
136
136
 
137
137
  context 'location header' do
138
- before do
139
- class ContactPerson < LHS::Record
140
- endpoint 'http://datastore/contact_persons'
141
- end
142
- end
143
-
144
- let(:location) { 'http://datastore/contact_persons/1' }
145
138
  let(:created_at) { '2017-12-21' }
139
+ let(:location) { 'http://datastore/contact_persons/1' }
146
140
  let(:name) { 'Sebastian' }
147
-
148
- it 'Loads the data from the "Location" header after creation' do
141
+ let!(:create_contact_person_request) do
149
142
  stub_request(:post, "http://datastore/contact_persons")
150
143
  .to_return(status: 204, headers: { Location: location })
144
+ end
145
+ let!(:fetch_contact_person_request) do
151
146
  stub_request(:get, "http://datastore/contact_persons/1")
152
147
  .to_return(body: { href: location, name: name, created_at: created_at }.to_json)
153
- contact_person = ContactPerson.create!(name: name)
154
- expect(contact_person.href).to eq location
155
- expect(contact_person.created_at).to eq Date.parse(created_at)
156
- expect(contact_person.name).to eq name
148
+ end
149
+
150
+ context 'without `followlocation` option' do
151
+ before do
152
+ class ContactPerson < LHS::Record
153
+ endpoint 'http://datastore/contact_persons'
154
+ end
155
+ end
156
+
157
+ it 'loads the data from the "Location" header after creation' do
158
+ contact_person = ContactPerson.create!(name: name)
159
+ expect(create_contact_person_request).to have_been_made.once
160
+ expect(fetch_contact_person_request).to have_been_made.once
161
+ expect(contact_person.href).to eq location
162
+ expect(contact_person.created_at).to eq Date.parse(created_at)
163
+ expect(contact_person.name).to eq name
164
+ end
165
+ end
166
+
167
+ context 'when `followlocation` is set to `true`' do
168
+ before do
169
+ class ContactPerson < LHS::Record
170
+ endpoint 'http://datastore/contact_persons', followlocation: true
171
+ end
172
+ end
173
+
174
+ it 'loads the data from the "Location" header after creation' do
175
+ contact_person = ContactPerson.create!(name: name)
176
+ expect(create_contact_person_request).to have_been_made.once
177
+ expect(fetch_contact_person_request).to have_been_made.once
178
+ expect(contact_person.href).to eq location
179
+ expect(contact_person.created_at).to eq Date.parse(created_at)
180
+ expect(contact_person.name).to eq name
181
+ end
182
+ end
183
+
184
+ context 'when `followlocation` is set to `false`' do
185
+ before do
186
+ class ContactPerson < LHS::Record
187
+ endpoint 'http://datastore/contact_persons', followlocation: false
188
+ end
189
+ end
190
+
191
+ it 'does not load the data from the "Location" header after creation' do
192
+ contact_person = ContactPerson.create!(name: name)
193
+ expect(create_contact_person_request).to have_been_made.once
194
+ expect(fetch_contact_person_request).not_to have_been_made
195
+ expect(contact_person.name).to eq name
196
+ end
157
197
  end
158
198
  end
159
199
  end
@@ -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
@@ -85,7 +85,7 @@ describe 'Request Cycle Cache', type: :request do
85
85
  context 'headers' do
86
86
  it 'considers the request headers when setting the cache key',
87
87
  dummy_models: true, request_cycle_cache: true do
88
- get '/request_cycle_cache/headers'
88
+ get '/request_cycle_cache/different_headers'
89
89
  expect(request).to have_been_made.times(2)
90
90
  end
91
91
  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.0.1
4
+ version: 25.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhs/graphs/contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-16 00:00:00.000000000 Z
11
+ date: 2021-05-10 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
@@ -389,6 +379,7 @@ files:
389
379
  - spec/dummy/app/mailers/.keep
390
380
  - spec/dummy/app/models/.keep
391
381
  - spec/dummy/app/models/concerns/.keep
382
+ - spec/dummy/app/models/concerns/dummy_customer/some_concern.rb
392
383
  - spec/dummy/app/models/dummy_customer.rb
393
384
  - spec/dummy/app/models/dummy_record.rb
394
385
  - spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb
@@ -418,6 +409,7 @@ files:
418
409
  - spec/dummy/config/initializers/cookies_serializer.rb
419
410
  - spec/dummy/config/initializers/filter_parameter_logging.rb
420
411
  - spec/dummy/config/initializers/inflections.rb
412
+ - spec/dummy/config/initializers/lhs.rb
421
413
  - spec/dummy/config/initializers/mime_types.rb
422
414
  - spec/dummy/config/initializers/rollbar.rb
423
415
  - spec/dummy/config/initializers/session_store.rb
@@ -504,8 +496,10 @@ files:
504
496
  - spec/record/href_for_spec.rb
505
497
  - spec/record/ignore_errors_spec.rb
506
498
  - spec/record/immutable_chains_spec.rb
499
+ - spec/record/includes_after_expansion_spec.rb
507
500
  - spec/record/includes_expanded_spec.rb
508
501
  - spec/record/includes_first_page_spec.rb
502
+ - spec/record/includes_missing_spec.rb
509
503
  - spec/record/includes_spec.rb
510
504
  - spec/record/includes_warning_spec.rb
511
505
  - spec/record/item_key_spec.rb
@@ -570,7 +564,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
570
564
  version: '0'
571
565
  requirements:
572
566
  - Ruby >= 2.3.0
573
- rubygems_version: 3.0.6
567
+ rubygems_version: 3.1.4
574
568
  signing_key:
575
569
  specification_version: 4
576
570
  summary: 'REST services accelerator: Rails gem providing an easy, active-record-like
@@ -619,6 +613,7 @@ test_files:
619
613
  - spec/dummy/app/mailers/.keep
620
614
  - spec/dummy/app/models/.keep
621
615
  - spec/dummy/app/models/concerns/.keep
616
+ - spec/dummy/app/models/concerns/dummy_customer/some_concern.rb
622
617
  - spec/dummy/app/models/dummy_customer.rb
623
618
  - spec/dummy/app/models/dummy_record.rb
624
619
  - spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb
@@ -648,6 +643,7 @@ test_files:
648
643
  - spec/dummy/config/initializers/cookies_serializer.rb
649
644
  - spec/dummy/config/initializers/filter_parameter_logging.rb
650
645
  - spec/dummy/config/initializers/inflections.rb
646
+ - spec/dummy/config/initializers/lhs.rb
651
647
  - spec/dummy/config/initializers/mime_types.rb
652
648
  - spec/dummy/config/initializers/rollbar.rb
653
649
  - spec/dummy/config/initializers/session_store.rb
@@ -734,8 +730,10 @@ test_files:
734
730
  - spec/record/href_for_spec.rb
735
731
  - spec/record/ignore_errors_spec.rb
736
732
  - spec/record/immutable_chains_spec.rb
733
+ - spec/record/includes_after_expansion_spec.rb
737
734
  - spec/record/includes_expanded_spec.rb
738
735
  - spec/record/includes_first_page_spec.rb
736
+ - spec/record/includes_missing_spec.rb
739
737
  - spec/record/includes_spec.rb
740
738
  - spec/record/includes_warning_spec.rb
741
739
  - spec/record/item_key_spec.rb
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org/'
2
-
3
- gemspec
4
- gem 'activesupport', '~> 4.2.11'
5
- gem 'bundler', '~> 1.17.3'
data/cider-ci.yml DELETED
@@ -1,6 +0,0 @@
1
- jobs:
2
- include:
3
- - cider-ci/jobs/rspec-activesupport-4.yml
4
- - cider-ci/jobs/rspec-activesupport-5.yml
5
- - cider-ci/jobs/rspec-activesupport-latest.yml
6
- - cider-ci/jobs/rubocop.yml
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
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -eux
3
-
4
- export PATH=~/.rubies/$RUBY/bin:$PATH
5
-
6
- if [ ! -d ~/.rubies/$RUBY ]; then
7
- ruby-install --no-install-deps $RUBY
8
- fi
@@ -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
@@ -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
-