aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/yaml_serialization_test.rb
blob: 6556771a9d8630b8a6ea43d9d692b0243e4d4e1d (plain) (blame)
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
require "cases/helper"
require "models/topic"
require "models/reply"
require "models/post"
require "models/author"

class YamlSerializationTest < ActiveRecord::TestCase
  fixtures :topics, :authors, :posts

  def test_to_yaml_with_time_with_zone_should_not_raise_exception
    with_timezone_config aware_attributes: true, zone: "Pacific Time (US & Canada)" do
      topic = Topic.new(written_on: DateTime.now)
      assert_nothing_raised { topic.to_yaml }
    end
  end

  def test_roundtrip
    topic = Topic.first
    assert topic
    t = YAML.load YAML.dump topic
    assert_equal topic, t
  end

  def test_roundtrip_serialized_column
    topic = Topic.new(content: {omg: :lol})
    assert_equal({omg: :lol}, YAML.load(YAML.dump(topic)).content)
  end

  def test_psych_roundtrip
    topic = Topic.first
    assert topic
    t = Psych.load Psych.dump topic
    assert_equal topic, t
  end

  def test_psych_roundtrip_new_object
    topic = Topic.new
    assert topic
    t = Psych.load Psych.dump topic
    assert_equal topic.attributes, t.attributes
  end

  def test_active_record_relation_serialization
    [Topic.all].to_yaml
  end

  def test_raw_types_are_not_changed_on_round_trip
    topic = Topic.new(parent_id: "123")
    assert_equal "123", topic.parent_id_before_type_cast
    assert_equal "123", YAML.load(YAML.dump(topic)).parent_id_before_type_cast
  end

  def test_cast_types_are_not_changed_on_round_trip
    topic = Topic.new(parent_id: "123")
    assert_equal 123, topic.parent_id
    assert_equal 123, YAML.load(YAML.dump(topic)).parent_id
  end

  def test_new_records_remain_new_after_round_trip
    topic = Topic.new

    assert topic.new_record?, "Sanity check that new records are new"
    assert YAML.load(YAML.dump(topic)).new_record?, "Record should be new after deserialization"

    topic.save!

    assert_not topic.new_record?, "Saved records are not new"
    assert_not YAML.load(YAML.dump(topic)).new_record?, "Saved record should not be new after deserialization"

    topic = Topic.select("title").last

    assert_not topic.new_record?, "Loaded records without ID are not new"
    assert_not YAML.load(YAML.dump(topic)).new_record?, "Record should not be new after deserialization"
  end

  def test_types_of_virtual_columns_are_not_changed_on_round_trip
    author = Author.select("authors.*, count(posts.id) as posts_count")
      .joins(:posts)
      .group("authors.id")
      .first
    dumped = YAML.load(YAML.dump(author))

    assert_equal 5, author.posts_count
    assert_equal 5, dumped.posts_count
  end

  def test_a_yaml_version_is_provided_for_future_backwards_compat
    coder = {}
    Topic.first.encode_with(coder)

    assert coder["active_record_yaml_version"]
  end

  def test_deserializing_rails_41_yaml
    topic = YAML.load(yaml_fixture("rails_4_1"))

    assert topic.new_record?
    assert_equal nil, topic.id
    assert_equal "The First Topic", topic.title
    assert_equal({ omg: :lol }, topic.content)
  end

  def test_deserializing_rails_4_2_0_yaml
    topic = YAML.load(yaml_fixture("rails_4_2_0"))

    assert_not topic.new_record?
    assert_equal 1, topic.id
    assert_equal "The First Topic", topic.title
    assert_equal("Have a nice day", topic.content)
  end

  def test_yaml_encoding_keeps_mutations
    author = Author.first
    author.name = "Sean"
    dumped = YAML.load(YAML.dump(author))

    assert_equal "Sean", dumped.name
    assert_equal author.name_was, dumped.name_was
    assert_equal author.changes, dumped.changes
  end

  private

  def yaml_fixture(file_name)
    path = File.expand_path(
      "../../support/yaml_compatibility_fixtures/#{file_name}.yml",
      __FILE__
    )
    File.read(path)
  end
end