1+ RSpec . shared_examples_for 'a serialized hash' do
2+ describe ".dump" do
3+ after { SnakyHash . dump_extensions . reset }
4+
5+ it "returns a JSON string" do
6+ value = subject . dump ( { hello : "World" } )
7+ expect ( value ) . to eq '{"hello":"World"}'
8+ end
9+
10+ it "removes any nil values" do
11+ value = subject . dump ( { hello : "World" , nilValue : nil } )
12+ expect ( value ) . to eq '{"hello":"World"}'
13+ end
14+
15+ it "removes empty strings" do
16+ value = subject . dump ( { hello : "World" , nilValue : "" } )
17+ expect ( value ) . to eq '{"hello":"World"}'
18+ end
19+
20+ it "does not remove false" do
21+ value = subject . dump ( { hello : "World" , falseValue : false } )
22+ expect ( value ) . to eq '{"hello":"World","falseValue":false}'
23+ end
24+
25+ it "removes any empty items from top-level arrays" do
26+ value = subject . dump ( { hello : "World" , array : [ nil , 1 , 2 , "" , false ] } )
27+ expect ( value ) . to eq '{"hello":"World","array":[1,2,false]}'
28+ end
29+
30+ it "passes through any extensions that have been added" do
31+ SnakyHash . dump_extensions . add ( :test ) { |value | value . upcase }
32+ value = subject . dump ( { hello : "WORLD" } )
33+ expect ( value ) . to eq '{"hello":"WORLD"}'
34+ end
35+
36+ it "works with nested hashes" do
37+ SnakyHash . dump_extensions . add ( :test ) { |value | value . is_a? ( String ) ? value . upcase : value }
38+ value = subject . dump ( { hello : "world" , nested : { vegetable : "potato" , more_nesting : { fruit : "banana" } } } )
39+ expect ( value ) . to eq '{"hello":"WORLD","nested":{"vegetable":"POTATO","more_nesting":{"fruit":"BANANA"}}}'
40+ end
41+
42+ it "works with nested hashes in arrays" do
43+ SnakyHash . dump_extensions . add ( :test ) { |value | value . is_a? ( String ) ? value . upcase : value }
44+ value = subject . dump ( { hello : "world" , nested : { vegetables : [ { name : "potato" } , { name : "cucumber" } ] , more_nesting : { fruits : [ { name : "banana" } , { name : "apple" } ] } } } )
45+ expect ( value ) . to eq '{"hello":"WORLD","nested":{"vegetables":[{"name":"POTATO"},{"name":"CUCUMBER"}],"more_nesting":{"fruits":[{"name":"BANANA"},{"name":"APPLE"}]}}}'
46+ end
47+ end
48+
49+ describe ".load" do
50+ after do
51+ SnakyHash . load_extensions . reset
52+ SnakyHash . load_hash_extensions . reset
53+ end
54+
55+ it "creates a Hashie::Mash from the given JSON" do
56+ hash = subject . load ( '{"hello":"world"}' )
57+ expect ( hash ) . to be_a Hashie ::Mash
58+ expect ( hash [ "hello" ] ) . to eq "world"
59+ end
60+
61+ it "shuold create an empty Mash if the given value is nil" do
62+ hash = subject . load ( nil )
63+ expect ( hash ) . to be_a Hashie ::Mash
64+ expect ( hash ) . to be_empty
65+ end
66+
67+ it "creates an empty Mash if the JSON is an empty string" do
68+ hash = subject . load ( "" )
69+ expect ( hash ) . to be_a Hashie ::Mash
70+ expect ( hash ) . to be_empty
71+ end
72+
73+ it "passes through any extensions that have been added" do
74+ SnakyHash . load_extensions . add ( :test ) { |value | value . upcase }
75+ hash = subject . load ( '{"hello":"world"}' )
76+ expect ( hash ) . to be_a Hashie ::Mash
77+ expect ( hash [ "hello" ] ) . to eq "WORLD"
78+ end
79+
80+ it "works with nested hashes" do
81+ SnakyHash . load_extensions . add ( :test ) { |value | value . is_a? ( String ) ? value . downcase : nil }
82+ hash = subject . load ( '{"hello":"WORLD","nested":{"vegetable":"POTATO","more_nesting":{"fruit":"BANANA"}}}' )
83+ expect ( hash ) . to be_a Hashie ::Mash
84+ expect ( hash ) . to eq ( { "hello" => "world" , "nested" => { "vegetable" => "potato" , "more_nesting" => { "fruit" => "banana" } } } )
85+ end
86+
87+ it "works with nested hashes in arrays" do
88+ SnakyHash . load_extensions . add ( :test ) { |value | value . is_a? ( String ) ? value . downcase : nil }
89+ hash = subject . load ( '{"num":3,"hello":"WORLD","nested":{"vegetables":[{"name":"POTATO"},{"name":"CUCUMBER"}],"more_nesting":{"fruits":[{"name":"BANANA"},{"name":"APPLE"}]}}}' )
90+ expect ( hash ) . to be_a Hashie ::Mash
91+ expect ( hash ) . to eq ( { "num" => nil , "hello" => "world" , "nested" => { "vegetables" => [ { "name" => "potato" } , { "name" => "cucumber" } ] , "more_nesting" => { "fruits" => [ { "name" => "banana" } , { "name" => "apple" } ] } } } )
92+ end
93+
94+ it "is unable to upcase keys, because instantiation of a SnakyHash downcases keys" do
95+ SnakyHash . load_hash_extensions . add ( :test ) { |value |
96+ if value . is_a? ( Hash )
97+ value . transform_keys ( &:upcase )
98+ else
99+ value
100+ end
101+ }
102+ hash = subject . load ( '{"some_hash":{"name":"Michael"}}' )
103+ expect ( hash ) . to be_a Hashie ::Mash
104+ expect ( hash ) . to eq ( { "some_hash" => { "name" => "Michael" } } )
105+ end
106+
107+ it "passes through hashes through their own extensions" do
108+ SnakyHash . load_hash_extensions . add ( :test ) { |value |
109+ if value . is_a? ( Hash )
110+ value . transform_keys ( &:next )
111+ else
112+ value
113+ end
114+ }
115+ hash = subject . load ( '{"some_hash":{"name":"Michael"}}' )
116+ expect ( hash ) . to be_a Hashie ::Mash
117+ expect ( hash ) . to eq ( { "some_hash" => { "namf" => "Michael" } } )
118+ end
119+
120+ it "passes hashses through their own extension and return non-hash values properly" do
121+ SnakyHash . load_hash_extensions . add ( :test ) { |value |
122+ if value . is_a? ( Hash )
123+ value . key? ( "name" ) ? value [ "name" ] : value
124+ else
125+ value
126+ end
127+ }
128+ hash = subject . load ( '{"some_hash":{"name":"Michael"}}' )
129+ expect ( hash ) . to be_a Hashie ::Mash
130+ expect ( hash ) . to eq ( { "some_hash" => "Michael" } )
131+ end
132+ end
133+ end
0 commit comments