activerecord-databasevalidations 0.5.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dbf207cb2907bee539a88662d3db30dc5ed839798cbfd9cfd85825477c2eb239
4
- data.tar.gz: daf34dab34b3d74bfc478c96f83fb49e6058a04fdd5351200fdb845707f87967
3
+ metadata.gz: 2f077f16b8f0e2832a0e5d50c3e4ce45953725296ce0bcf31f1715413e362c2e
4
+ data.tar.gz: 8f82f37b686c7cdd222dae109c1a13caabfcc1086e5be71d0defee5b02dc89a8
5
5
  SHA512:
6
- metadata.gz: 8e9be16afadaa21e4954ef0f5cee4d3a890831e3b3b18b19b020363121d774138bd98063ba40334988825f4fd4821daf5ca495f6f76e5fa42a17155ec962d2d2
7
- data.tar.gz: b4dbec89f5d44fd5a6235147fe8dd98a97cb6e4a37cca1e804d977091c80ea4054d781b7fcf61e9fb93a9bfcf02c191606ac2b751e20efe1a8aa75cdb0da62af
6
+ metadata.gz: 5e34412eb9b7662b4a972de4bfff63cc7ff5eb40880965ad9531ce8aed174d0d203015481f6b7c2b4bfe16bc0a1ffd9081ea88e4ceefb2d0f2ddf886cad6457e
7
+ data.tar.gz: e36e86a6bbbc6ed588a23a2b509193f0dfa788957a3d1c2b7ea06e81e8e957f41b8e529a2be5f24d087d83f1a67f63e00e06d7278a9289d800d561f1f6a8b22e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # Unreleased
2
+
3
+ # 1.0.0 (May 12, 2021)
4
+
5
+ * Removed the utf8mb3 validator as it is a bit anachronistic in 2021.
6
+
1
7
  # 0.5.1 (May 22, 2020)
2
8
 
3
9
  * Fix various Ruby 2.7 warnings
data/README.md CHANGED
@@ -30,7 +30,7 @@ to validate based on the database constraints.
30
30
  ``` ruby
31
31
  class Foo < ActiveRecord::Base
32
32
  validates :boolean_field, database_constraints: :not_null
33
- validates :string_field, database_constraints: [:size, :basic_multilingual_plane]
33
+ validates :string_field, database_constraints: [:size]
34
34
  validates :decimal_field, :integer_field, database_constraints: :range
35
35
  end
36
36
  ```
@@ -50,8 +50,6 @@ You have to specify what conatrints you want to validate for. Valid values are:
50
50
  - `:range` to validate the numeric range of a column based on it's type.
51
51
  - `:size` to validate for the size of textual and binary columns. It will pick character
52
52
  size or bytesize based on the column's type.
53
- - `:basic_multilingual_plane` to validate that all characters for text fields are inside
54
- the basic multilingual plane of unicode (unless you use the utf8mb4 character set).
55
53
  - `:not_null` to validate a NOT NULL contraint.
56
54
 
57
55
  The validations will only be created if it makes sense for the column, e.g. a `:not_null`
@@ -63,7 +61,7 @@ You can also instantiate the validators yourself:
63
61
 
64
62
  ``` ruby
65
63
  class Bar < ActiveRecord::Base
66
- validates :string_field, bytesize: { maximum: 255 }, basic_multilingual_plane: true
64
+ validates :string_field, bytesize: { maximum: 255 }
67
65
  validates :string_field, not_null: true
68
66
  end
69
67
  ```
@@ -21,7 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = '>= 2.5'
22
22
 
23
23
  spec.add_runtime_dependency "activerecord", ">= 5.2"
24
- spec.add_runtime_dependency "rejectu"
25
24
 
26
25
  spec.add_development_dependency "bundler"
27
26
  spec.add_development_dependency "rake"
@@ -4,5 +4,4 @@ en:
4
4
  # The value :count is available when applicable. Can be used for pluralization.
5
5
  messages:
6
6
  too_many_bytes: "is too long (maximum is %{count} bytes)"
7
- characters_outside_basic_multilingual_plane: "contains characters outside Unicode's basic multilingual plane"
8
7
  must_be_set: "must be set"
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module DatabaseValidations
3
- VERSION = "0.5.1"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -1,13 +1,12 @@
1
1
  require 'active_model/validations/bytesize'
2
2
  require 'active_model/validations/not_null'
3
- require 'active_model/validations/basic_multilingual_plane'
4
3
 
5
4
  module ActiveRecord
6
5
  module Validations
7
6
  class DatabaseConstraintsValidator < ActiveModel::EachValidator
8
7
  attr_reader :constraints
9
8
 
10
- VALID_CONSTRAINTS = Set[:size, :basic_multilingual_plane, :not_null, :range]
9
+ VALID_CONSTRAINTS = Set[:size, :not_null, :range]
11
10
 
12
11
  SIZE_VALIDATORS_FOR_TYPE = {
13
12
  characters: ActiveModel::Validations::LengthValidator,
@@ -55,12 +54,6 @@ module ActiveRecord
55
54
  ActiveModel::Validations::NumericalityValidator.new(args)
56
55
  end
57
56
 
58
- def basic_multilingual_plane_validator(klass, column)
59
- return unless constraints.include?(:basic_multilingual_plane)
60
- return unless column.text? && column.collation =~ /\Autf8(?:mb3)?_/
61
- ActiveModel::Validations::BasicMultilingualPlaneValidator.new(attributes: [column.name.to_sym], class: klass)
62
- end
63
-
64
57
  def attribute_validators(klass, attribute)
65
58
  @constraint_validators[attribute] ||= begin
66
59
  column_definition = klass.columns_hash[attribute.to_s]
@@ -74,7 +67,6 @@ module ActiveRecord
74
67
  [
75
68
  not_null_validator(klass, column),
76
69
  size_validator(klass, column),
77
- basic_multilingual_plane_validator(klass, column),
78
70
  range_validator(klass, column),
79
71
  ].compact
80
72
  end
@@ -3,7 +3,7 @@
3
3
  require 'test_helper'
4
4
 
5
5
  ActiveRecord::Migration.suppress_messages do
6
- ActiveRecord::Migration.create_table("unicorns", force: true, options: "CHARACTER SET utf8mb3") do |t|
6
+ ActiveRecord::Migration.create_table("unicorns", force: true) do |t|
7
7
  t.column :string, "VARCHAR(40)"
8
8
  t.column :tinytext, "TINYTEXT"
9
9
  t.column :blob, "BLOB"
@@ -97,11 +97,4 @@ class DataLossTest < Minitest::Test
97
97
  refute_data_loss Unicorn.new(blob: [].pack('x65535')) # 65535 is bytesize limit of blob field
98
98
  assert_data_loss Unicorn.new(blob: [].pack('x65536'))
99
99
  end
100
-
101
- def test_utf8mb3_field_sliently_truncates_strings_after_first_4byte_character
102
- emoji = "\u{1F4A9}"
103
- assert_equal 1, emoji.length
104
- assert_equal 4, emoji.bytesize
105
- assert_data_loss Unicorn.new(string: emoji)
106
- end
107
100
  end
data/test/database.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  test:
2
2
  adapter: mysql2
3
3
  database: database_validations
4
- username: travis
4
+ #username: travis
5
+ host: localhost
6
+ username: root
5
7
  encoding: utf8mb4
6
8
  strict: false
@@ -13,10 +13,6 @@ ActiveRecord::Migration.suppress_messages do
13
13
  t.integer :unchecked, null: false
14
14
  end
15
15
 
16
- ActiveRecord::Migration.create_table("bars", force: true, options: "CHARACTER SET utf8mb4") do |t|
17
- t.string :mb4_string
18
- end
19
-
20
16
  ActiveRecord::Migration.create_table("empties", force: true)
21
17
 
22
18
  ActiveRecord::Migration.create_table("nums", force: true) do |t|
@@ -34,11 +30,7 @@ end
34
30
  class Foo < ActiveRecord::Base
35
31
  validates :string, :tinytext, :varbinary, :blob, database_constraints: :size
36
32
  validates :checked, database_constraints: :not_null
37
- validates :not_null_text, database_constraints: [:size, :basic_multilingual_plane]
38
- end
39
-
40
- class Bar < ActiveRecord::Base
41
- validates :mb4_string, database_constraints: :basic_multilingual_plane
33
+ validates :not_null_text, database_constraints: [:size]
42
34
  end
43
35
 
44
36
  class Empty < ActiveRecord::Base
@@ -55,10 +47,10 @@ class DatabaseConstraintsValidatorTest < Minitest::Test
55
47
  include DataLossAssertions
56
48
 
57
49
  def test_argument_validation
58
- assert_raises(ArgumentError) { Bar.validates(:mb4_string, database_constraints: []) }
59
- assert_raises(ArgumentError) { Bar.validates(:mb4_string, database_constraints: true) }
60
- assert_raises(ArgumentError) { Bar.validates(:mb4_string, database_constraints: :bogus) }
61
- assert_raises(ArgumentError) { Bar.validates(:mb4_string, database_constraints: [:size, :bogus]) }
50
+ assert_raises(ArgumentError) { Foo.validates(:string, database_constraints: []) }
51
+ assert_raises(ArgumentError) { Foo.validates(:string, database_constraints: true) }
52
+ assert_raises(ArgumentError) { Foo.validates(:string, database_constraints: :bogus) }
53
+ assert_raises(ArgumentError) { Foo.validates(:string, database_constraints: [:size, :bogus]) }
62
54
  end
63
55
 
64
56
  def test_column_validation
@@ -104,10 +96,9 @@ class DatabaseConstraintsValidatorTest < Minitest::Test
104
96
  def test_not_null_text_field_defines_requested_bytesize_validator_and_unicode_validator
105
97
  validator = Foo._validators[:not_null_text].first
106
98
  subvalidators = validator.attribute_validators(Foo, :not_null_text)
107
- assert_equal 2, subvalidators.length
99
+ assert_equal 1, subvalidators.length
108
100
 
109
101
  assert_kind_of ActiveModel::Validations::BytesizeValidator, subvalidators.first
110
- assert_kind_of ActiveModel::Validations::BasicMultilingualPlaneValidator, subvalidators.second
111
102
  assert_equal 65535, subvalidators.first.options[:maximum]
112
103
  assert_equal Encoding.find('utf-8'), subvalidators.first.encoding
113
104
  end
@@ -118,13 +109,6 @@ class DatabaseConstraintsValidatorTest < Minitest::Test
118
109
  refute Foo.new(checked: nil).valid?
119
110
  end
120
111
 
121
- def test_should_not_create_a_validator_for_a_utf8mb4_field
122
- assert Bar._validators[:mb4_string].first.attribute_validators(Bar, :mb4_string).empty?
123
- emoji = Bar.new(mb4_string: '')
124
- assert emoji.valid?
125
- refute_data_loss emoji
126
- end
127
-
128
112
  def test_decimal_range
129
113
  subvalidators = Num._validators[:decimal].first.attribute_validators(Num, :decimal)
130
114
  assert_equal 1, subvalidators.length
@@ -219,7 +203,6 @@ class DatabaseConstraintsValidatorTest < Minitest::Test
219
203
 
220
204
  assert_equal ["is too long (maximum is 40 characters)"], foo.errors[:string]
221
205
  assert_equal ["must be set"], foo.errors[:checked]
222
- assert_equal ["contains characters outside Unicode's basic multilingual plane"], foo.errors[:not_null_text]
223
206
  end
224
207
 
225
208
  def test_encoding_craziness
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-databasevalidations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willem van Bergen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-22 00:00:00.000000000 Z
11
+ date: 2021-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.2'
27
- - !ruby/object:Gem::Dependency
28
- name: rejectu
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: bundler
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -112,7 +98,6 @@ files:
112
98
  - activerecord-databasevalidations.gemspec
113
99
  - gemfiles/Gemfile.activerecord52
114
100
  - gemfiles/Gemfile.activerecord60
115
- - lib/active_model/validations/basic_multilingual_plane.rb
116
101
  - lib/active_model/validations/bytesize.rb
117
102
  - lib/active_model/validations/not_null.rb
118
103
  - lib/active_record/database_validations.rb
@@ -126,7 +111,6 @@ files:
126
111
  - lib/active_record/validations/typed_column.rb
127
112
  - lib/activerecord-databasevalidations.rb
128
113
  - lib/activerecord/databasevalidations.rb
129
- - test/basic_multilingual_plane_validator_test.rb
130
114
  - test/bytesize_validator_test.rb
131
115
  - test/data_loss_test.rb
132
116
  - test/database.yml
@@ -139,7 +123,7 @@ homepage: https://github.com/wvanbergen/activerecord-database_validations
139
123
  licenses:
140
124
  - MIT
141
125
  metadata: {}
142
- post_install_message:
126
+ post_install_message:
143
127
  rdoc_options: []
144
128
  require_paths:
145
129
  - lib
@@ -154,12 +138,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
138
  - !ruby/object:Gem::Version
155
139
  version: '0'
156
140
  requirements: []
157
- rubygems_version: 3.1.2
158
- signing_key:
141
+ rubygems_version: 3.1.4
142
+ signing_key:
159
143
  specification_version: 4
160
144
  summary: Add validations to your ActiveRecord models based on MySQL database constraints.
161
145
  test_files:
162
- - test/basic_multilingual_plane_validator_test.rb
163
146
  - test/bytesize_validator_test.rb
164
147
  - test/data_loss_test.rb
165
148
  - test/database.yml
@@ -1,27 +0,0 @@
1
- require 'rejectu/rejectu'
2
-
3
- module ActiveModel
4
- module Validations
5
- class BasicMultilingualPlaneValidator < ActiveModel::EachValidator
6
- OUTSIDE_BMP = /[^\u{0}-\u{FFFF}]/
7
-
8
- def validate_each(record, attribute, value)
9
- return if value.nil?
10
- return if value.to_s.encoding != Encoding::UTF_8
11
-
12
- unless Rejectu.valid?(value.to_s)
13
- errors_options = options.except(:characters_outside_basic_multilingual_plane)
14
- default_message = options[:characters_outside_basic_multilingual_plane]
15
- errors_options[:message] ||= default_message if default_message
16
- record.errors.add(attribute, :characters_outside_basic_multilingual_plane, **errors_options)
17
- end
18
- end
19
- end
20
-
21
- module HelperMethods
22
- def validates_basic_multilingual_plane_of(*attr_names)
23
- validates_with ActiveModel::Validations::BasicMultilingualPlaneValidator, _merge_attributes(attr_names)
24
- end
25
- end
26
- end
27
- end
@@ -1,54 +0,0 @@
1
- # encoding: utf-8
2
- require 'test_helper'
3
-
4
- class BasicMultilingualPlaneValidatorTest < Minitest::Test
5
-
6
- class Model
7
- include ActiveModel::Validations
8
-
9
- attr_accessor :unicode
10
- validates :unicode, basic_multilingual_plane: true
11
- end
12
-
13
- def setup
14
- @model = Model.new
15
- end
16
-
17
- def test_basic_multilingual_plane_string
18
- @model.unicode = 'basic multilingual ünicode'
19
- assert @model.valid?
20
-
21
- end
22
-
23
- def test_emoji
24
- @model.unicode = '💩'
25
- assert @model.invalid?
26
- assert_equal ["contains characters outside Unicode's basic multilingual plane"], @model.errors[:unicode]
27
- end
28
-
29
- def test_nil
30
- @model.unicode = nil
31
- assert @model.valid?
32
- end
33
-
34
- def test_different_type
35
- @model.unicode = 1
36
- assert @model.valid?
37
- end
38
-
39
- def test_non_unicode_encoding
40
- @model.unicode = 'ü'.encode('ISO-8859-15')
41
- assert @model.valid?
42
- end
43
-
44
- def test_utf8mb3_japanese
45
- @model.unicode = 'これは普通なストリングです'
46
- assert @model.valid?
47
- end
48
-
49
- def test_utf8mb4_kanji
50
- @model.unicode = '𠜎𠜱𠝹𠱓𠱸𠲖𠳏𠳕𠴕𠵼𠵿𠸎𠸏𠹷'
51
- assert @model.invalid?
52
- assert_equal ["contains characters outside Unicode's basic multilingual plane"], @model.errors[:unicode]
53
- end
54
- end