lazy_doc 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MTYzNGFkNWU2YjdkM2I4OGE4YzAyY2UyNmRmOGNmOTFkMWI4ZDQ3Yg==
4
+ OGMxMGUwZTdmMDk4OGUyZGRhMTliNTI3NmUzM2RjZDMwYjY0ODM3Yg==
5
5
  data.tar.gz: !binary |-
6
- Nzk4YzFiNjhkMzg1YTI2YTI0YWIwY2QzZGIzYjk1OGE0NDVjYTNmMw==
6
+ MTNhYWFlY2MzOTQ0YWFmNDYyZTMxZTBkMDI0Mjk3YmVjMjg2YWFkZg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NmY4NmIwMGRjYmEzYTEwMWI2N2MxY2ZhYTRjYjc2NGNhZjU2NzBjYTllMmM0
10
- MzdlOWI1ZmY2ZGMzZmUxM2IwMjE1YWQ5OTE3NTRkZjBjYmIxZWNiNjkyOTk0
11
- Y2RjOTYwMzI1M2ViYTAyYjNjZWVlZDBhNzdmMTdlZDY1NzdkZmI=
9
+ MTJjMjgwZmYyZTA5ZWIxNWFmODBiMWUwZGNjZTM3ZGNiMDFlYzRhOTI4ZmE2
10
+ MjFiZWFhZWI2YmI5YzZmOTlmNWMwNmQwODg2M2MxNDgzYzM1ODBkYjJhZDlm
11
+ MTNmMjkzMGIyNWY5MzY3MTgzYWI1YmZkZDc2ZDMzZmQwMWMxODQ=
12
12
  data.tar.gz: !binary |-
13
- N2UzNDQ5OGVkNDlkZGQ3MmU0NzU2YzIyNTJiZDI2NDZmN2ZlNTZiN2ZhMmNi
14
- ZjkwNDY4M2EwY2YxYWI4MGQxYmUwOWZlNTRmNGE5YTk2ZmVjYzFkODA3ZGZh
15
- NDljN2U5ODg5NGQwYWJlOGJhN2IwN2IzMjVlM2I3ZTMzMTViOTY=
13
+ ZTQ0MWIxMjJmMzJiNmFlMjcxNTg1MTIxMDEyYjNkNjc5MDI5NDE0YzIxMTcx
14
+ MDJkMzM5NmIzOTIxOWQ4ZjNmNzY2NmM0ODJkZWJiYzc3NDEyMGMyMzFjYWRk
15
+ OGExNjc5MmIxMTU3MjQ4MzdkOTFlOTQ3ZjE4ODE0M2UxNzc5ODY=
data/README.md CHANGED
@@ -66,13 +66,13 @@ puts user.job
66
66
  5. DONE - Objects from sub-trees. ex: `access :profile, as: Profile` (This would construct a LazyDoc Profile object and pass the json found at "profile" to it)
67
67
  6. Collections.
68
68
  - DONE - Map. For example, extract array of customer names from array of customers. ex: `access :customers, extract: :name`
69
- - Objects from collection. Instead of extracting just the name, extract whole objects like in #5. ex: `access :customers, as: Customer`
70
- - Other Collection manipulations, select, inject, etc
69
+ - DONE - Objects from collection. Instead of extracting just the name, extract whole objects like in #5. ex: `access :customers, as: Customer`
70
+ - Other Collection manipulations, select, inject, count, etc
71
71
  7. Joins
72
72
  - Using previously defined attributes. ex: `join :address, from: [:street, :city, :state:, :zip]`
73
73
  - Defining attributes in place.
74
74
  8. DONE - Multiple simple paths in one line (ex: `access :name, :street, :city, :state`)
75
- 9. Infer camelCase to snake_case and vice versa in JSON ex: `access :customer_name` (Where the json has customerName)
75
+ 9. DONE- Infer camelCase to snake_case and vice versa in JSON ex: `access :customer_name` (Where the json has customerName)
76
76
  10. XML support
77
77
 
78
78
  ## Contributing
@@ -1,4 +1,5 @@
1
1
  require 'lazy_doc/attribute_not_found_error'
2
+ require 'lazy_doc/camelizable_string'
2
3
  require 'lazy_doc/commands'
3
4
  require 'lazy_doc/dsl'
4
5
  require 'lazy_doc/memoizer'
@@ -1,3 +1,3 @@
1
1
  module LazyDoc
2
- class AttributeNotFoundError < StandardError ;end
2
+ class AttributeNotFoundError < StandardError; end
3
3
  end
@@ -0,0 +1,15 @@
1
+ module LazyDoc
2
+ class CamelizableString
3
+ attr_reader :original
4
+
5
+ def initialize(original)
6
+ @original = original
7
+ end
8
+
9
+ def camelize
10
+ original.gsub(/(_)(.)/) { $2.upcase }
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -8,3 +8,21 @@ require 'lazy_doc/commands/default_value_command'
8
8
  require 'lazy_doc/commands/extract_command'
9
9
  require 'lazy_doc/commands/finally_command'
10
10
  require 'lazy_doc/commands/via_command'
11
+
12
+ module LazyDoc::Commands
13
+ OPTIONAL_COMMAND_CLASSES = {
14
+ default: DefaultValueCommand,
15
+ as: AsClassCommand,
16
+ extract: ExtractCommand,
17
+ finally: FinallyCommand
18
+ }
19
+
20
+ def self.create_commands_for(options)
21
+ options.map do |key, initialization_value|
22
+ if OPTIONAL_COMMAND_CLASSES.has_key?(key)
23
+ OPTIONAL_COMMAND_CLASSES[key].new(initialization_value)
24
+ end
25
+ end.compact
26
+
27
+ end
28
+ end
@@ -7,7 +7,16 @@ module LazyDoc::Commands
7
7
  end
8
8
 
9
9
  def execute(value)
10
- klass.nil? ? value : klass.new(value.to_json)
10
+ if klass.nil?
11
+ value
12
+ else
13
+ if value.is_a? Array
14
+ value.map { |element| klass.new(element.to_json) }
15
+ else
16
+ klass.new(value.to_json)
17
+ end
18
+ end
19
+
11
20
  end
12
21
  end
13
22
  end
@@ -7,15 +7,28 @@ module LazyDoc::Commands
7
7
  end
8
8
 
9
9
  def execute(document)
10
- path.inject(document) do |final_value, attribute|
11
- unless final_value.has_key?(attribute.to_s)
12
- raise LazyDoc::AttributeNotFoundError.new("Unable to access #{attribute} via #{path.join(', ')}")
13
- end
10
+ path.inject(document) do |sub_document, attribute|
11
+ attribute_identifier = determine_attribute_identifier(attribute, sub_document)
14
12
 
15
- final_value[attribute.to_s]
13
+ sub_document[attribute_identifier]
16
14
  end
17
15
  end
18
16
 
17
+ private
18
+
19
+ def determine_attribute_identifier(attribute, sub_document)
20
+ camelizable_attribute = LazyDoc::CamelizableString.new(attribute.to_s)
21
+
22
+ if sub_document.has_key?(camelizable_attribute.original)
23
+ camelizable_attribute.original
24
+ elsif sub_document.has_key?(camelizable_attribute.camelize)
25
+ camelizable_attribute.camelize
26
+ else
27
+ raise LazyDoc::AttributeNotFoundError.new("Unable to access #{attribute} via #{path.join(', ')}")
28
+ end
29
+
30
+ end
31
+
19
32
  end
20
33
 
21
34
  end
@@ -33,11 +33,8 @@ module LazyDoc
33
33
  end
34
34
 
35
35
  def define_access_method_for(attribute, options)
36
- create_method(attribute, Commands::ViaCommand.new(options[:via] || attribute),
37
- Commands::DefaultValueCommand.new(options[:default]),
38
- Commands::AsClassCommand.new(options[:as]),
39
- Commands::ExtractCommand.new(options[:extract]),
40
- Commands::FinallyCommand.new(options[:finally]))
36
+ optional_commands = Commands.create_commands_for options
37
+ create_method(attribute, Commands::ViaCommand.new(options[:via] || attribute), optional_commands)
41
38
  end
42
39
 
43
40
  def define_access_methods_for(attributes)
@@ -47,10 +44,10 @@ module LazyDoc
47
44
 
48
45
  end
49
46
 
50
- def create_method(attribute, required_command, *optional_commands)
47
+ def create_method(attribute, via_command, optional_commands = [])
51
48
  define_method attribute do
52
49
  memoizer.memoize attribute do
53
- value = required_command.execute(embedded_doc)
50
+ value = via_command.execute(embedded_doc)
54
51
 
55
52
  optional_commands.inject(value) do |final_value, command|
56
53
  final_value = command.execute(final_value)
@@ -1,3 +1,3 @@
1
1
  module LazyDoc
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -4,7 +4,7 @@ describe 'basic behavior with a simple JSON document' do
4
4
  class Friends
5
5
  include LazyDoc::DSL
6
6
 
7
- access :best_friend, via: :bestFriend
7
+ access :best_friend
8
8
  access :lover
9
9
 
10
10
  def initialize(json)
@@ -12,18 +12,29 @@ describe 'basic behavior with a simple JSON document' do
12
12
  end
13
13
  end
14
14
 
15
+ class Accomplishment
16
+ include LazyDoc::DSL
17
+
18
+ access :description
19
+
20
+ def initialize(json)
21
+ lazily_embed(json)
22
+ end
23
+ end
24
+
15
25
  class User
16
26
  include LazyDoc::DSL
17
27
 
18
28
  access :name
19
29
  access :phone, :zip
20
30
  access :home_town
21
- access :address, via: :streetAddress
31
+ access :street_address
22
32
  access :job_title, via: [:profile, :occupation, :title]
23
33
  access :born_on, via: [:profile, :bornOn], finally: lambda { |born_on| born_on.to_i }
24
34
  access :friends, as: Friends
25
35
  access :father, default: 'Chuck Palahniuk'
26
36
  access :fight_club_rules, via: [:fightClub, :rules], extract: :title
37
+ access :accomplishments, as: Accomplishment
27
38
 
28
39
  def initialize(json)
29
40
  lazily_embed(json)
@@ -38,7 +49,7 @@ describe 'basic behavior with a simple JSON document' do
38
49
  its(:name) { should == 'Tyler Durden' }
39
50
  its(:phone) { should == '288-555-0153' }
40
51
  its(:zip) { should == '00000' }
41
- its(:address) { should == 'Paper Street' }
52
+ its(:street_address) { should == 'Paper Street' }
42
53
  its(:job_title) { should == 'Soap Maker' }
43
54
  its(:born_on) { should == 1999 }
44
55
  specify { expect { user.home_town }.to raise_error(LazyDoc::AttributeNotFoundError) }
@@ -54,4 +65,12 @@ describe 'basic behavior with a simple JSON document' do
54
65
  its(:fight_club_rules) { should == ['You do not talk about Fight Club',
55
66
  'You DO NOT talk about Fight Club',
56
67
  'If someone says stop or goes limp, taps out the fight is over'] }
68
+
69
+ context 'accomplishments' do
70
+ let(:accomplishments) { user.accomplishments }
71
+
72
+ specify { expect(accomplishments[0].description).to eq('Sold a lot of soap') }
73
+ specify { expect(accomplishments[1].description).to eq('Started fight club with himself') }
74
+ specify { expect(accomplishments[2].description).to eq('Blew up a bunch of credit card companies') }
75
+ end
57
76
  end
@@ -21,5 +21,10 @@
21
21
  {"number": 2, "title": "You DO NOT talk about Fight Club"},
22
22
  {"number": 3, "title": "If someone says stop or goes limp, taps out the fight is over"}
23
23
  ]
24
- }
24
+ },
25
+ "accomplishments": [
26
+ {"description": "Sold a lot of soap"},
27
+ {"description": "Started fight club with himself"},
28
+ {"description": "Blew up a bunch of credit card companies"}
29
+ ]
25
30
  }
@@ -0,0 +1,21 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ module LazyDoc
4
+ describe CamelizableString do
5
+ describe '#camelize' do
6
+ it 'converts a string from snake_case to camelCase' do
7
+ camelized_string = CamelizableString.new('snake_case').camelize
8
+
9
+ expect(camelized_string).to eq('snakeCase')
10
+ end
11
+
12
+ it 'has no effect on a string with no underscores' do
13
+ camelized_string = CamelizableString.new('snakecase').camelize
14
+
15
+ expect(camelized_string).to eq('snakecase')
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -3,8 +3,7 @@ require_relative '../../../spec_helper'
3
3
  module LazyDoc
4
4
  describe Commands::AsClassCommand do
5
5
  class Foo
6
- def initialize(value)
7
- end
6
+ def initialize(value) end
8
7
  end
9
8
 
10
9
  let(:value) { {foo: 'bar'} }
@@ -38,5 +37,19 @@ module LazyDoc
38
37
 
39
38
  as_class_command.execute(value)
40
39
  end
40
+
41
+ context 'when the value being sent to the AsClassCommand is an array' do
42
+ let(:value) { [{foo: 'bar'}, {foo: 'baz'}] }
43
+
44
+ it 'returns an array of objects of the specified class' do
45
+ as_class_command = Commands::AsClassCommand.new(Foo)
46
+
47
+ as_class_value = as_class_command.execute(value)
48
+
49
+ expect(as_class_value).to be_an Array
50
+ expect(as_class_value[0]).to be_a Foo
51
+ expect(as_class_value[1]).to be_a Foo
52
+ end
53
+ end
41
54
  end
42
55
  end
@@ -32,5 +32,14 @@ module LazyDoc
32
32
 
33
33
  expect { via.execute(document) }.to raise_error(AttributeNotFoundError)
34
34
  end
35
+
36
+ it 'finds the attribute when specified as snake_case but is found in camelCase' do
37
+ document = {'helloWorld' => 'foobar'}
38
+ via = Commands::ViaCommand.new(:hello_world)
39
+
40
+ final_value = via.execute(document)
41
+
42
+ expect(final_value).to eq('foobar')
43
+ end
35
44
  end
36
45
  end
@@ -0,0 +1,48 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ module LazyDoc
4
+ describe Commands do
5
+ describe '#create_commands_for' do
6
+ class FooCommand
7
+ def initialize(_) end
8
+ end
9
+ class BarCommand
10
+ def initialize(_) end
11
+ end
12
+
13
+ before(:all) do
14
+ @optional_command_classes = Commands::OPTIONAL_COMMAND_CLASSES.dup
15
+ Commands::OPTIONAL_COMMAND_CLASSES = {foo: FooCommand, bar: BarCommand}
16
+ end
17
+
18
+ after(:all) do
19
+ Commands::OPTIONAL_COMMAND_CLASSES = @optional_command_classes
20
+ end
21
+
22
+ let(:initialization_value) { 'initialization value' }
23
+
24
+ it 'creates a command object for the specified option' do
25
+ options = {foo: initialization_value}
26
+ commands = Commands.create_commands_for(options)
27
+
28
+ expect(commands[0]).to be_a FooCommand
29
+ end
30
+
31
+ it 'creates a command object for multiple options' do
32
+ options = {foo: initialization_value, bar: initialization_value}
33
+ commands = Commands.create_commands_for(options)
34
+
35
+ expect(commands[0]).to be_a FooCommand
36
+ expect(commands[1]).to be_a BarCommand
37
+ end
38
+
39
+ it 'ignores options for which it does not have a matching command' do
40
+ options = {unknown: initialization_value}
41
+ commands = Commands.create_commands_for(options)
42
+
43
+ expect(commands).to be_empty
44
+ end
45
+ end
46
+ end
47
+
48
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lazy_doc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Oglesby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-14 00:00:00.000000000 Z
11
+ date: 2013-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -58,6 +58,7 @@ files:
58
58
  - lazy_doc.gemspec
59
59
  - lib/lazy_doc.rb
60
60
  - lib/lazy_doc/attribute_not_found_error.rb
61
+ - lib/lazy_doc/camelizable_string.rb
61
62
  - lib/lazy_doc/commands.rb
62
63
  - lib/lazy_doc/commands/as_class_command.rb
63
64
  - lib/lazy_doc/commands/default_value_command.rb
@@ -69,11 +70,13 @@ files:
69
70
  - lib/lazy_doc/version.rb
70
71
  - spec/acceptance/basic_behavior_spec.rb
71
72
  - spec/acceptance/support/user.json
73
+ - spec/lib/lazy_doc/camelizable_string_spec.rb
72
74
  - spec/lib/lazy_doc/commands/as_class_command_spec.rb
73
75
  - spec/lib/lazy_doc/commands/default_value_command_spec.rb
74
76
  - spec/lib/lazy_doc/commands/extract_command_spec.rb
75
77
  - spec/lib/lazy_doc/commands/finally_command_spec.rb
76
78
  - spec/lib/lazy_doc/commands/via_command_spec.rb
79
+ - spec/lib/lazy_doc/commands_spec.rb
77
80
  - spec/lib/lazy_doc/dsl_spec.rb
78
81
  - spec/lib/lazy_doc/memoizer_spec.rb
79
82
  - spec/spec_helper.rb
@@ -105,11 +108,13 @@ summary: An implementation of the Embedded Document pattern for POROs
105
108
  test_files:
106
109
  - spec/acceptance/basic_behavior_spec.rb
107
110
  - spec/acceptance/support/user.json
111
+ - spec/lib/lazy_doc/camelizable_string_spec.rb
108
112
  - spec/lib/lazy_doc/commands/as_class_command_spec.rb
109
113
  - spec/lib/lazy_doc/commands/default_value_command_spec.rb
110
114
  - spec/lib/lazy_doc/commands/extract_command_spec.rb
111
115
  - spec/lib/lazy_doc/commands/finally_command_spec.rb
112
116
  - spec/lib/lazy_doc/commands/via_command_spec.rb
117
+ - spec/lib/lazy_doc/commands_spec.rb
113
118
  - spec/lib/lazy_doc/dsl_spec.rb
114
119
  - spec/lib/lazy_doc/memoizer_spec.rb
115
120
  - spec/spec_helper.rb