Skip to content

Commit c31fd26

Browse files
authored
Fix types taking into account types cast (#96)
1 parent 8f6d184 commit c31fd26

File tree

7 files changed

+124
-36
lines changed

7 files changed

+124
-36
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22
All notable changes to this project will be documented in this file.
33

4+
## [6.9.2] - 2025-10-03
5+
### Fixed
6+
- Fix of all types taking type cast into account
7+
48
## [6.9.1] - 2025-10-02
59
### Fixed
610
- DateTime can be String now

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
table_sync (6.9.1)
4+
table_sync (6.9.2)
55
memery
66
rabbit_messaging (>= 1.7.0)
77
rails

lib/table_sync/utils/schema/builder/active_record.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ def type(value)
2828
ActiveModel::Type::Date,
2929
ActiveModel::Type::Time
3030
Type::DATETIME
31-
when ActiveModel::Type::Integer
32-
Type::INTEGER
33-
when ActiveModel::Type::Decimal,
31+
when ActiveModel::Type::Integer,
32+
ActiveModel::Type::Decimal,
3433
ActiveModel::Type::Float,
3534
ActiveModel::Type::BigInteger
3635
Type::DECIMAL

lib/table_sync/utils/schema/builder/sequel.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ def type(value)
2525
Type::STRING
2626
when :datetime, :date, :time
2727
Type::DATETIME
28-
when :integer
29-
Type::INTEGER
30-
when :decimal, :float
28+
when :integer, :decimal, :float
3129
Type::DECIMAL
3230
when :boolean
3331
Type::BOOLEAN

lib/table_sync/utils/schema/validator/type.rb

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,53 @@
33
class TableSync::Utils::Schema
44
class Validator
55
class Type
6+
class Decimal < Type
7+
def valid?(value)
8+
!Float(value, exception: false).nil?
9+
end
10+
end
11+
12+
class DateTime < Type
13+
def valid?(value)
14+
Date._parse(value.to_s).any?
15+
end
16+
end
17+
18+
class Boolean < Type
19+
def valid?(value)
20+
%w[true false t f 0 1 on off].include?(value.to_s.downcase)
21+
end
22+
end
23+
24+
class Text < Type
25+
def valid?(value)
26+
return true if value.is_a?(::String)
27+
return true if value.is_a?(::Symbol)
28+
return true if Type::DECIMAL.valid?(value)
29+
return true if Type::BOOLEAN.valid?(value)
30+
return true if Type::DATETIME.valid?(value)
31+
false
32+
end
33+
end
34+
635
attr_reader :display_name
7-
attr_reader :klasses
836

9-
def initialize(display_name, klasses)
37+
def initialize(display_name)
1038
@display_name = display_name
11-
@klasses = klasses
1239
end
1340

41+
# @!method valid?
42+
1443
# rubocop:disable Layout/ClassStructure
15-
STRING = new("String", [String]).freeze
16-
DATETIME = new("DateTime", [String, ::Sequel::SQLTime, Date, Time, DateTime]).freeze
17-
INTEGER = new("Integer", [Integer]).freeze
18-
DECIMAL = new("Decimal", [Numeric]).freeze
19-
BOOLEAN = new("Boolean", [TrueClass, FalseClass]).freeze
44+
DECIMAL = Decimal.new("Decimal")
45+
DATETIME = DateTime.new("DateTime")
46+
BOOLEAN = Boolean.new("Boolean")
47+
STRING = Text.new("String")
2048
# rubocop:enable Layout/ClassStructure
2149

2250
def validate(value)
2351
return if value.nil?
24-
return if klasses.any? { |klass| value.is_a?(klass) }
52+
return if valid?(value)
2553
"expected #{display_name}, got: #{value.class}"
2654
end
2755

lib/table_sync/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module TableSync
4-
VERSION = "6.9.1"
4+
VERSION = "6.9.2"
55
end

spec/receiving/models_spec.rb

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -592,29 +592,88 @@
592592
end
593593

594594
describe "#validate_types" do
595-
let(:data) do
596-
[
597-
id: 1,
598-
string: nil,
599-
datetime: "string",
600-
integer: 10.5,
601-
decimal: "string",
602-
array: "string",
603-
boolean: "string",
604-
version: 123.456,
595+
shared_examples "returns success" do |field, value|
596+
context "with #{value}" do
597+
specify do
598+
result = types_test.validate_types([id: 1, field => value])
599+
expect(result).to be_nil
600+
end
601+
end
602+
end
603+
604+
shared_examples "returns error" do |field, value, got|
605+
context "with #{value}" do
606+
specify do
607+
result = types_test.validate_types([id: 1, field => value])
608+
expect(result[field]).to include("got: #{got}")
609+
end
610+
end
611+
end
612+
613+
context "Decimal" do
614+
values = ["1.5", 1.5, 1, "-1.567", BigDecimal("1.5"), Time.current]
615+
values.each do |value|
616+
it_behaves_like "returns success", :decimal, value
617+
end
618+
619+
it_behaves_like "returns error", :decimal, {}, "Hash"
620+
it_behaves_like "returns error", :decimal, [], "Array"
621+
it_behaves_like "returns error", :decimal, "test", "String"
622+
it_behaves_like "returns error", :decimal, true, "TrueClass"
623+
end
624+
625+
context "DateTime" do
626+
values = [
627+
"01.01.2010",
628+
Time.current, Date.current, DateTime.current,
629+
Sequel::SQLTime.date,
630+
123, 123.5, BigDecimal("123.5")
605631
]
632+
values.each do |value|
633+
it_behaves_like "returns success", :datetime, value
634+
end
635+
636+
it_behaves_like "returns error", :datetime, {}, "Hash"
637+
it_behaves_like "returns error", :datetime, [], "Array"
638+
it_behaves_like "returns error", :datetime, "test", "String"
639+
it_behaves_like "returns error", :datetime, true, "TrueClass"
640+
it_behaves_like "returns error", :datetime, 0, "Integer"
641+
it_behaves_like "returns error", :datetime, 0.1, "Float"
606642
end
607-
let(:error) do
608-
{
609-
integer: "expected Integer, got: Float",
610-
decimal: "expected Decimal, got: String",
611-
boolean: "expected Boolean, got: String",
612-
}
643+
644+
context "Boolean" do
645+
values = [
646+
true, false,
647+
0, 1,
648+
"true", "false", "TRUE", "False", "tRuE", "t", "f", "on", "off", "0", "1"
649+
]
650+
values.each do |value|
651+
it_behaves_like "returns success", :boolean, value
652+
end
653+
654+
it_behaves_like "returns error", :boolean, {}, "Hash"
655+
it_behaves_like "returns error", :boolean, [], "Array"
656+
it_behaves_like "returns error", :boolean, "test", "String"
657+
it_behaves_like "returns error", :boolean, 10, "Integer"
658+
it_behaves_like "returns error", :boolean, -1, "Integer"
659+
it_behaves_like "returns error", :boolean, 1.5, "Float"
660+
it_behaves_like "returns error", :boolean, Time.current, "Time"
613661
end
614662

615-
it "raises TableSync::DataError" do
616-
result = types_test.validate_types(data)
617-
expect(result).to eq(error)
663+
context "String" do
664+
values = [
665+
true, false,
666+
"asfdnk", "1.5", "-1", "t", "f", :test,
667+
BigDecimal(45435), 1, 1.5, -1, 0,
668+
Time.current, Sequel::SQLTime.date
669+
]
670+
values.each do |value|
671+
it_behaves_like "returns success", :string, value
672+
end
673+
674+
it_behaves_like "returns error", :string, {}, "Hash"
675+
it_behaves_like "returns error", :string, [], "Array"
676+
it_behaves_like "returns error", :string, String, "Class"
618677
end
619678
end
620679

0 commit comments

Comments
 (0)