|
1 | 1 | # encoding: utf-8 |
2 | 2 | require 'cases/sqlserver_helper' |
| 3 | +require 'models/event' |
| 4 | + |
| 5 | +class Event < ActiveRecord::Base |
| 6 | + before_validation :strip_mb_chars_for_sqlserver |
| 7 | + protected |
| 8 | + def strip_mb_chars_for_sqlserver |
| 9 | + self.title = title.mb_chars.to(4).to_s if title && title.is_utf8? |
| 10 | + end |
| 11 | +end |
3 | 12 |
|
4 | 13 | class UniquenessValidationTestSqlserver < ActiveRecord::TestCase |
5 | 14 | end |
6 | 15 |
|
7 | 16 | class UniquenessValidationTest < ActiveRecord::TestCase |
8 | 17 |
|
9 | | - # COERCED_TESTS = [:test_validate_uniqueness_with_limit_and_utf8] |
| 18 | + COERCED_TESTS = [:test_validate_uniqueness_with_limit_and_utf8] |
10 | 19 |
|
11 | | - # include SqlserverCoercedTest |
| 20 | + include SqlserverCoercedTest |
12 | 21 |
|
13 | | - # This test is tricky to pass. The validation SQL would generate something like this: |
14 | | - # |
15 | | - # SELECT TOP 1 [events].id FROM [events] WHERE ([events].[title] COLLATE Latin1_General_CS_AS = '一二三四五') |
16 | | - # |
17 | | - # The problem is that we can not change the adapters quote method from this: |
18 | | - # |
19 | | - # elsif column && column.respond_to?(:is_utf8?) && column.is_utf8? |
20 | | - # quoted_utf8_value(value) |
| 22 | + # I guess most databases just truncate a string when inserting. To pass this test we do a few things. |
| 23 | + # First, we make sure the type is unicode safe, second we extend the limit to well beyond what is |
| 24 | + # needed. At the top we make sure to auto truncate the :title string like other databases would do |
| 25 | + # automatically. |
21 | 26 | # |
22 | | - # To something like this for all quoting like blind bind vars: |
23 | | - # |
24 | | - # elsif value.is_utf8? |
25 | | - # quoted_utf8_value(value) |
26 | | - # |
27 | | - # As it would cause way more errors, sure this piggybacks on ActiveSupport's 1.8/1.9 abstract |
28 | | - # code to infer if the passed in string is indeed a national/unicde type. Perhaps in rails 3 |
29 | | - # and using AREL this might get better, but I do not see a solution right now. |
30 | | - # |
31 | | - # def test_coerced_test_validate_uniqueness_with_limit_and_utf8 |
32 | | - # assert true |
33 | | - # end |
| 27 | + # "一二三四五".mb_chars.size # => 5 |
| 28 | + # "一二三四五六七八".mb_chars.size # => 8 |
| 29 | + # "一二三四五六七八".mb_chars.to(4).to_s # => "一二三四五" |
| 30 | + |
| 31 | + def test_coerced_validate_uniqueness_with_limit_and_utf8 |
| 32 | + with_kcode('UTF8') do |
| 33 | + Event.connection.change_column :events, :title, :nvarchar, :limit => 30 |
| 34 | + Event.reset_column_information |
| 35 | + # Now the actual test copied from core. |
| 36 | + e1 = Event.create(:title => "一二三四五") |
| 37 | + assert e1.valid?, "Could not create an event with a unique, 5 character title" |
| 38 | + e2 = Event.create(:title => "一二三四五六七八") |
| 39 | + assert !e2.valid?, "Created an event whose title, with limit taken into account, is not unique" |
| 40 | + end |
| 41 | + end |
34 | 42 |
|
35 | 43 | end |
36 | 44 |
|
0 commit comments