diff --git a/.rubocop.yml b/.rubocop.yml index 451eecf..62e7e41 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -10,6 +10,11 @@ Layout/SpaceInsideHashLiteralBraces: Lint/AssignmentInCondition: Enabled: false +Metrics/CyclomaticComplexity: + Max: 9 +Metrics/PerceivedComplexity: + Max: 9 + Style/ClassAndModuleChildren: Enabled: false Style/ConditionalAssignment: diff --git a/lib/ja2r/element.rb b/lib/ja2r/element.rb index b54ca8d..4e58cf3 100644 --- a/lib/ja2r/element.rb +++ b/lib/ja2r/element.rb @@ -3,7 +3,8 @@ class Element def initialize(origin_data, options = {}) @origin_data = origin_data.with_indifferent_access @options = options - @relationships = origin_data['relationships'] ? convert_relationships(origin_data['relationships']) : {} + @relationships = origin_data['relationships']&.then { |rd| convert_relationships(rd) } || {} + build_references end attr_reader :origin_data, :relationships @@ -39,18 +40,31 @@ def type private - def method_missing(symbol, *args) - return attributes[symbol] if attributes&.key? symbol - return relationships[symbol] if relationships&.key? symbol + def build_references + @references = {}.with_indifferent_access + attributes&.each_key do |key| + @references[key] ||= {attribute: key} + @references[key.underscore] ||= {attribute: key} + end + relationships&.each_key do |key| + @references[key] ||= {relationship: key} + @references[key.underscore] ||= {relationship: key} + end + end - safe_traverse? ? nil : super + def method_missing(symbol, *args) + case @references[symbol] + in attribute: + attributes[attribute] + in relationship: + relationships[relationship] + else + safe_traverse? ? nil : super + end end def respond_to_missing?(symbol, include_all = false) - return true if attributes&.key?(symbol) - return true if relationships&.key?(symbol) - - safe_traverse? || super + @references.key?(symbol) || safe_traverse? || super end def safe_traverse? diff --git a/spec/fixtures/singular.json b/spec/fixtures/singular.json index fa1661c..59acf2a 100644 --- a/spec/fixtures/singular.json +++ b/spec/fixtures/singular.json @@ -12,6 +12,12 @@ "example": true }, "relationships":{ + "best-friend":{ + "data":{ + "id":"1005", + "type":"persons" + } + }, "sister":{ "data":{ "id":"1002", @@ -34,6 +40,13 @@ "name":"Lisa" } }, + { + "id":"1005", + "type":"persons", + "attributes":{ + "name":"Milhouse" + } + }, { "id":"998", "type":"persons", diff --git a/spec/ja2r/element_spec.rb b/spec/ja2r/element_spec.rb index 242d4a9..61d9785 100644 --- a/spec/ja2r/element_spec.rb +++ b/spec/ja2r/element_spec.rb @@ -43,4 +43,30 @@ end end end + + context 'with dashes in the keys' do + let(:origin_data) do + { + 'id' => 'some-id', + 'attributes' => { + 'foo-field' => 'foo-value', + 'bar-field' => { + 'bar-value' => true + } + }, + 'relationships' => { + 'some-one' => { + 'data' => {'id' => '1122', 'type' => 'some-ones'} + } + } + } + end + + it 'allows navigation with underscore' do + expect(element.foo_field).to eq 'foo-value' + expect(element.bar_field).to eq('bar-value' => true) + expect(element.some_one).to be_a(described_class) + expect(element.some_one.type).to eq('some-ones') + end + end end diff --git a/spec/ja2r_spec.rb b/spec/ja2r_spec.rb index 7cca268..cc48abe 100644 --- a/spec/ja2r_spec.rb +++ b/spec/ja2r_spec.rb @@ -5,6 +5,7 @@ it 'can handle singular relations' do ele = described_class.parse payload expect(ele.id).to eq '1001' + expect(ele.best_friend.name).to eq 'Milhouse' expect(ele.sister.id).to eq '1002' expect(ele.sister.name).to eq 'Lisa' expect(ele.father.id).to eq '998'