aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/attributes/typecasting_test.rb
blob: c712f224b216962f2416eaa2344df809052b5119 (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
require "cases/helper"

class TypecastingTest < ActiveRecord::TestCase

  class TypecastingAttributes < Hash
    include ActiveRecord::Attributes::Typecasting
  end

  module MockType
    class Object

      def cast(value)
        value
      end

      def precast(value)
        value
      end

      def boolean(value)
        !value.blank?
      end

      def appendable?
        false
      end

    end

    class Integer < Object

      def cast(value)
        value.to_i
      end

      def precast(value)
        value ? value : 0
      end

      def boolean(value)
        !Float(value).zero?
      end

    end

    class Serialize < Object

      def cast(value)
        YAML::load(value) rescue value
      end

      def precast(value)
        value
      end

      def appendable?
        true
      end

    end
  end

  def setup
    @attributes = TypecastingAttributes.new
    @attributes.types.default = MockType::Object.new
    @attributes.types['comments_count'] = MockType::Integer.new
  end

  test "typecast on read" do
    attributes = @attributes.merge('comments_count' => '5')
    assert_equal 5, attributes['comments_count']
  end

  test "typecast on write" do
    @attributes['comments_count'] = false

    assert_equal 0, @attributes.to_h['comments_count']
  end

  test "serialized objects" do
    attributes = @attributes.merge('tags' => [ 'peanut butter' ].to_yaml)
    attributes.types['tags'] = MockType::Serialize.new
    attributes['tags'] << 'jelly'

    assert_equal [ 'peanut butter', 'jelly' ], attributes['tags']
  end

  test "without typecasting" do
    attributes = @attributes.without_typecast
    attributes['comments_count'] = '5'

    assert_equal '5', attributes['comments_count']
  end

  test "typecast all attributes" do
    attributes = @attributes.merge('title' => 'I love sandwiches', 'comments_count' => '5')
    attributes.typecast!

    assert_equal({ 'title' => 'I love sandwiches', 'comments_count' => 5 }, attributes)
  end

  test "query for has? value" do
    attributes = @attributes.merge('comments_count' => '1')

    assert_equal true,  attributes.has?('comments_count')
    attributes['comments_count'] = '0'
    assert_equal false,  attributes.has?('comments_count')
  end

  test "attributes to Hash" do
    attributes_hash = { 'title' => 'I love sandwiches', 'comments_count' => '5' }
    attributes = @attributes.merge(attributes_hash)

    assert_equal Hash, attributes.to_h.class
    assert_equal attributes_hash, attributes.to_h
  end

end