lazy_doc 0.1.0 → 0.2.1
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 +8 -8
- data/README.md +3 -3
- data/lib/lazy_doc.rb +1 -0
- data/lib/lazy_doc/attribute_not_found_error.rb +1 -1
- data/lib/lazy_doc/camelizable_string.rb +15 -0
- data/lib/lazy_doc/commands.rb +18 -0
- data/lib/lazy_doc/commands/as_class_command.rb +10 -1
- data/lib/lazy_doc/commands/via_command.rb +18 -5
- data/lib/lazy_doc/dsl.rb +4 -7
- data/lib/lazy_doc/version.rb +1 -1
- data/spec/acceptance/basic_behavior_spec.rb +22 -3
- data/spec/acceptance/support/user.json +6 -1
- data/spec/lib/lazy_doc/camelizable_string_spec.rb +21 -0
- data/spec/lib/lazy_doc/commands/as_class_command_spec.rb +15 -2
- data/spec/lib/lazy_doc/commands/via_command_spec.rb +9 -0
- data/spec/lib/lazy_doc/commands_spec.rb +48 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OGMxMGUwZTdmMDk4OGUyZGRhMTliNTI3NmUzM2RjZDMwYjY0ODM3Yg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MTNhYWFlY2MzOTQ0YWFmNDYyZTMxZTBkMDI0Mjk3YmVjMjg2YWFkZg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTJjMjgwZmYyZTA5ZWIxNWFmODBiMWUwZGNjZTM3ZGNiMDFlYzRhOTI4ZmE2
|
10
|
+
MjFiZWFhZWI2YmI5YzZmOTlmNWMwNmQwODg2M2MxNDgzYzM1ODBkYjJhZDlm
|
11
|
+
MTNmMjkzMGIyNWY5MzY3MTgzYWI1YmZkZDc2ZDMzZmQwMWMxODQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
data/lib/lazy_doc.rb
CHANGED
data/lib/lazy_doc/commands.rb
CHANGED
@@ -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?
|
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 |
|
11
|
-
|
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
|
-
|
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
|
data/lib/lazy_doc/dsl.rb
CHANGED
@@ -33,11 +33,8 @@ module LazyDoc
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def define_access_method_for(attribute, options)
|
36
|
-
|
37
|
-
|
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,
|
47
|
+
def create_method(attribute, via_command, optional_commands = [])
|
51
48
|
define_method attribute do
|
52
49
|
memoizer.memoize attribute do
|
53
|
-
value =
|
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)
|
data/lib/lazy_doc/version.rb
CHANGED
@@ -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
|
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 :
|
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(:
|
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
|
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-
|
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
|