require 'spec_helper' describe CrazyHashFilter do before do @sample = { :code => 0, :items => [ { :id => 1, :title => 'First item', :thumbs => [ { :code => '50', :url => 'http://some-url/1/50' }, { :code => '100', :url => 'http://some-url/1/100' }, { :code => '150', :url => 'http://some-url/1/150' } ] }, { :id => 2, :title => 'Second item', :thumbs => [ { :code => '50', :url => 'http://some-url/2/50' }, { :code => '100', :url => 'http://some-url/2/100' }, { :code => '150', :url => 'http://some-url/2/150' } ] }, ] } end it "should return same hash if no filters passed" do result = CrazyHashFilter.process(@sample, {}) result.should == @sample end it "should select only certain keys from the hash" do rules = { :select => [ :code ] } result = CrazyHashFilter.process(@sample, rules) result.should == { :code => 0 } end it "should filter with nested rules" do rules = { :select => [ :code, :items ], :child_rules => { :items => { :select => [ :id, :title ] } } } result = CrazyHashFilter.process(@sample, rules) result.keys.should include(:code) result.keys.should include(:items) result[:items][0].keys.should include(:id) result[:items][0].keys.should include(:title) result[:items][0].keys.should_not include(:thumbs) result[:items][1].keys.should include(:id) result[:items][1].keys.should include(:title) result[:items][1].keys.should_not include(:thumbs) end it "should filter with nested rules and conditions" do rules = { :select => [ :code, :items ], :child_rules => { :items => { :select => [ :id, :title, :thumbs ], :child_rules => { :thumbs => { :conditions => { :code => [ '50', '100' ] } } } } } } result = CrazyHashFilter.process(@sample, rules) result.keys.should include(:code) result.keys.should include(:items) result[:items][0].keys.should include(:id) result[:items][0].keys.should include(:title) result[:items][0].keys.should include(:thumbs) result[:items][0][:thumbs].collect { |t| t[:code] }.should include('50') result[:items][0][:thumbs].collect { |t| t[:code] }.should include('100') result[:items][0][:thumbs].collect { |t| t[:code] }.should_not include('150') end it "should accept condition strings" do rules = { :select => [ :code, :items ], :child_rules => { :items => { :select => [ :id, :thumbs ], :child_rules => { :thumbs => { :conditions => { :code => '50' } } } } } } result = CrazyHashFilter.process(@sample, rules) result[:items][0][:thumbs].collect { |t| t[:code] }.should include('50') result[:items][0][:thumbs].collect { |t| t[:code] }.should_not include('100') result[:items][0][:thumbs].collect { |t| t[:code] }.should_not include('150') end it "should allow using strings in rules" do rules = { 'select' => [ 'code', 'items' ], 'child_rules' => { 'items' => { 'select' => [ 'id', 'title' ] } } } result = CrazyHashFilter.process(@sample, rules) result.keys.should include(:code) result.keys.should include(:items) result[:items][0].keys.should include(:id) result[:items][0].keys.should include(:title) result[:items][0].keys.should_not include(:thumbs) result[:items][1].keys.should include(:id) result[:items][1].keys.should include(:title) result[:items][1].keys.should_not include(:thumbs) end it "should match integer conditions" do rules = { :select => [ :code, :items ], :child_rules => { :items => { :select => [ :id, :thumbs ], :conditions => { :id => 1 } } } } result = CrazyHashFilter.process(@sample, rules) result[:items].collect { |i| i[:id] }.should include(1) result[:items].collect { |i| i[:id] }.should_not include(2) end it "should match integer to string conditions" do rules = { :select => [ :code, :items ], :child_rules => { :items => { :select => [ :id, :thumbs ], :conditions => { :id => '1' } } } } result = CrazyHashFilter.process(@sample, rules) result[:items].collect { |i| i[:id] }.should include(1) result[:items].collect { |i| i[:id] }.should_not include(2) end it "should deal with nil values" do sample = { :code => 0, :items => [ { :id => 1, :title => nil, :thumbs => nil }, { :id => 2, :title => 'Second item', :thumbs => [ { :code => '50', :url => 'http://some-url/2/50' }, { :code => '100', :url => 'http://some-url/2/100' }, { :code => '150', :url => 'http://some-url/2/150' } ] }, ] } rules = { :select => [ :code, :items ], :child_rules => { :items => { :select => [ :id, :thumbs ], :child_rules => { :thumbs => { :conditions => { :code => '50' } } } } } } result = CrazyHashFilter.process(sample, rules) result[:items].collect { |i| i[:id] }.should include(1) end describe "Extending Hash" do it "should define crazy_filter method" do rules = { :select => [ :code ] } result = @sample.crazy_filter(rules) result[:code].should == 0 result[:items].should be_nil end it "should define crazy_filter! method" do rules = { :select => [ :code ] } sample = @sample.clone sample.crazy_filter!(rules) sample[:code].should == 0 sample[:items].should be_nil end end end