1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
require_relative "spec_helper"
require 'csv'
describe "Sequel::Plugins::CsvSerializer" do
before do
artist = @Artist = Class.new(Sequel::Model(:artists))
@Artist.class_eval do
def self.name; 'Artist' end
unrestrict_primary_key
plugin :csv_serializer
columns :id, :name
def_column_accessor :id, :name
@db_schema = {:id=>{:type=>:integer}}
end
@Album = Class.new(Sequel::Model(:albums))
@Album.class_eval do
def self.name; 'Album' end
unrestrict_primary_key
attr_accessor :blah
plugin :csv_serializer
columns :id, :name, :artist_id
def_column_accessor :id, :name, :artist_id
@db_schema = {:id=>{:type=>:integer}, :artist_id=>{:type=>:integer}}
many_to_one :artist, :class=>artist
end
@artist = @Artist.load(:id=>2, :name=>'YJM')
@artist.associations[:albums] = []
@album = @Album.load(:id=>1, :name=>'RF')
@album.artist = @artist
@album.blah = 'Blah'
end
it "should round trip successfully" do
@Artist.from_csv(@artist.to_csv).must_equal @artist
@Album.from_csv(@album.to_csv).must_equal @album
end
it "should handle ruby objects in values" do
@Artist.send(:define_method, :name=) do |v|
super(Date.parse(v))
end
a = @Artist.load(:name=>Date.today)
opts = {:columns=>[:name]}
@Artist.from_csv(a.to_csv(opts), opts).must_equal a
end
it "should handle the :only option" do
@Artist.from_csv(@artist.to_csv(:only=>:name), :only=>:name).must_equal @Artist.load(:name=>@artist.name)
@Album.from_csv(@album.to_csv(:only=>[:id, :name]), :only=>[:id, :name]).must_equal @Album.load(:id=>@album.id, :name=>@album.name)
end
it "should handle the :except option" do
@Artist.from_csv(@artist.to_csv(:except=>:id), :except=>:id).must_equal @Artist.load(:name=>@artist.name)
@Album.from_csv(@album.to_csv(:except=>[:id, :artist_id]), :except=>[:id, :artist_id]).must_equal @Album.load(:name=>@album.name)
end
it "should handle the :include option for arbitrary attributes" do
@Album.from_csv(@album.to_csv(:include=>:blah), :include=>:blah).blah.must_equal @album.blah
end
it "should handle multiple inclusions using an array for the :include option" do
a = @Album.from_csv(@album.to_csv(:include=>[:blah]), :include=>:blah)
a.blah.must_equal @album.blah
end
it "#from_csv should set column values" do
@artist.from_csv('AS', :only=>:name)
@artist.name.must_equal 'AS'
@artist.id.must_equal 2
@artist.from_csv('1', :only=>:id)
@artist.name.must_equal 'AS'
@artist.id.must_equal 1
end
it ".array_from_csv should support :headers to specify headers" do
@albums = @Album.array_from_csv("AS,2\nDF,3", :headers=>['name', 'artist_id'])
@albums.map(&:name).must_equal %w'AS DF'
@albums.map(&:artist_id).must_equal [2, 3]
@albums = @Album.array_from_csv("2,AS\n3,DF", :headers=>[nil, 'name'])
@albums.map(&:name).must_equal %w'AS DF'
@albums.map(&:artist_id).must_equal [nil, nil]
end
it ".from_csv should support :headers to specify headers" do
@album = @Album.from_csv('AS,2', :headers=>['name', 'artist_id'])
@album.name.must_equal 'AS'
@album.artist_id.must_equal 2
@album = @Album.from_csv('2,AS', :headers=>[nil, 'name'])
@album.name.must_equal 'AS'
@album.artist_id.must_be_nil
end
it "#from_csv should support :headers to specify headers" do
@album.from_csv('AS,2', :headers=>['name'])
@album.name.must_equal 'AS'
@album.artist_id.must_equal 2
@album.from_csv('2,AS', :headers=>[nil, 'name'])
@album.name.must_equal 'AS'
@album.artist_id.must_equal 2
end
it "should support a to_csv class and dataset method" do
@Album.dataset = @Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
@Artist.dataset = @Artist.dataset.with_fetch(:id=>2, :name=>'YJM')
@Album.columns(:id, :name, :artist_id)
@Album.db_schema.replace(:id=>{:type=>:integer}, :artist_id=>{:type=>:integer})
@Album.array_from_csv(@Album.to_csv).must_equal [@album]
@Album.array_from_csv(@Album.dataset.to_csv(:only=>:name), :only=>:name).must_equal [@Album.load(:name=>@album.name)]
end
it "should have dataset to_csv method respect :array option" do
a = @Album.new(:id=>1, :name=>'RF', :artist_id=>3)
@Album.array_from_csv(@Album.to_csv(:array=>[a])).must_equal [a]
end
it "#to_csv should respect class options" do
@Album = Class.new(Sequel::Model(:albums))
artist = @Artist
@Album.class_eval do
attr_accessor :blah
plugin :csv_serializer, :except => :id, :write_headers=>true, :include=>:blah
columns :id, :name, :artist_id
many_to_one :artist, :class=>artist
end
@album = @Album.load(:id=>2, :name=>'JK')
@album.artist = @artist
@album.blah = 'Gak'
@album.to_csv.must_equal "name,artist_id,blah\nJK,2,Gak\n"
@album.to_csv(:write_headers=>false).must_equal "JK,2,Gak\n"
@album.to_csv(:headers=>[:name]).must_equal "name\nJK\n"
@album.to_csv(:headers=>[:name, :id]).must_equal "name,id\nJK,2\n"
@album.to_csv(:only=>[:name]).must_equal "name,blah\nJK,Gak\n"
@album.to_csv(:except=>nil).must_equal "id,name,artist_id,blah\n2,JK,2,Gak\n"
@album.to_csv(:except=>[:blah]).must_equal "id,name,artist_id\n2,JK,2\n"
end
it "should store the default options in csv_serializer_opts" do
@Album.csv_serializer_opts.must_equal({})
c = Class.new(@Album)
@Album.csv_serializer_opts[:include] = :blah
c.plugin :csv_serializer, :naked=>false
c.csv_serializer_opts.must_equal(:naked=>false)
@Album.csv_serializer_opts.must_equal(:include=>:blah)
end
it "should work correctly when subclassing" do
@Artist2 = Class.new(@Artist)
@Artist2.plugin :csv_serializer, :only=>:name
@Artist3 = Class.new(@Artist2)
@Artist3.from_csv(@Artist3.load(:id=>2, :name=>'YYY').to_csv).must_equal @Artist3.load(:name=>'YYY')
@Artist2 = Class.new(@Artist)
@Artist2.plugin :csv_serializer, :only=>[:name]
@Artist3 = Class.new(@Artist2)
@Artist3.from_csv(@Artist3.load(:id=>2, :name=>'YYY').to_csv).must_equal @Artist3.load(:name=>'YYY')
end
it "should raise an error if attempting to set a restricted column and :all_columns is not used" do
@Artist.restrict_primary_key
proc{@Artist.from_csv(@artist.to_csv)}.must_raise(Sequel::MassAssignmentRestriction)
end
it "should use a dataset's selected columns" do
columns = [:id]
ds = @Artist.select(*columns).limit(1)
ds.send(:columns=, columns)
ds.with_fetch(:id => 10).to_csv(:write_headers => true).must_equal "id\n10\n"
end
it "should pass all the examples from the documentation" do
@album.to_csv(:write_headers=>true).must_equal "id,name,artist_id\n1,RF,2\n"
@album.to_csv(:only=>:name).must_equal "RF\n"
@album.to_csv(:except=>[:id, :artist_id]).must_equal "RF\n"
end
it "should freeze csv serializier opts when model class is frozen" do
@Album.csv_serializer_opts[:only] = [:id]
@Album.csv_serializer_opts[:foo] = :bar
@Album.freeze
@Album.csv_serializer_opts.frozen?.must_equal true
@Album.csv_serializer_opts[:only].frozen?.must_equal true
end
end
|