awrence 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "minitest", ">= 0"
10
+ gem "yard", "~> 0.7"
11
+ gem "rdoc", "~> 3.12"
12
+ gem "bundler"
13
+ gem "jeweler", "~> 1.8.4"
14
+ end
@@ -0,0 +1,25 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.8.4)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rdoc
10
+ json (1.7.7)
11
+ minitest (4.7.0)
12
+ rake (10.0.3)
13
+ rdoc (3.12.2)
14
+ json (~> 1.4)
15
+ yard (0.8.5.2)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ bundler
22
+ jeweler (~> 1.8.4)
23
+ minitest
24
+ rdoc (~> 3.12)
25
+ yard (~> 0.7)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Dave Hrycyszyn
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ =======
2
+ awrence
3
+ ========
4
+
5
+ Have you ever needed to automatically convert Rubyish `snake_case` to JSON-style `camelBack` or `CamelCase` hash keys?
6
+
7
+ Awrence to the rescue.
8
+
9
+ This gem recursively converts all snake_case keys in a hash structure to camelBack or CamelCase.
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ my_hash = {"first_key" => 1, "foo_bars" => [{"baz_baz" => "value"}, {"blah_blah" => "value"}]}
15
+ camel_hash = my_hash.to_camel_keys
16
+ # => {"firstKey" => 1, "fooBars" => [{"bazBaz" => "value"}, {"blahBlah" => "value"}]}
17
+ ```
18
+
19
+ Awrence works on either string keys or symbolized keys. It has no dependencies, as it has its own `camelize` method lifted out of ActiveSupport.
20
+
21
+ ## Limitations
22
+
23
+ * Your keys must be camelBack or CamelCase. The key "Foo Bar" will output as "foo bar".
24
+ * Unlike the original T.E. Lawrence, the awrence gem is non-destructive. There is no Hash#to_camel_keys! form.
25
+
26
+ ## Contributing to awrence
27
+
28
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
29
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
30
+ * Fork the project.
31
+ * Start a feature/bugfix branch.
32
+ * Commit and push until you are happy with your contribution.
33
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
34
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
35
+
36
+ == Copyright
37
+
38
+ Copyright (c) 2013 Dave Hrycyszyn. See LICENSE.txt for
39
+ further details.
40
+
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "awrence"
18
+ gem.homepage = "http://github.com/futurechimp/awrence"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Camelize your snake keys when working with JSON APIs}
21
+ gem.description = %Q{Have you ever needed to automatically convert Ruby-style
22
+ snake_case to CamelCase or camelBack hash keys?
23
+
24
+ Awrence to the rescue.
25
+
26
+ This gem recursively converts all snake_case keys in a hash
27
+ structure to camelBack. }
28
+ gem.email = "dave.hrycyszyn@headlondon.com"
29
+ gem.authors = ["Dave Hrycyszyn"]
30
+ # dependencies defined in Gemfile
31
+ end
32
+ Jeweler::RubygemsDotOrgTasks.new
33
+
34
+ require 'rake/testtask'
35
+ Rake::TestTask.new(:test) do |test|
36
+ test.libs << 'lib' << 'test'
37
+ test.pattern = 'test/**/test_*.rb'
38
+ test.verbose = true
39
+ end
40
+
41
+ task :default => :test
42
+
43
+ require 'yard'
44
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,64 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "awrence"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Dave Hrycyszyn"]
12
+ s.date = "2013-03-19"
13
+ s.description = "Have you ever needed to automatically convert Ruby-style\n snake_case to CamelCase or camelBack hash keys?\n\n Awrence to the rescue.\n\n This gem recursively converts all snake_case keys in a hash\n structure to camelBack. "
14
+ s.email = "dave.hrycyszyn@headlondon.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.md",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "awrence.gemspec",
28
+ "lib/awrence.rb",
29
+ "lib/awrence/ext/hash/to_camel_keys.rb",
30
+ "test/awrence/ext/hash/to_camel_keys_test.rb",
31
+ "test/helper.rb",
32
+ "test/test_awrence.rb"
33
+ ]
34
+ s.homepage = "http://github.com/futurechimp/awrence"
35
+ s.licenses = ["MIT"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = "1.8.17"
38
+ s.summary = "Camelize your snake keys when working with JSON APIs"
39
+
40
+ if s.respond_to? :specification_version then
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_development_dependency(%q<minitest>, [">= 0"])
45
+ s.add_development_dependency(%q<yard>, ["~> 0.7"])
46
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
47
+ s.add_development_dependency(%q<bundler>, [">= 0"])
48
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
49
+ else
50
+ s.add_dependency(%q<minitest>, [">= 0"])
51
+ s.add_dependency(%q<yard>, ["~> 0.7"])
52
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
53
+ s.add_dependency(%q<bundler>, [">= 0"])
54
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<minitest>, [">= 0"])
58
+ s.add_dependency(%q<yard>, ["~> 0.7"])
59
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
60
+ s.add_dependency(%q<bundler>, [">= 0"])
61
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
62
+ end
63
+ end
64
+
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/awrence/ext/hash/to_camel_keys'
@@ -0,0 +1,51 @@
1
+ class Hash
2
+
3
+ # Recursively converts Rubyish snake_case hash keys to camelBack JSON-style
4
+ # hash keys suitable for use with a JSON API.
5
+ #
6
+ def to_camelback_keys(value = self)
7
+ case value
8
+ when Array
9
+ value.map { |v| to_camelback_keys(v) }
10
+ when Hash
11
+ Hash[value.map { |k, v| [camelize_key(k, false), to_camelback_keys(v)] }]
12
+ else
13
+ value
14
+ end
15
+ end
16
+
17
+ # Recursively converts Rubyish snake_case hash keys to CamelCase JSON-style
18
+ # hash keys suitable for use with a JSON API.
19
+ #
20
+ def to_camel_keys(value = self)
21
+ case value
22
+ when Array
23
+ value.map { |v| to_camel_keys(v) }
24
+ when Hash
25
+ Hash[value.map { |k, v| [camelize_key(k), to_camel_keys(v)] }]
26
+ else
27
+ value
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def camelize_key(k, first_upper = true)
34
+ if k.is_a? Symbol
35
+ camelize(k.to_s, first_upper).to_sym
36
+ elsif k.is_a? String
37
+ camelize(k, first_upper)
38
+ else
39
+ k # Awrence can't camelize anything except strings and symbols
40
+ end
41
+ end
42
+
43
+ def camelize(snake_word, first_upper = true)
44
+ if first_upper
45
+ snake_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
46
+ else
47
+ snake_word.chars.first + camelize(snake_word)[1..-1]
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,157 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../test_awrence.rb')
2
+
3
+ describe "A Hash" do
4
+ describe "with snake keys" do
5
+ describe "which are JSON-style strings" do
6
+ describe "in the simplest case" do
7
+ before do
8
+ @hash = { "first_key" => "fooBar" }
9
+ end
10
+
11
+ describe "non-destructive conversion to CamelCase" do
12
+ before do
13
+ @camelized = @hash.to_camel_keys
14
+ end
15
+
16
+ it "camelizes the key" do
17
+ assert_equal("FirstKey", @camelized.keys.first)
18
+ end
19
+
20
+ it "leaves the key as a string" do
21
+ assert @camelized.keys.first.is_a? String
22
+ end
23
+
24
+ it "leaves the value untouched" do
25
+ assert_equal(@camelized.values.first, "fooBar")
26
+ end
27
+
28
+ it "leaves the original hash untouched" do
29
+ assert_equal(@hash.keys.first, "first_key")
30
+ end
31
+ end
32
+
33
+ describe "non-destructive conversion to camelBack" do
34
+ before do
35
+ @camelized = @hash.to_camelback_keys
36
+ end
37
+
38
+ it "camelizes the key" do
39
+ assert_equal("firstKey", @camelized.keys.first)
40
+ end
41
+
42
+ it "leaves the key as a string" do
43
+ assert @camelized.keys.first.is_a? String
44
+ end
45
+
46
+ it "leaves the value untouched" do
47
+ assert_equal(@camelized.values.first, "fooBar")
48
+ end
49
+
50
+ it "leaves the original hash untouched" do
51
+ assert_equal(@hash.keys.first, "first_key")
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "containing an array of other hashes" do
57
+ before do
58
+ @hash = {
59
+ "apple_type" => "Granny Smith",
60
+ "vegetable_types" => [
61
+ {"potato_type" => "Golden delicious"},
62
+ {"other_tuber_type" => "peanut"},
63
+ {"peanut_names_and_spouses" => [
64
+ {"bill_the_peanut" => "sally_peanut"}, {"sammy_the_peanut" => "jill_peanut"}
65
+ ]}
66
+ ]}
67
+ end
68
+
69
+ describe "non-destructive conversion to CamelCase" do
70
+ before do
71
+ @camelized = @hash.to_camel_keys
72
+ end
73
+
74
+ it "recursively camelizes the keys on the top level of the hash" do
75
+ assert @camelized.keys.include?("AppleType")
76
+ assert @camelized.keys.include?("VegetableTypes")
77
+ end
78
+
79
+ it "leaves the values on the top level alone" do
80
+ assert_equal(@camelized["AppleType"], "Granny Smith")
81
+ end
82
+
83
+ it "converts second-level keys" do
84
+ assert @camelized["VegetableTypes"].first.has_key? "PotatoType"
85
+ end
86
+
87
+ it "leaves second-level values alone" do
88
+ assert @camelized["VegetableTypes"].first.has_value? "Golden delicious"
89
+ end
90
+
91
+ it "converts third-level keys" do
92
+ assert @camelized["VegetableTypes"].last["PeanutNamesAndSpouses"].first.has_key?("BillThePeanut")
93
+ assert @camelized["VegetableTypes"].last["PeanutNamesAndSpouses"].last.has_key?("SammyThePeanut")
94
+ end
95
+
96
+ it "leaves third-level values alone" do
97
+ assert_equal "sally_peanut", @camelized["VegetableTypes"].last["PeanutNamesAndSpouses"].first["BillThePeanut"]
98
+ assert_equal "jill_peanut", @camelized["VegetableTypes"].last["PeanutNamesAndSpouses"].last["SammyThePeanut"]
99
+ end
100
+ end
101
+
102
+ describe "non-destructive conversion to camelBack" do
103
+ before do
104
+ @camelized = @hash.to_camelback_keys
105
+ end
106
+
107
+ it "recursively camelizes the keys on the top level of the hash" do
108
+ assert @camelized.keys.include?("appleType")
109
+ assert @camelized.keys.include?("vegetableTypes")
110
+ end
111
+
112
+ it "leaves the values on the top level alone" do
113
+ assert_equal(@camelized["appleType"], "Granny Smith")
114
+ end
115
+
116
+ it "converts second-level keys" do
117
+ assert @camelized["vegetableTypes"].first.has_key? "potatoType"
118
+ end
119
+
120
+ it "leaves second-level values alone" do
121
+ assert @camelized["vegetableTypes"].first.has_value? "Golden delicious"
122
+ end
123
+
124
+ it "converts third-level keys" do
125
+ assert @camelized["vegetableTypes"].last["peanutNamesAndSpouses"].first.has_key?("billThePeanut")
126
+ assert @camelized["vegetableTypes"].last["peanutNamesAndSpouses"].last.has_key?("sammyThePeanut")
127
+ end
128
+
129
+ it "leaves third-level values alone" do
130
+ assert_equal "sally_peanut", @camelized["vegetableTypes"].last["peanutNamesAndSpouses"].first["billThePeanut"]
131
+ assert_equal "jill_peanut", @camelized["vegetableTypes"].last["peanutNamesAndSpouses"].last["sammyThePeanut"]
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ describe "strings with spaces in them" do
139
+ before do
140
+ @hash = { "With Spaces" => "FooBar"}
141
+ end
142
+
143
+ describe "to_camel_keys" do
144
+ it "doesn't get camelized" do
145
+ @camelized = @hash.to_camel_keys
146
+ assert_equal "With Spaces", @camelized.keys.first
147
+ end
148
+ end
149
+
150
+ describe "to_camelback_keys" do
151
+ it "doesn't get camelized" do
152
+ @camelized = @hash.to_camelback_keys
153
+ assert_equal "With Spaces", @camelized.keys.first
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'minitest/spec'
11
+
12
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ require 'awrence'
15
+
16
+ class MiniTest::Unit::TestCase
17
+ end
18
+
19
+ MiniTest::Unit.autorun
@@ -0,0 +1,2 @@
1
+ require 'helper'
2
+ require File.dirname(__FILE__) + '/../lib/awrence/ext/hash/to_camel_keys'
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awrence
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dave Hrycyszyn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: &2165004220 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2165004220
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ requirement: &2165003740 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '0.7'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2165003740
36
+ - !ruby/object:Gem::Dependency
37
+ name: rdoc
38
+ requirement: &2165003260 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '3.12'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2165003260
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: &2165002780 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2165002780
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &2165002300 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.8.4
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2165002300
69
+ description: ! "Have you ever needed to automatically convert Ruby-style\n snake_case
70
+ to CamelCase or camelBack hash keys?\n\n Awrence to the rescue.\n\n This gem
71
+ recursively converts all snake_case keys in a hash\n structure to camelBack.
72
+ \ "
73
+ email: dave.hrycyszyn@headlondon.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files:
77
+ - LICENSE.txt
78
+ - README.md
79
+ files:
80
+ - .document
81
+ - Gemfile
82
+ - Gemfile.lock
83
+ - LICENSE.txt
84
+ - README.md
85
+ - Rakefile
86
+ - VERSION
87
+ - awrence.gemspec
88
+ - lib/awrence.rb
89
+ - lib/awrence/ext/hash/to_camel_keys.rb
90
+ - test/awrence/ext/hash/to_camel_keys_test.rb
91
+ - test/helper.rb
92
+ - test/test_awrence.rb
93
+ homepage: http://github.com/futurechimp/awrence
94
+ licenses:
95
+ - MIT
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ segments:
107
+ - 0
108
+ hash: -4025899429127598383
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 1.8.17
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Camelize your snake keys when working with JSON APIs
121
+ test_files: []