diff --git a/.gitignore b/.gitignore index 048015b..1ffd04c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ tmtags ## VIM *.swp +## RubyMine +/.idea + ## PROJECT::GENERAL coverage rdoc diff --git a/README.rdoc b/README.rdoc index f611dd5..de11e0d 100644 --- a/README.rdoc +++ b/README.rdoc @@ -38,6 +38,48 @@ You will now be able to access those keys through underscored key names (camelCa @rash.nested_two.nested_two # => 22 @rash.nested_two.nested_three # => 23 += Unrash + +Unrash is an extension to Hashie ( http://github.com/intridea/hashie ) + +Unrash subclasses Hashie::Mash to convert all keys in the hash to lower camel case + +The purpose of this is when working w/ Java (or any other apis) and need to send hashes (including nested) that need to be +camelCased keys + +You will now be able to access those keys through camelCase key names (underscored still available) + +== Usage + + @unrash = Hashie::UnRash.new({ + "var_one" => 1, + "two" => 2, + :three => 3, + :var_four => 4, + "five_hump_humps" => 5, + :nested => { + "nested_one" => "One", + :two => "two", + "nested_three" => "three" + }, + "nested_wwo" => { + "nested_two" => 22, + :nested_three => 23 + } + }) + + @unrash.varOne # => 1 + @unrash.two # => 2 + @unrash.three # => 3 + @unrash.varFour # => 4 + @unrash.fiveHumpHumps # => 5 + @unrash.nested.nestedOne # => "One" + @unrash.nested.two # => "two" + @unrash.nested.nestedThree # => "three" + @unrash.nestedTwo.nestedTwo # => 22 + @unrash.nestedTwo.nestedThree # => 23 + + == Note on Patches/Pull Requests * Fork the project. @@ -57,3 +99,4 @@ Copyright (c) 2010 Tom Cocca. See LICENSE for details. * Intridea (https://github.com/intridea) for Hashie * Mislav Marohnić (https://github.com/mislav) for contributions to Rash * Steve Agalloco (https://github.com/spagalloco) for updating Rash to use bundler, rspec 2.5, hashie 1.0 and fixing some load dependencies +* Sebastian Ortiz (https://github.com/neoecos) for the implementation of Unrash diff --git a/lib/hashie/unrash.rb b/lib/hashie/unrash.rb new file mode 100644 index 0000000..682cf31 --- /dev/null +++ b/lib/hashie/unrash.rb @@ -0,0 +1,40 @@ +require 'hashie/mash' + +module Hashie + class Unrash < Mash + + protected + + def convert_key(key) #:nodoc: + camel_case_lower(key.to_s) + end + + # Unlike its parent Mash, a Unrash will convert other Hashie::Hash values to a Unrash when assigning + # instead of respecting the existing subclass + def convert_value(val, duping=false) #:nodoc: + case val + when self.class + val.dup + when ::Hash + val = val.dup if duping + self.class.new(val) + when Array + val.collect{ |e| convert_value(e) } + else + val + end + end + + # converts a underscore string to a lowerCamelCase string + def camel_case_lower(str) + str.strip().gsub(' ','').split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join + end + + def camel_case(str) + return str if str !~ /_/ && str =~ /[A-Z]+.*/ + str.strip().gsub(' ','').split('_').map{|e| e.capitalize}.join + end + + end + +end \ No newline at end of file diff --git a/lib/rash.rb b/lib/rash.rb index 903a924..9ba1210 100644 --- a/lib/rash.rb +++ b/lib/rash.rb @@ -1 +1,2 @@ -require 'hashie/rash' \ No newline at end of file +require 'hashie/rash' +require 'hashie/unrash' \ No newline at end of file diff --git a/spec/unrash_spec.rb b/spec/unrash_spec.rb new file mode 100644 index 0000000..79f873a --- /dev/null +++ b/spec/unrash_spec.rb @@ -0,0 +1,115 @@ +require 'spec_helper' + +describe Hashie::Unrash do + subject { + Hashie::Unrash.new({ + "var_one" => 1, + "two" => 2, + :three => 3, + :var_four => 4, + "five_hump_humps" => 5, + :nested => { + "nested_one" => "One", + :two => "two", + "nested_three" => "three" + }, + "nested_two" => { + "nested_two" => 22, + :nested_three => 23 + }, + "spaced _Key" => "When would this happen?", + " trailing_spaces " => "better safe than sorry", + "extra___spaces" => "hopefully this never happens" + }) + } + + it { should be_a(Hashie::Mash) } + + it "should create a new unrash where all the keys are camelcased instead of underscored" do + subject.varOne.should == 1 + subject.two.should == 2 + subject.three.should == 3 + subject.varFour.should == 4 + subject.fiveHumpHumps.should == 5 + subject.nested.should be_a(Hashie::Unrash) + subject.nested.nestedOne.should == "One" + subject.nested.two.should == "two" + subject.nested.nested_three.should == "three" + subject.nestedTwo.should be_a(Hashie::Unrash) + subject.nestedTwo.nestedTwo.should == 22 + subject.nestedTwo.nestedThree.should == 23 + subject.spacedKey.should == "When would this happen?" + subject.trailingSpaces.should == "better safe than sorry" + subject.extraSpaces.should == "hopefully this never happens" + end + + it "should allow underscored accessors" do + subject.var_one.should == 1 + subject.var_one = "once" + subject.var_one.should == "once" + subject.varOne.should == "once" + end + + it "should allow underscored accessors on nested hashes" do + subject.nested.nested_one.should == "One" + subject.nested.nested_one = "once" + subject.nested.nestedOne.should == "once" + end + + it "should merge well with a Mash" do + merged = subject.merge Hashie::Mash.new( + :nested => {:fourTimes => "a charm"}, + :nested3 => {:helloWorld => "hi"} + ) + + merged.nested.four_times.should == "a charm" + merged.nested.fourTimes.should == "a charm" + merged.nested3.should be_a(Hashie::Unrash) + merged.nested3.helloWorld.should == "hi" + merged.nested3.hello_world.should == "hi" + merged[:nested3][:helloWorld].should == "hi" + end + + it "should update well with a Mash" do + subject.update Hashie::Mash.new( + :nested => {:four_times => "a charm"}, + :nested3 => {:hello_world => "hi"} + ) + + subject.nested.four_times.should == "a charm" + subject.nested.fourTimes.should == "a charm" + subject.nested3.should be_a(Hashie::Unrash) + subject.nested3.hello_world.should == "hi" + subject.nested3.helloWorld.should == "hi" + subject[:nested3][:hello_world].should == "hi" + end + + it "should merge well with a Hash" do + merged = subject.merge({ + :nested => {:fourTimes => "work like a charm"}, + :nested3 => {:helloWorld => "hi"} + }) + + merged.nested.four_times.should == "work like a charm" + merged.nested.fourTimes.should == "work like a charm" + merged.nested3.should be_a(Hashie::Unrash) + merged.nested3.hello_world.should == "hi" + merged.nested3.helloWorld.should == "hi" + merged[:nested3][:helloWorld].should == "hi" + end + + it "should handle assigning a new Hash and convert it to a unrash" do + subject.nested3 = {:helloWorld => "hi"} + + subject.nested3.should be_a(Hashie::Unrash) + subject.nested3.hello_world.should == "hi" + subject.nested3.helloWorld.should == "hi" + subject[:nested3][:helloWorld].should == "hi" + end + + it "should allow initializing reader" do + subject.nested3!.helloWorld = "hi" + subject.nested3.hello_world.should == "hi" + end + +end