require 'spec_helper' require 'stringio' describe "Mutations::ArrayFilter" do class SimpleModel; end it "allows arrays" do f = Mutations::ArrayFilter.new(:arr) filtered, errors = f.filter([1]) assert_equal [1], filtered assert_equal nil, errors end it "considers non-arrays to be invalid" do f = Mutations::ArrayFilter.new(:arr) ['hi', true, 1, {:a => "1"}, Object.new].each do |thing| _filtered, errors = f.filter(thing) assert_equal :array, errors end end it "considers nil to be invalid" do f = Mutations::ArrayFilter.new(:arr, :nils => false) filtered, errors = f.filter(nil) assert_equal nil, filtered assert_equal :nils, errors end it "considers nil to be valid" do f = Mutations::ArrayFilter.new(:arr, :nils => true) _filtered, errors = f.filter(nil) _filtered, errors = f.filter(nil) assert_equal nil, errors end it "lets you specify a class, and has valid elements" do f = Mutations::ArrayFilter.new(:arr, :class => Integer) filtered, errors = f.filter([1,2,3]) assert_equal nil, errors assert_equal [1,2,3], filtered end it "lets you specify a class as a string, and has valid elements" do f = Mutations::ArrayFilter.new(:arr, :class => 'Integer') filtered, errors = f.filter([1,2,3]) assert_equal nil, errors assert_equal [1,2,3], filtered end it "lets you specify a class, and has invalid elements" do f = Mutations::ArrayFilter.new(:arr, :class => Integer) filtered, errors = f.filter([1, "bob"]) assert_equal [nil, :class], errors.symbolic assert_equal [1,"bob"], filtered end it "lets you use a block to supply an element filter" do f = Mutations::ArrayFilter.new(:arr) { string } _filtered, errors = f.filter(["hi", {:stuff => "ok"}]) assert_nil errors[0] assert_equal :string, errors[1].symbolic end it "lets you array-ize everything" do f = Mutations::ArrayFilter.new(:arr, :arrayize => true) { string } filtered, errors = f.filter("foo") assert_equal ["foo"], filtered assert_nil errors end it "lets you array-ize an empty string" do f = Mutations::ArrayFilter.new(:arr, :arrayize => true) { string } filtered, errors = f.filter("") assert_equal [], filtered assert_nil errors end it "lets you pass integers in arrays" do f = Mutations::ArrayFilter.new(:arr) { integer :min => 4 } filtered, errors = f.filter([5,6,1,"bob"]) assert_equal [5,6,1,"bob"], filtered assert_equal [nil, nil, :min, :integer], errors.symbolic end it "lets you pass floats in arrays" do f = Mutations::ArrayFilter.new(:float) { float :min => 4.0 } filtered, errors = f.filter([5.0,6.0,1.0,"bob"]) assert_equal [5.0,6.0,1.0,"bob"], filtered assert_equal [nil, nil, :min, :float], errors.symbolic end it "lets you pass ducks in arrays" do f = Mutations::ArrayFilter.new(:arr) { duck(:methods => :length) } filtered, errors = f.filter(["hi", [1], true]) assert_equal ["hi", [1], true], filtered assert_equal [nil, nil, :duck], errors.symbolic end it "lets you pass dates in arrays" do f = Mutations::ArrayFilter.new(:arr) {date(:format => "%Y-%m-%d")} filtered, errors = f.filter(["2000-1-1", Date.new(2000, 1, 1), "2000-20-1"]) assert_equal ["2000-1-1", Date.new(2000, 1, 1), "2000-20-1"], filtered assert_equal [nil, nil, :date], errors.symbolic end it "lets you pass files in arrays" do sio = StringIO.new("bob") f = Mutations::ArrayFilter.new(:arr) { file } filtered, errors = f.filter([sio, "bob"]) assert_equal [sio, "bob"], filtered assert_equal [nil, :file], errors.symbolic end it "lets you pass booleans in arrays" do f = Mutations::ArrayFilter.new(:arr) { boolean } filtered, errors = f.filter([true, false, "1"]) assert_equal [true, false, true], filtered assert_equal nil, errors end it "lets you pass model in arrays" do f = Mutations::ArrayFilter.new(:arr) { model :string } filtered, errors = f.filter(["hey"]) assert_equal ["hey"], filtered assert_equal nil, errors end it "lets you pass hashes in arrays" do f = Mutations::ArrayFilter.new(:arr) do hash do required do string :foo integer :bar end optional do boolean :baz end end end filtered, errors = f.filter([{:foo => "f", :bar => 3, :baz => true}, {:foo => "f", :bar => 3}, {:foo => "f"}]) assert_equal [{:foo=>"f", :bar=>3, :baz=>true}, {:foo=>"f", :bar=>3}, {:foo=>"f"}], filtered assert_equal nil, errors[0] assert_equal nil, errors[1] assert_equal({"bar"=>:required}, errors[2].symbolic) end it "lets you pass arrays of arrays" do f = Mutations::ArrayFilter.new(:arr) do array do string end end filtered, errors = f.filter([["h", "e"], ["l"], [], ["lo"]]) assert_equal filtered, [["h", "e"], ["l"], [], ["lo"]] assert_equal nil, errors end it "handles errors for arrays of arrays" do f = Mutations::ArrayFilter.new(:arr) do array do string end end _filtered, errors = f.filter([["h", "e", {}], ["l"], [], [""]]) assert_equal [[nil, nil, :string], nil, nil, [:empty]], errors.symbolic assert_equal [[nil, nil, "Array[2] isn't a string"], nil, nil, ["Array[0] can't be blank"]], errors.message assert_equal ["Array[2] isn't a string", "Array[0] can't be blank"], errors.message_list end it "strips invalid elements" do f = Mutations::ArrayFilter.new(:arr) do integer :discard_invalid => true end filtered, errors = f.filter([1, "2", "three", "4", 5, [6]]) assert_equal [1,2,4,5], filtered assert_equal nil, errors end it "considers long arrays to be valid" do f = Mutations::ArrayFilter.new(:arr, :min_length => 2) filtered, errors = f.filter([1, 2]) assert_equal [1, 2], filtered assert_equal nil, errors end it "considers short arrays to be invalid" do f = Mutations::ArrayFilter.new(:arr, :min_length => 2) filtered, errors = f.filter([1]) assert_equal [1], filtered assert_equal :min_length, errors end it "sets a max_length for the array of 20 with one element as valid" do f = Mutations::ArrayFilter.new(:arr, :max_length => 20) filtered, errors = f.filter([1]) assert_equal [1], filtered assert_equal nil, errors end it "sets a max_length for the array of 2 with 5 as invalid" do f = Mutations::ArrayFilter.new(:arr, :max_length => 2) filtered, errors = f.filter([1,2,3,4,5]) assert_equal [1,2,3,4,5], filtered assert_equal :max_length, errors end it "will not re-constantize if cache_constants is true" do was = Mutations.cache_constants? Mutations.cache_constants = true f = Mutations::ArrayFilter.new(:simple_models, :class => "SimpleModel") m = SimpleModel.new filtered, errors = f.filter([m]) assert_equal [m], filtered assert_equal nil, errors Object.send(:remove_const, 'SimpleModel') class SimpleModel; end m = SimpleModel.new filtered, errors = f.filter([m]) assert_equal [m], filtered assert_equal [:class], errors.symbolic Mutations.cache_constants = was end it "will re-constantize if cache_constants is false" do was = Mutations.cache_constants? Mutations.cache_constants = false f = Mutations::ArrayFilter.new(:simple_models, :class => "SimpleModel") m = SimpleModel.new filtered, errors = f.filter([m]) assert_equal [m], filtered assert_equal nil, errors Object.send(:remove_const, 'SimpleModel') class SimpleModel; end m = SimpleModel.new filtered, errors = f.filter([m]) assert_equal [m], filtered assert_equal nil, errors Mutations.cache_constants = was end end