lhs 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.localch.yml +190 -0
  3. data/.rubocop.yml +7 -0
  4. data/cider-ci.yml +2 -1
  5. data/cider-ci/jobs/rspec.yml +48 -0
  6. data/cider-ci/jobs/rubocop.yml +55 -0
  7. data/cider-ci/scripts/bundle.yml +2 -0
  8. data/cider-ci/scripts/github_comment.yml +6 -0
  9. data/cider-ci/scripts/rspec.yml +4 -0
  10. data/cider-ci/scripts/rubocop.yml +5 -0
  11. data/cider-ci/scripts/ruby-version.yml +2 -0
  12. data/cider-ci/scripts/tmp-cache.yml +2 -0
  13. data/lhs.gemspec +1 -0
  14. data/lib/lhs/collection.rb +2 -6
  15. data/lib/lhs/concerns/data/json.rb +1 -1
  16. data/lib/lhs/concerns/item/save.rb +11 -10
  17. data/lib/lhs/concerns/item/update.rb +1 -1
  18. data/lib/lhs/concerns/item/validation.rb +2 -2
  19. data/lib/lhs/concerns/record/all.rb +1 -2
  20. data/lib/lhs/concerns/record/batch.rb +2 -3
  21. data/lib/lhs/concerns/record/create.rb +7 -8
  22. data/lib/lhs/concerns/record/endpoints.rb +2 -3
  23. data/lib/lhs/concerns/record/find.rb +6 -6
  24. data/lib/lhs/concerns/record/find_by.rb +8 -8
  25. data/lib/lhs/concerns/record/first.rb +0 -1
  26. data/lib/lhs/concerns/record/includes.rb +0 -1
  27. data/lib/lhs/concerns/record/mapping.rb +0 -1
  28. data/lib/lhs/concerns/record/model.rb +0 -1
  29. data/lib/lhs/concerns/record/request.rb +18 -14
  30. data/lib/lhs/concerns/record/where.rb +0 -1
  31. data/lib/lhs/data.rb +3 -4
  32. data/lib/lhs/endpoint.rb +1 -2
  33. data/lib/lhs/errors.rb +7 -13
  34. data/lib/lhs/item.rb +5 -9
  35. data/lib/lhs/record.rb +12 -8
  36. data/lib/lhs/version.rb +1 -1
  37. data/spec/collection/delegate_spec.rb +0 -2
  38. data/spec/collection/enumerable_spec.rb +2 -4
  39. data/spec/collection/meta_data_spec.rb +0 -1
  40. data/spec/collection/respond_to_spec.rb +0 -1
  41. data/spec/collection/without_object_items_spec.rb +0 -1
  42. data/spec/data/collection_spec.rb +4 -7
  43. data/spec/data/item_spec.rb +3 -5
  44. data/spec/data/merge_spec.rb +7 -9
  45. data/spec/data/raw_spec.rb +3 -5
  46. data/spec/data/respond_to_spec.rb +3 -5
  47. data/spec/data/root_spec.rb +3 -5
  48. data/spec/data/select_spec.rb +2 -4
  49. data/spec/data/to_json_spec.rb +5 -7
  50. data/spec/dummy/bin/rails +1 -1
  51. data/spec/dummy/config.ru +1 -1
  52. data/spec/dummy/config/initializers/cookies_serializer.rb +1 -1
  53. data/spec/endpoint/for_url_spec.rb +3 -5
  54. data/spec/item/delegate_spec.rb +0 -2
  55. data/spec/item/destroy_spec.rb +3 -5
  56. data/spec/item/errors_spec.rb +20 -23
  57. data/spec/item/getter_spec.rb +1 -3
  58. data/spec/item/internal_data_structure_spec.rb +2 -3
  59. data/spec/item/respond_to_spec.rb +1 -1
  60. data/spec/item/save_spec.rb +7 -10
  61. data/spec/item/setter_spec.rb +2 -4
  62. data/spec/item/update_spec.rb +4 -7
  63. data/spec/item/validation_spec.rb +7 -9
  64. data/spec/proxy/load_spec.rb +0 -2
  65. data/spec/record/all_spec.rb +10 -12
  66. data/spec/record/build_spec.rb +0 -2
  67. data/spec/record/create_spec.rb +8 -10
  68. data/spec/record/creation_failed_spec.rb +4 -6
  69. data/spec/record/definitions_spec.rb +1 -3
  70. data/spec/record/endpoint_misconfiguration_spec.rb +2 -4
  71. data/spec/record/endpoint_options_spec.rb +0 -2
  72. data/spec/record/endpoints_spec.rb +1 -6
  73. data/spec/record/find_each_spec.rb +2 -4
  74. data/spec/record/find_in_batches_spec.rb +4 -6
  75. data/spec/record/find_spec.rb +10 -13
  76. data/spec/record/first_spec.rb +0 -3
  77. data/spec/record/includes_spec.rb +15 -20
  78. data/spec/record/mapping_spec.rb +13 -15
  79. data/spec/record/model_name_spec.rb +0 -2
  80. data/spec/record/new_spec.rb +4 -2
  81. data/spec/record/request_spec.rb +1 -3
  82. data/spec/record/where_spec.rb +1 -3
  83. data/spec/spec_helper.rb +1 -1
  84. data/spec/support/cleanup_configuration.rb +0 -2
  85. data/spec/support/cleanup_endpoints.rb +0 -1
  86. data/spec/support/cleanup_records.rb +0 -2
  87. metadata +26 -4
  88. data/cider-ci/contexts/rspec.yml +0 -16
  89. data/cider-ci/jobs/tests.yml +0 -27
@@ -6,7 +6,6 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  # Should be an edge case but sometimes all objects from a certain resource
11
10
  # are required. In this case we load the first page with the default max limit,
12
11
  # compute the amount of left over requests, do all the the left over requests
@@ -22,7 +21,7 @@ class LHS::Record
22
21
  if limit > 0
23
22
  requests = total_left / limit
24
23
  requests.times do |i|
25
- offset = limit * (i+1) + 1
24
+ offset = limit * (i + 1) + 1
26
25
  all.concat request(params: params.merge(limit: limit, offset: offset))._raw[:items]
27
26
  end
28
27
  end
@@ -6,13 +6,12 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  # Process single entries fetched in batches
11
10
  def find_each(options = {})
12
11
  find_in_batches(options) do |data|
13
12
  data.each do |record|
14
13
  item = LHS::Item.new(LHS::Data.new(record, data, self))
15
- yield self.new(LHS::Data.new(item, data, self))
14
+ yield new(LHS::Data.new(item, data, self))
16
15
  end
17
16
  end
18
17
  end
@@ -27,7 +26,7 @@ class LHS::Record
27
26
  data = request(params: params.merge(limit: batch_size, offset: start))
28
27
  batch_size = data._raw[:limit]
29
28
  left = data._raw[:total].to_i - data._raw[:offset].to_i - data._raw[:limit].to_i
30
- yield self.new(data)
29
+ yield new(data)
31
30
  break if left <= 0
32
31
  start += batch_size
33
32
  end
@@ -6,20 +6,19 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  def create(data = {})
11
10
  create!(data)
12
- rescue LHC::Error => e
13
- json = JSON.parse(data.to_json)
14
- data = LHS::Data.new(json, nil, self, e.response.request)
15
- item = LHS::Item.new(data)
16
- item.errors = LHS::Errors.new(e.response)
17
- data._record_class.new(LHS::Data.new(item, data))
11
+ rescue LHC::Error => e
12
+ json = JSON.parse(data.to_json)
13
+ data = LHS::Data.new(json, nil, self, e.response.request)
14
+ item = LHS::Item.new(data)
15
+ item.errors = LHS::Errors.new(e.response)
16
+ data._record_class.new(LHS::Data.new(item, data))
18
17
  end
19
18
 
20
19
  def create!(data = {})
21
20
  url = compute_url!(data)
22
- data = request(url: url, method: :post, body: data.to_json, headers: {'Content-Type' => 'application/json'})
21
+ data = request(url: url, method: :post, body: data.to_json, headers: { 'Content-Type' => 'application/json' })
23
22
  data._record_class.new(data)
24
23
  end
25
24
  end
@@ -12,7 +12,6 @@ class LHS::Record
12
12
  mattr_accessor :all
13
13
 
14
14
  module ClassMethods
15
-
16
15
  def endpoints
17
16
  @endpoints ||= []
18
17
  end
@@ -32,7 +31,7 @@ class LHS::Record
32
31
 
33
32
  def for_url(url)
34
33
  return unless url
35
- template, record = LHS::Record::Endpoints.all.detect do |template, _record_class|
34
+ _template, record = LHS::Record::Endpoints.all.detect do |template, _record_class|
36
35
  LHC::Endpoint.match?(url, template)
37
36
  end
38
37
  record
@@ -75,7 +74,7 @@ class LHS::Record
75
74
 
76
75
  # Sort endpoints by number of placeholders, heighest first
77
76
  def sorted_endpoints
78
- endpoints.sort{|a, b| b.placeholders.count <=> a.placeholders.count }
77
+ endpoints.sort { |a, b| b.placeholders.count <=> a.placeholders.count }
79
78
  end
80
79
 
81
80
  # Finds the base endpoint.
@@ -6,14 +6,14 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  # Find a single uniqe record
11
10
  def find(args)
12
- data = if args.is_a? Hash
13
- find_with_parameters(args)
14
- else
15
- find_by_id(args)
16
- end
11
+ data =
12
+ if args.is_a? Hash
13
+ find_with_parameters(args)
14
+ else
15
+ find_by_id(args)
16
+ end
17
17
  data._record_class.new(data)
18
18
  end
19
19
 
@@ -6,12 +6,11 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  # Fetch some record by parameters
11
10
  def find_by(params = {})
12
11
  _find_by(params)
13
- rescue LHC::NotFound
14
- nil
12
+ rescue LHC::NotFound
13
+ nil
15
14
  end
16
15
 
17
16
  # Raise if no record was found
@@ -24,11 +23,12 @@ class LHS::Record
24
23
  def _find_by(params)
25
24
  params = params.dup.merge(limit: 1)
26
25
  data = request(params: params)
27
- data = if data._proxy.is_a?(LHS::Collection)
28
- data.first || fail(LHC::NotFound.new('No item was found.', data._request.response))
29
- else
30
- data
31
- end
26
+ data =
27
+ if data._proxy.is_a?(LHS::Collection)
28
+ data.first || fail(LHC::NotFound.new('No item was found.', data._request.response))
29
+ else
30
+ data
31
+ end
32
32
  data._record_class.new(data)
33
33
  end
34
34
  end
@@ -6,7 +6,6 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  def first
11
10
  find_by
12
11
  end
@@ -6,7 +6,6 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  def including
11
10
  @including
12
11
  end
@@ -7,7 +7,6 @@ class LHS::Record
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  module ClassMethods
10
-
11
10
  def mapping
12
11
  @mapping ||= {}
13
12
  end
@@ -7,7 +7,6 @@ class LHS::Record
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  module ClassMethods
10
-
11
10
  def model_name
12
11
  ActiveModel::Name.new(self)
13
12
  end
@@ -6,7 +6,6 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  def request(options)
11
10
  if options.is_a? Array
12
11
  multiple_requests(options)
@@ -29,7 +28,8 @@ class LHS::Record
29
28
  def convert_option_to_endpoints(option)
30
29
  new_options = option.dup
31
30
  url = option[:url]
32
- return unless endpoint = LHS::Endpoint.for_url(url)
31
+ endpoint = LHS::Endpoint.for_url(url)
32
+ return unless endpoint
33
33
  template = endpoint.url
34
34
  new_options = new_options.merge(params: LHC::Endpoint.values_as_params(template, url))
35
35
  new_options[:url] = template
@@ -50,23 +50,26 @@ class LHS::Record
50
50
 
51
51
  def handle_includes(includes, data)
52
52
  if includes.is_a? Hash
53
- includes.each { |_include, sub_includes| handle_include(_include, data, sub_includes) }
53
+ includes.each { |included, sub_includes| handle_include(included, data, sub_includes) }
54
54
  elsif includes.is_a? Array
55
- includes.each { |_include| handle_includes(_include, data) }
55
+ includes.each { |included| handle_includes(included, data) }
56
56
  else
57
57
  handle_include(includes, data)
58
58
  end
59
59
  end
60
60
 
61
- def handle_include(_include, data, sub_includes = nil)
61
+ def handle_include(included, data, sub_includes = nil)
62
62
  return unless data.present?
63
- options = if data._proxy.is_a? LHS::Collection
64
- options_for_multiple(data, _include)
65
- else
66
- url_option_for(data, _include)
67
- end
63
+ options =
64
+ if data._proxy.is_a? LHS::Collection
65
+ options_for_multiple(data, included)
66
+ options_for_multiple(data, included)
67
+ else
68
+ url_option_for(data, included)
69
+ url_option_for(data, included)
70
+ end
68
71
  addition = load_include(options, data, sub_includes)
69
- extend_raw_data(data, addition, _include)
72
+ extend_raw_data(data, addition, included)
70
73
  end
71
74
 
72
75
  # Load additional resources that are requested with include
@@ -89,9 +92,9 @@ class LHS::Record
89
92
  end
90
93
 
91
94
  def multiple_requests(options)
92
- options = options.map { |options| process_options(options) }
95
+ options = options.map { |option| process_options(option) }
93
96
  responses = LHC.request(options)
94
- data = responses.map{ |response| LHS::Data.new(response.body, nil, self, response.request) }
97
+ data = responses.map { |response| LHS::Data.new(response.body, nil, self, response.request) }
95
98
  data = LHS::Data.new(data, nil, self)
96
99
  handle_includes(including, data) if including
97
100
  data
@@ -120,7 +123,8 @@ class LHS::Record
120
123
  records = []
121
124
  if options.is_a?(Array)
122
125
  options.each do |option|
123
- next unless record = LHS::Record.for_url(option[:url])
126
+ record = LHS::Record.for_url(option[:url])
127
+ next unless record
124
128
  records.push(record)
125
129
  end
126
130
  fail 'Found more than one record that could be used to do the request' if records.uniq.count > 1
@@ -6,7 +6,6 @@ class LHS::Record
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
-
10
9
  # Used to query data from the service.
11
10
  def where(params = {})
12
11
  data = request(params: params)
@@ -1,5 +1,5 @@
1
1
  require File.join(__dir__, 'proxy.rb')
2
- Dir[File.dirname(__FILE__) + '/concerns/data/*.rb'].each {|file| require file }
2
+ Dir[File.dirname(__FILE__) + '/concerns/data/*.rb'].each { |file| require file }
3
3
 
4
4
  # Data provides functionalities to accesses information
5
5
  class LHS::Data
@@ -51,7 +51,7 @@ class LHS::Data
51
51
 
52
52
  def respond_to_missing?(name, include_all = false)
53
53
  (root_item? && _root._record_class.instance_methods.include?(name)) ||
54
- _proxy.respond_to?(name, include_all)
54
+ _proxy.respond_to?(name, include_all)
55
55
  end
56
56
 
57
57
  private
@@ -61,14 +61,13 @@ class LHS::Data
61
61
  end
62
62
 
63
63
  def root_item
64
- return if self._proxy.class != LHS::Item
64
+ return if _proxy.class != LHS::Item
65
65
  root = root_item = self
66
66
  loop do
67
67
  root = root._parent
68
68
  root_item = root if root && root._proxy.is_a?(LHS::Item)
69
69
  if !(root && root._parent)
70
70
  break
71
- else
72
71
  end
73
72
  end
74
73
  root_item
@@ -1,6 +1,6 @@
1
1
  # An endpoint is used as source to fetch objects
2
2
  class LHS::Endpoint
3
-
3
+
4
4
  def self.for_url(url)
5
5
  template, record = LHS::Record::Endpoints.all.detect do |template, _record_class|
6
6
  LHC::Endpoint.match?(url, template)
@@ -8,4 +8,3 @@ class LHS::Endpoint
8
8
  record.endpoints.detect { |endpoint| endpoint.url == template } if record
9
9
  end
10
10
  end
11
-
@@ -8,14 +8,14 @@ class LHS::Errors
8
8
  @messages = messages_from_response(response)
9
9
  @message = message_from_response(response)
10
10
  @raw = response.body
11
- rescue JSON::ParserError
11
+ rescue JSON::ParserError # rubocop:disable Lint/HandleExceptions
12
12
  end
13
13
 
14
14
  def include?(attribute)
15
15
  messages[attribute].present?
16
16
  end
17
- alias :has_key? :include?
18
- alias :key? :include?
17
+ alias has_key? include?
18
+ alias key? include?
19
19
 
20
20
  def get(key)
21
21
  messages[key]
@@ -25,9 +25,7 @@ class LHS::Errors
25
25
  messages[key] = value
26
26
  end
27
27
 
28
- def delete(key)
29
- messages.delete(key)
30
- end
28
+ delegate :delete, to: :messages
31
29
 
32
30
  def [](attribute)
33
31
  get(attribute.to_sym) || set(attribute.to_sym, [])
@@ -47,20 +45,16 @@ class LHS::Errors
47
45
  values.flatten.size
48
46
  end
49
47
 
50
- def values
51
- messages.values
52
- end
48
+ delegate :values, to: :messages
53
49
 
54
- def keys
55
- messages.keys
56
- end
50
+ delegate :keys, to: :messages
57
51
 
58
52
  def count
59
53
  to_a.size
60
54
  end
61
55
 
62
56
  def empty?
63
- all? { |k, v| v && v.empty? && !v.is_a?(String) }
57
+ all? { |_k, v| v && v.empty? && !v.is_a?(String) }
64
58
  end
65
59
 
66
60
  private
@@ -1,5 +1,5 @@
1
1
  require File.join(__dir__, 'proxy.rb')
2
- Dir[File.dirname(__FILE__) + '/concerns/item/*.rb'].each {|file| require file }
2
+ Dir[File.dirname(__FILE__) + '/concerns/item/*.rb'].each { |file| require file }
3
3
 
4
4
  # An item is a concrete record.
5
5
  # It can be part of another proxy like collection.
@@ -14,13 +14,11 @@ class LHS::Item < LHS::Proxy
14
14
  # prevent clashing with attributes of underlying data
15
15
  attr_accessor :errors
16
16
 
17
- def _raw
18
- _data._raw
19
- end
17
+ delegate :_raw, to: :_data
20
18
 
21
19
  protected
22
20
 
23
- def method_missing(name, *args, &block)
21
+ def method_missing(name, *args, &_block)
24
22
  return set(name, args.try(&:first)) if name.to_s[/=$/]
25
23
  name = args.first if name == :[]
26
24
  value = _data._raw[name.to_s]
@@ -36,7 +34,7 @@ class LHS::Item < LHS::Proxy
36
34
  end
37
35
  end
38
36
 
39
- def respond_to_missing?(name, include_all = false)
37
+ def respond_to_missing?(name, _include_all = false)
40
38
  # We accept every message that does not belong to set of keywords
41
39
  BLACKLISTED_KEYWORDS.exclude?(name.to_s)
42
40
  end
@@ -49,7 +47,7 @@ class LHS::Item < LHS::Proxy
49
47
  def convert(value)
50
48
  return value unless value.is_a?(String)
51
49
  if date_time?(value)
52
- DateTime.parse(value)
50
+ Time.zone.parse(value)
53
51
  elsif date?(value)
54
52
  Date.parse(value)
55
53
  else
@@ -72,8 +70,6 @@ class LHS::Item < LHS::Proxy
72
70
  _data._raw[key.to_sym] = value
73
71
  end
74
72
 
75
- private
76
-
77
73
  def date?(value)
78
74
  value[date_time_regex, :date].presence
79
75
  end
@@ -1,4 +1,4 @@
1
- Dir[File.dirname(__FILE__) + '/concerns/record/*.rb'].each {|file| require file }
1
+ Dir[File.dirname(__FILE__) + '/concerns/record/*.rb'].each { |file| require file }
2
2
 
3
3
  class LHS::Record
4
4
  include All
@@ -18,15 +18,19 @@ class LHS::Record
18
18
  data = LHS::Data.new({}, nil, self.class) unless data
19
19
  data = LHS::Data.new(data, nil, self.class) unless data.is_a?(LHS::Data)
20
20
  define_singleton_method(:_data) { data }
21
- if data._proxy.is_a?(LHS::Item) and data._raw.is_a?(Hash)
22
- data._raw.each { |k, v| instance_variable_set("@#{k}", v) }
23
- elsif data._proxy.is_a? LHS::Collection
24
- instance_variable_set('@collection', data._collection.raw)
25
- end
21
+ instance_data =
22
+ if data._proxy.is_a?(LHS::Item) && data._raw.is_a?(Hash)
23
+ data._raw
24
+ elsif data._proxy.is_a?(LHS::Collection) && data._raw.is_a?(Hash)
25
+ data._raw.fetch(:items, [])
26
+ else
27
+ data._raw
28
+ end
29
+ instance_variable_set('@data', instance_data)
26
30
  end
27
31
 
28
32
  def self.build(data = nil)
29
- self.new(data)
33
+ new(data)
30
34
  end
31
35
 
32
36
  protected
@@ -37,6 +41,6 @@ class LHS::Record
37
41
 
38
42
  def respond_to_missing?(name, include_all = false)
39
43
  (_data.root_item? && _data._root._record_class.instance_methods.include?(name)) ||
40
- _data._proxy.respond_to?(name, include_all)
44
+ _data._proxy.respond_to?(name, include_all)
41
45
  end
42
46
  end