File: date_time_precision_test.rb

package info (click to toggle)
rails 2%3A7.2.2.1%2Bdfsg-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 43,352 kB
  • sloc: ruby: 349,799; javascript: 30,703; yacc: 46; sql: 43; sh: 29; makefile: 27
file content (259 lines) | stat: -rw-r--r-- 9,319 bytes parent folder | download
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# frozen_string_literal: true

require "cases/helper"
require "support/schema_dumping_helper"

class DateTimePrecisionTest < ActiveRecord::TestCase
  if supports_datetime_with_precision?
    include InTimeZone
    include SchemaDumpingHelper
    self.use_transactional_tests = false

    class Foo < ActiveRecord::Base; end

    setup do
      @connection = ActiveRecord::Base.lease_connection
      Foo.reset_column_information
    end

    teardown do
      @connection.drop_table :foos, if_exists: true
    end

    def test_datetime_data_type_with_precision
      @connection.create_table(:foos, force: true)
      @connection.add_column :foos, :created_at, :datetime, precision: 0
      @connection.add_column :foos, :updated_at, :datetime, precision: 5
      assert_equal 0, Foo.columns_hash["created_at"].precision
      assert_equal 5, Foo.columns_hash["updated_at"].precision
    end

    def test_datetime_precision_is_truncated_on_assignment
      @connection.create_table(:foos, force: true)
      @connection.add_column :foos, :created_at, :datetime, precision: 0
      @connection.add_column :foos, :updated_at, :datetime, precision: 6

      time = ::Time.now.change(nsec: 123456789)
      foo = Foo.new(created_at: time, updated_at: time)

      assert_equal 0, foo.created_at.nsec
      assert_equal 123456000, foo.updated_at.nsec

      foo.save!
      foo.reload

      assert_equal 0, foo.created_at.nsec
      assert_equal 123456000, foo.updated_at.nsec
    end

    unless current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
      def test_no_datetime_precision_isnt_truncated_on_assignment
        @connection.create_table(:foos, force: true)
        @connection.add_column :foos, :created_at, :datetime, precision: nil
        @connection.add_column :foos, :updated_at, :datetime

        time = ::Time.now.change(nsec: 123)
        foo = Foo.new(created_at: time, updated_at: time)

        assert_equal 123, foo.created_at.nsec
        assert_equal 0, foo.updated_at.nsec

        foo.save!
        foo.reload

        assert_equal 0, foo.created_at.nsec
        assert_equal 0, foo.updated_at.nsec
      end
    end

    def test_timestamps_helper_with_custom_precision
      @connection.create_table(:foos, force: true) do |t|
        t.timestamps precision: 4
      end
      assert_equal 4, Foo.columns_hash["created_at"].precision
      assert_equal 4, Foo.columns_hash["updated_at"].precision
    end

    def test_passing_precision_to_datetime_does_not_set_limit
      @connection.create_table(:foos, force: true) do |t|
        t.timestamps precision: 4
      end
      assert_nil Foo.columns_hash["created_at"].limit
      assert_nil Foo.columns_hash["updated_at"].limit
    end

    def test_invalid_datetime_precision_raises_error
      assert_raises ArgumentError do
        @connection.create_table(:foos, force: true) do |t|
          t.timestamps precision: 7
        end
      end
    end

    def test_formatting_datetime_according_to_precision
      @connection.create_table(:foos, force: true) do |t|
        t.datetime :created_at, precision: 0
        t.datetime :updated_at, precision: 4
      end

      date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
      Foo.create!(created_at: date, updated_at: date)

      assert foo = Foo.find_by(created_at: date)
      assert_equal 1, Foo.where(updated_at: date).count
      assert_equal date.to_i, foo.created_at.to_i
      assert_equal date.to_s, foo.created_at.to_s
      assert_equal date.to_s, foo.updated_at.to_s
      assert_equal 000000, foo.created_at.usec
      assert_equal 999900, foo.updated_at.usec
    end

    def test_formatting_datetime_according_to_precision_when_time_zone_aware
      with_timezone_config aware_attributes: true, zone: "Pacific Time (US & Canada)" do
        @connection.create_table(:foos, force: true) do |t|
          t.datetime :created_at, precision: 0
          t.datetime :updated_at, precision: 4
        end

        date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
        Foo.create!(created_at: date, updated_at: date)

        assert foo = Foo.find_by(created_at: date)
        assert_equal 1, Foo.where(updated_at: date).count
        assert_equal date.to_i, foo.created_at.to_i
        assert_equal date.in_time_zone.to_s, foo.created_at.to_s
        assert_equal date.in_time_zone.to_s, foo.updated_at.to_s
        assert_equal 000000, foo.created_at.usec
        assert_equal 999900, foo.updated_at.usec
      end
    end

    if current_adapter?(:PostgreSQLAdapter)
      def test_formatting_datetime_according_to_precision_using_timestamptz
        with_postgresql_datetime_type(:timestamptz) do
          @connection.create_table(:foos, force: true) do |t|
            t.datetime :created_at, precision: 0
            t.datetime :updated_at, precision: 4
          end

          date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
          Foo.create!(created_at: date, updated_at: date)

          assert foo = Foo.find_by(created_at: date)
          assert_equal 1, Foo.where(updated_at: date).count
          assert_equal date.to_i, foo.created_at.to_i
          assert_equal date.to_s, foo.created_at.to_s
          assert_equal date.to_s, foo.updated_at.to_s
          assert_equal 000000, foo.created_at.usec
          assert_equal 999900, foo.updated_at.usec
        end
      end

      def test_formatting_datetime_according_to_precision_when_time_zone_aware_using_timestamptz
        with_postgresql_datetime_type(:timestamptz) do
          with_timezone_config aware_attributes: true, zone: "Pacific Time (US & Canada)" do
            @connection.create_table(:foos, force: true) do |t|
              t.datetime :created_at, precision: 0
              t.datetime :updated_at, precision: 4
            end

            date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
            Foo.create!(created_at: date, updated_at: date)

            assert foo = Foo.find_by(created_at: date)
            assert_equal 1, Foo.where(updated_at: date).count
            assert_equal date.to_i, foo.created_at.to_i
            assert_equal date.in_time_zone.to_s, foo.created_at.to_s
            assert_equal date.in_time_zone.to_s, foo.updated_at.to_s
            assert_equal 000000, foo.created_at.usec
            assert_equal 999900, foo.updated_at.usec
          end
        end
      end
    end

    def test_writing_a_blank_attribute
      @connection.create_table(:foos, force: true) do |t|
        t.datetime :happened_at
      end

      assert_nil Foo.create!(happened_at: nil).happened_at
      assert_nil Foo.create!(happened_at: "").happened_at
    end

    def test_writing_a_date_attribute
      @connection.create_table(:foos, force: true) do |t|
        t.datetime :happened_at
      end

      date = ::Date.new(2001, 2, 3)
      assert_equal date, Foo.create!(happened_at: date).happened_at
    end

    if current_adapter?(:PostgreSQLAdapter)
      def test_writing_a_blank_attribute_timestamptz
        with_postgresql_datetime_type(:timestamptz) do
          @connection.create_table(:foos, force: true) do |t|
            t.datetime :happened_at
          end

          assert_nil Foo.create!(happened_at: nil).happened_at
          assert_nil Foo.create!(happened_at: "").happened_at
        end
      end

      def test_writing_a_date_attribute_timestamptz
        with_postgresql_datetime_type(:timestamptz) do
          @connection.create_table(:foos, force: true) do |t|
            t.datetime :happened_at
          end

          date = ::Date.new(2001, 2, 3)
          assert_equal date, Foo.create!(happened_at: date).happened_at
        end
      end

      def test_writing_a_time_with_zone_attribute_timestamptz
        with_postgresql_datetime_type(:timestamptz) do
          @connection.create_table(:foos, force: true) do |t|
            t.datetime :happened_at
          end

          in_time_zone("Pacific Time (US & Canada)") do
            time = Time.zone.now
            assert_equal time.zone, Foo.new(happened_at: time).happened_at.zone
          end
        end
      end
    end

    def test_schema_dump_with_default_precision_is_not_dumped
      @connection.create_table(:foos, force: true) do |t|
        t.timestamps precision: 6
      end
      output = dump_table_schema("foos")
      assert_match %r{t\.datetime\s+"created_at",\s+null: false$}, output
      assert_match %r{t\.datetime\s+"updated_at",\s+null: false$}, output
    end

    def test_schema_dump_with_without_precision_has_precision_as_nil
      @connection.create_table(:foos, force: true) do |t|
        t.timestamps precision: nil
      end
      output = dump_table_schema("foos")
      assert_match %r{t\.datetime\s+"created_at",\s+precision: nil,\s+null: false$}, output
      assert_match %r{t\.datetime\s+"updated_at",\s+precision: nil,\s+null: false$}, output
    end

    if current_adapter?(:PostgreSQLAdapter)
      def test_datetime_precision_with_zero_should_be_dumped
        @connection.create_table(:foos, force: true) do |t|
          t.timestamps precision: 0
        end
        output = dump_table_schema("foos")
        assert_match %r{t\.datetime\s+"created_at",\s+precision: 0,\s+null: false$}, output
        assert_match %r{t\.datetime\s+"updated_at",\s+precision: 0,\s+null: false$}, output
      end
    end
  end
end