whoopee-cushion 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ada589c5e9a9f9ff5bca6dbed49f5e8f217bb47
4
- data.tar.gz: 80775f1deabb6de9a20c62c2030e12c12ea86921
3
+ metadata.gz: 511989dd2912ff76496a7633ed8b3879d25550f9
4
+ data.tar.gz: 48e85a251bd17590807ec59f986da00507d70eef
5
5
  SHA512:
6
- metadata.gz: e41b72652029b3f0268331977f4f7fa21f27e51163d7246dfa46bbcbc00293378d9f46675d3d522316566f07a5e65e98b46250be230f833a974acc85130117b9
7
- data.tar.gz: 96694182f4b57a80e7bae615b5ebb23e098e3633d3dada28b0dce765259c5c459fef9c2acfabaf64f4eabd2a4a47d40ae3e185f9849626d1c6bec127e68be2ef
6
+ metadata.gz: 8b0501be20f64d23f1ad6e0e3580f8230f9ca4af9b33acfddbdf55f5e63ed341d1e0b1598b0d638e6c6933d07be46244ef80d20b13bd7009cb7e45b7872d910c
7
+ data.tar.gz: 2f87403c437fc9d363b1a4bc7c3e4bc4505dadcf3e4f3195322f6a1f5eea20ea89336dd5321e984e70d71a256e79b4f4d75391f8d8c33cf61385fdfcffa789ff
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- whoopee-cushion (0.1.0)
4
+ whoopee-cushion (1.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -12,40 +12,70 @@ Wouldn't it be nice if you could access all your API response data like this?
12
12
 
13
13
  `obj.products.first.customer.customer_id`
14
14
 
15
- whoopee-cushion will let you do just that. It's faster than using OpenStructs or any recursive algorithms based on them
15
+ whoopee-cushion will let you do just that. It's faster than using OpenStructs and any recursive algorithms based on them
16
16
  because it uses Ruby's faster Struct objects under the hood.
17
17
 
18
18
  Setup
19
19
  =====
20
20
 
21
- `gem install whoopee-cushion`
21
+ `
22
+ gem install whoopee-cushion
23
+ `
22
24
 
23
25
  or
24
26
 
25
- `gem "whoopee-cushion"`
27
+ `
28
+ gem "whoopee-cushion"
29
+ `
26
30
 
27
31
  in your Gemfile.
28
32
 
29
33
  In your Ruby code:
30
34
 
31
- `require 'whoopee_cushion'`
35
+ `
36
+ require 'whoopee_cushion'
37
+ `
32
38
 
33
39
  then
34
40
 
35
- `hash = {:a => 1, :CamelCase => 2, :c => 3, :d => { :e => 4, :f => [1,2,3,4,5]}}`
41
+ `
42
+ hash = {:a => 1, :CamelCase => 2, :c => 3, :d => { :e => 4, :f => [1,2,3,4,5]}}
36
43
 
37
- `obj = WhoopeeCushion::Inflate.from_hash(hash)`
44
+ obj = WhoopeeCushion::Inflate.from_hash(hash)
38
45
 
39
- `puts obj.a`
40
- `puts obj.camel_case`
41
- `puts obj.d.f.first`
42
-
43
- `json = '{"CamelCase": "no", "json": "yes"}'`
46
+ puts obj.a
47
+ puts obj.camel_case
48
+ puts obj.d.f.first
49
+ `
44
50
 
45
51
  You can also go straight from JSON, or turn off the automatic camel case conversion:
46
52
 
47
- `obj = WhoopeeCushion::Inflate.from_json(json, :to_snake_keys => false)`
53
+ `
54
+ json = '{"CamelCase": "no", "json": "yes"}'
55
+
56
+ obj = WhoopeeCushion::Inflate.from_json(json, :convert_keys => false)
57
+
58
+ puts obj.CamelCase
59
+ `
60
+
61
+ If you want to carry out your own string conversion, use a lambda:
62
+
63
+ `
64
+ hash = {:a => 1, :CamelCase => 2, :c => 3, :d => { :e => 4, :f => [1,2,3,4,5]}}
65
+
66
+ obj = WhoopeeCushion::Inflate.from_hash(hash, :convert_keys => lambda {|s| '#{s}_foo'})
67
+
68
+ puts obj.a_foo
69
+ puts obj.CamelCase_foo
70
+ puts obj.d_foo.f_foo.first
71
+ `
72
+
73
+ Performance
74
+ ===========
48
75
 
49
- `puts obj.CamelCase`
76
+ Check the project out, bundle it and run the simple `rake benchmark` suite to see some figures. Comparisons are made
77
+ against the recursive-open-struct gem and simple OpenStruct creates. The whoopee-cushion gem performs very well against
78
+ both when not converting strings to snake case (quite an expensive operation, using a stripped-down version of the
79
+ Rails 'underscore' method.) When converting strings the performance increase is diminished, but it still comes out well.
50
80
 
51
- Have fun.
81
+ If you can increase performance (or otherwise improve the gem in any way) please fork it and issue a pull request.
data/Rakefile CHANGED
@@ -1,8 +1,16 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ currdir = File.dirname(__FILE__)
3
+ require currdir+ '/test/benchmarks'
2
4
 
3
5
  require 'rake/testtask'
4
6
 
5
7
  Rake::TestTask.new do |t|
6
8
  t.libs << 'test'
7
9
  t.pattern = "test/*_test.rb"
10
+ end
11
+
12
+
13
+ desc 'Run the benchmarks'
14
+ task :benchmark do
15
+ benchmarks
8
16
  end
@@ -26,42 +26,31 @@ module WhoopeeCushion
26
26
  end
27
27
 
28
28
  def self.from_hash(hash, options = {})
29
- hash = process_hash hash, options
30
- keys = hash.keys
31
- model = Struct.new(*keys)
32
- out = model.new
33
- hash.each do |key, value|
34
- out.send("#{key}=", self.from_object(value, options))
35
- end
36
- out
29
+ @iter ||= 1
30
+ keys, values = process_hash hash, options
31
+ Struct.new(*keys).new(*values)
37
32
  end
38
33
 
39
34
  private
40
35
 
41
36
  def self.process_hash hash, options
42
- remap = hash.map do |key, value|
43
- key = underscore_key key unless options[:to_snake_keys] == false
44
- [key.to_sym, value]
37
+ keys = []
38
+ values = []
39
+ hash.each do |k,v|
40
+ keys << (options[:convert_keys] == false ? k : underscore_key(k, options)).to_sym
41
+ values << from_object(v, options)
45
42
  end
46
- Hash[remap]
43
+ # Split the keys and values to arrays for 1: speed and 2: backwards compatibility with Ruby < 1.9
44
+ # where hashes are unordered
45
+ [keys, values]
47
46
  end
48
47
 
49
- def self.underscore_key(key)
50
- if key.is_a? Symbol
51
- underscore(key.to_s)
52
- elsif key.is_a? String
53
- underscore(key)
54
- else
55
- key
56
- end
57
- end
48
+ def self.underscore_key(string, options)
49
+ return options[:convert_keys].call(string) if options[:convert_keys]
58
50
 
59
- def self.underscore(string)
60
- string.gsub(/::/, '/').
61
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
62
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
63
- tr("-", "_").
64
- downcase
51
+ string.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
52
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
53
+ downcase
65
54
  end
66
55
  end
67
56
  end
@@ -1,3 +1,3 @@
1
1
  module WhoopeeCushion
2
- VERSION = "0.1.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -0,0 +1,72 @@
1
+ require 'whoopee_cushion'
2
+ require 'byebug'
3
+ require 'benchmark'
4
+ require 'recursive-open-struct'
5
+
6
+ def benchmarks
7
+ puts "Benchmarking 10000 operations on deep hash:"
8
+
9
+ hash = {:aaaaBbbb => 'ccccDDDD',
10
+ :a => 2, :b => 2, :c => 2, :d => 2, :e => 2,
11
+ :f => 2, :g => 2, :h => 2, :i => 2, :j => 2,
12
+ :k => 2, :l => 2, :m => 2, :n => 2, :o => 2,
13
+ :p => 2, :q => 2, :r => 2, :s => 2, :t => 2,
14
+ 'eeeeEeee' =>[{"NameThe1" => {"CamelName" => 4444},
15
+ "NameThe3" => [4,5,6]}, "3", "4"]}
16
+ puts "whoopee-cushion"
17
+ puts Benchmark.measure {
18
+ 10000.times do
19
+ a = WhoopeeCushion::Inflate.from_hash hash, :convert_keys => false
20
+ raise 'Incorrect value found' if a.eeeeEeee.first.NameThe3[0] != 4
21
+ end
22
+ }
23
+
24
+ puts "whoopee-cushion with camel to snake case conversion"
25
+ puts Benchmark.measure {
26
+ 10000.times do
27
+ a = WhoopeeCushion::Inflate.from_hash hash
28
+ raise 'Incorrect value found' if a.eeee_eeee.first.name_the3[0] != 4
29
+ end
30
+ }
31
+
32
+ puts 'recursive-open-struct gem for comparison'
33
+ puts Benchmark.measure {
34
+ 10000.times do
35
+ a = RecursiveOpenStruct.new hash, :recurse_over_arrays => true
36
+ raise 'Incorrect value found' if a.eeeeEeee.first.NameThe3[0] != 4
37
+ end
38
+ }
39
+
40
+
41
+
42
+ puts "Benchmarking 10000 operations on light hash:"
43
+
44
+ hash = {:a => 2, :b => 2, :c => 2, :d => 2, :e => 2,
45
+ :f => 2, :g => 2, :h => 2, :i => 2, :j => 2,
46
+ :k => 2, :l => 2, :m => 2, :n => 2, :c1 => "Lorem Ipsum"}
47
+
48
+
49
+ puts Benchmark.measure {
50
+ 10000.times do
51
+ x = WhoopeeCushion::Inflate.from_hash hash, :convert_keys => false
52
+ x.c1
53
+ end
54
+ }
55
+
56
+ puts "Benchmarking 10000 operations on light hash with camel case conversion:"
57
+ puts Benchmark.measure {
58
+ 10000.times do
59
+ x = WhoopeeCushion::Inflate.from_hash hash
60
+ x.c1
61
+ end
62
+ }
63
+
64
+ puts "Benchmarking 10000 OpenStruct creates"
65
+
66
+ puts Benchmark.measure {
67
+ 10000.times do
68
+ x = OpenStruct.new(hash)
69
+ x.c1
70
+ end
71
+ }
72
+ end
data/test/inflate_test.rb CHANGED
@@ -19,7 +19,7 @@ end
19
19
 
20
20
  describe 'converting keys to snake case' do
21
21
  before do
22
- @json = { 'CaseOne' => 'FirstCase', 'caseTwo' => 'secondCase', 'case_three' => 'third_case' }
22
+ @json = { 'CaseOne' => 'FirstCase', 'caseTwo' => 'secondCase', 'case_three' => 'third_case', 'CASEFour' => '4' }
23
23
  end
24
24
 
25
25
  it 'should convert CamelCase' do
@@ -32,18 +32,23 @@ describe 'converting keys to snake case' do
32
32
  assert_equal 'secondCase', obj.case_two
33
33
  end
34
34
 
35
+ it 'should convert CAMELCase with acronyms' do
36
+ obj = WhoopeeCushion::Inflate.from_hash @json
37
+ assert_equal '4', obj.case_four, "Could not find case_four: #{obj.inspect}"
38
+ end
39
+
35
40
  it 'should not convert camel case with snake keys option false' do
36
- obj = WhoopeeCushion::Inflate.from_hash @json, :to_snake_keys => false
41
+ obj = WhoopeeCushion::Inflate.from_hash @json, :convert_keys => false
37
42
  assert_equal 'FirstCase', obj.CaseOne
38
43
  end
39
44
 
40
45
  it 'should not convert camel back with snake keys option false' do
41
- obj = WhoopeeCushion::Inflate.from_hash @json, :to_snake_keys => false
46
+ obj = WhoopeeCushion::Inflate.from_hash @json, :convert_keys => false
42
47
  assert_equal 'secondCase', obj.caseTwo
43
48
  end
44
49
 
45
50
  it 'should leave snake case alone with snake keys option false' do
46
- obj = WhoopeeCushion::Inflate.from_hash @json, :to_snake_keys => false
51
+ obj = WhoopeeCushion::Inflate.from_hash @json, :convert_keys => false
47
52
  assert_equal 'third_case', obj.case_three
48
53
  end
49
54
 
@@ -64,7 +69,7 @@ describe 'converting recursive hashes' do
64
69
  end
65
70
 
66
71
  it 'should not convert keys to snake case with snake keys option false' do
67
- obj = WhoopeeCushion::Inflate.from_hash @json, :to_snake_keys => false
72
+ obj = WhoopeeCushion::Inflate.from_hash @json, :convert_keys => false
68
73
  assert_equal 'value', obj.CaseOne.caseTwo.ThisIsCaseThree
69
74
  end
70
75
  end
@@ -82,7 +87,7 @@ describe 'converting deep arrays' do
82
87
  end
83
88
 
84
89
  it 'should get deep array values correctly with snake keys option false' do
85
- obj = WhoopeeCushion::Inflate.from_hash @json, :to_snake_keys => false
90
+ obj = WhoopeeCushion::Inflate.from_hash @json, :convert_keys => false
86
91
  assert_equal 2, obj.CaseOne[0].caseTwo
87
92
  assert_equal 'four', obj.CaseOne[0].CaseThree[0].CaseFour
88
93
  assert_equal 5, obj.CaseOne[0].CaseThree[1]
@@ -113,8 +118,17 @@ describe 'converting from array' do
113
118
  end
114
119
 
115
120
  it 'should convert an embedded hash without changing keys with snake keys option false' do
116
- obj = WhoopeeCushion::Inflate.from_array @array, :to_snake_keys => false
121
+ obj = WhoopeeCushion::Inflate.from_array @array, :convert_keys => false
117
122
  assert_equal 'now', obj[4].ThePeople
118
123
  end
119
124
  end
125
+ end
126
+
127
+ describe 'converting keys' do
128
+ it 'should use the lambda if possible' do
129
+ hash = {'power' => 'to', 'the_people' => 'now', 'bar' => {'interesting' => 'times'}}
130
+ obj = WhoopeeCushion::Inflate.from_hash hash, :convert_keys => lambda {|s| "#{s}_foo"}
131
+ assert_equal 'to', obj.power_foo
132
+ assert_equal 'times', obj.bar_foo.interesting_foo
133
+ end
120
134
  end
data/test/test_helper.rb CHANGED
@@ -3,52 +3,3 @@ require 'minitest/unit'
3
3
  require 'minitest/autorun'
4
4
  require 'minitest/pride'
5
5
  require 'byebug'
6
- require 'benchmark'
7
- require 'recursive-open-struct'
8
-
9
- puts "Benchmarking 10000 operations on deep hash:"
10
-
11
- hash = {:aaaaBbbb => 'ccccDDDD',
12
- :a => 2, :b => 2, :c => 2, :d => 2, :e => 2,
13
- :f => 2, :g => 2, :h => 2, :i => 2, :j => 2,
14
- :k => 2, :l => 2, :m => 2, :n => 2,
15
- 'eeeeEeee' =>[{"splandact" => {"Griffin" => 4444},
16
- "splortitude" => [4,5,6]}, "3", "4"]}
17
- puts "whoopee-cushion"
18
- puts Benchmark.measure {
19
- 10000.times do
20
- a = WhoopeeCushion::Inflate.from_hash hash, :to_snake_keys => false
21
- raise 'Incorrect value found' if a.eeeeEeee.first.splortitude[0] != 4
22
- end
23
- }
24
- puts 'recursive-open-struct'
25
-
26
- puts Benchmark.measure {
27
- 10000.times do
28
- a = RecursiveOpenStruct.new hash, :recurse_over_arrays => true
29
- raise 'Incorrect value found' if a.eeeeEeee.first.splortitude[0] != 4
30
- end
31
- }
32
-
33
-
34
-
35
- puts "Benchmarking 10000 operations on light hash:"
36
-
37
- hash = {:a => 2, :b => 2, :c => 2, :d => 2, :e => 2,
38
- :f => 2, :g => 2, :h => 2, :i => 2, :j => 2,
39
- :k => 2, :l => 2, :m => 2, :n => 2, :c => "Lorem Ipsum"}
40
-
41
-
42
- puts Benchmark.measure {
43
- 10000.times do
44
- WhoopeeCushion::Inflate.from_hash hash, :to_snake_keys => false
45
- end
46
- }
47
-
48
- puts "Benchmarking 10000 OpenStruct creates"
49
-
50
- puts Benchmark.measure {
51
- 10000.times do
52
- x = OpenStruct.new(hash)
53
- end
54
- }
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["ben@chemica.co.uk"]
11
11
  spec.summary = %q{Allow recursive inflation of JSON data into structs.}
12
12
  spec.description = %q{Inflates JSON data recursively into structs to allow use of dot notation for data access.}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/chemica/whoopee-cushion?source=c"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whoopee-cushion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Dunkley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-21 00:00:00.000000000 Z
11
+ date: 2014-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -97,10 +97,11 @@ files:
97
97
  - Rakefile
98
98
  - lib/whoopee_cushion.rb
99
99
  - lib/whoopee_cushion/version.rb
100
+ - test/benchmarks.rb
100
101
  - test/inflate_test.rb
101
102
  - test/test_helper.rb
102
103
  - whoopee_cushion.gemspec
103
- homepage: ''
104
+ homepage: https://github.com/chemica/whoopee-cushion?source=c
104
105
  licenses:
105
106
  - MIT
106
107
  metadata: {}
@@ -125,5 +126,6 @@ signing_key:
125
126
  specification_version: 4
126
127
  summary: Allow recursive inflation of JSON data into structs.
127
128
  test_files:
129
+ - test/benchmarks.rb
128
130
  - test/inflate_test.rb
129
131
  - test/test_helper.rb