summaryrefslogtreecommitdiff
path: root/test/csv/test_serialization.rb
blob: 878619f58a575cd39c776917bef9bcbae2f9ad61 (plain)
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
#!/usr/bin/env ruby -w
# encoding: UTF-8

# tc_serialization.rb
#
#  Created by James Edward Gray II on 2005-10-31.
#  Copyright 2005 James Edward Gray II. You can redistribute or modify this code
#  under the terms of Ruby's license.

require "test/unit"

require "csv"

# An example of how to provide custom CSV serialization.
class Hash
  def self.csv_load( meta, headers, fields )
    self[*headers.zip(fields).to_a.flatten.map { |e| eval(e) }]
  end
  
  def csv_headers
    keys.map { |key| key.inspect }
  end
  
  def csv_dump( headers )
    headers.map { |header| fetch(eval(header)).inspect }
  end
end

class TestSerialization < Test::Unit::TestCase
  
  ### Classes Used to Test Serialization ###
  
  class ReadOnlyName
    def initialize( first, last )
      @first, @last = first, last
    end

    attr_reader :first, :last
    
    def ==( other )
      %w{first last}.all? { |att| send(att) == other.send(att) }
    end
  end

  Name = Struct.new(:first, :last)
  
  class FullName < Name
    def initialize( first, last, suffix = nil )
      super(first, last)
      
      @suffix = suffix
    end
    
    attr_accessor :suffix
    
    def ==( other )
      %w{first last suffix}.all? { |att| send(att) == other.send(att) }
    end
  end
  
  ### Tests ###

  def test_class_dump
    @names = [ %w{James Gray},
              %w{Dana Gray},
              %w{Greg Brown} ].map do |first, last|
      ReadOnlyName.new(first, last)
    end
    
    assert_nothing_raised(Exception) do 
      @data = CSV.dump(@names)
    end
    assert_equal(<<-END_CLASS_DUMP.gsub(/^\s*/, ""), @data)
    class,TestSerialization::ReadOnlyName
    @first,@last
    James,Gray
    Dana,Gray
    Greg,Brown
    END_CLASS_DUMP
  end
  
  def test_struct_dump
    @names = [ %w{James Gray},
              %w{Dana Gray},
              %w{Greg Brown} ].map do |first, last|
      Name.new(first, last)
    end
    
    assert_nothing_raised(Exception) do 
      @data = CSV.dump(@names)
    end
    assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
    class,TestSerialization::Name
    first=,last=
    James,Gray
    Dana,Gray
    Greg,Brown
    END_STRUCT_DUMP
  end
  
  def test_inherited_struct_dump
    @names = [ %w{James Gray II},
              %w{Dana Gray},
              %w{Greg Brown} ].map do |first, last, suffix|
      FullName.new(first, last, suffix)
    end
    
    assert_nothing_raised(Exception) do 
      @data = CSV.dump(@names)
    end
    assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
    class,TestSerialization::FullName
    @suffix,first=,last=
    II,James,Gray
    ,Dana,Gray
    ,Greg,Brown
    END_STRUCT_DUMP
  end
  
  def test_load
    %w{ test_class_dump
        test_struct_dump
        test_inherited_struct_dump }.each do |test|
      send(test)
      CSV.load(@data).each do |loaded|
        assert_instance_of(@names.first.class, loaded)
        assert_equal(@names.shift, loaded)
      end
    end
  end
  
  def test_io
    test_class_dump
    
    data_file = File.join(File.dirname(__FILE__), "temp_test_data.csv")
    CSV.dump(@names, File.open(data_file, "w"))
    
    assert(File.exist?(data_file))
    assert_equal(<<-END_IO_DUMP.gsub(/^\s*/, ""), File.read(data_file))
    class,TestSerialization::ReadOnlyName
    @first,@last
    James,Gray
    Dana,Gray
    Greg,Brown
    END_IO_DUMP
    
    assert_equal(@names, CSV.load(File.open(data_file)))
    
    File.unlink(data_file)
  end
  
  def test_custom_dump_and_load
    obj = {1 => "simple", test: Hash}
    assert_equal(obj, CSV.load(CSV.dump([obj])).first)
  end
end