Skip to content

Commit 9b522ce

Browse files
committed
Add validation and constraints for generic_keys length in data types and runtime function definitions
1 parent 49786ec commit 9b522ce

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

app/models/data_type.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class DataType < ApplicationRecord
2626
in: VARIANTS.keys.map(&:to_s),
2727
}
2828

29+
validate :generic_keys_length
30+
2931
validate :validate_recursion, if: :parent_type_changed?
3032

3133
def validate_recursion
@@ -39,4 +41,9 @@ def validate_recursion
3941
end
4042
end
4143
end
44+
45+
def generic_keys_length
46+
errors.add(:generic_keys, 'each key must be 50 characters or fewer') if generic_keys.any? { |key| key.length > 50 }
47+
errors.add(:generic_keys, 'must be 30 or fewer') if generic_keys.size > 30
48+
end
4249
end

app/models/runtime_function_definition.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ class RuntimeFunctionDefinition < ApplicationRecord
1919
validates :runtime_name, presence: true,
2020
length: { minimum: 3, maximum: 50 },
2121
uniqueness: { case_sensitive: false, scope: :runtime_id }
22+
23+
validate :generic_keys_length
24+
25+
def generic_keys_length
26+
errors.add(:generic_keys, 'each key must be 50 characters or fewer') if generic_keys.any? { |key| key.length > 50 }
27+
errors.add(:generic_keys, 'must be 30 or fewer') if generic_keys.size > 30
28+
end
29+
2230
end

db/migrate/20250525192143_implement_generics.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ def change
66
# https://github.com/code0-tech/tucana/pull/93
77

88
add_column :data_types, :generic_keys, 'text[]', null: false, default: []
9+
add_check_constraint :data_types,
10+
"NOT EXISTS (
11+
SELECT 1 FROM unnest(generic_keys) AS key
12+
WHERE length(key) > 50
13+
)", name: 'generic_keys_max_length'
914

1015
create_table :data_type_identifiers do |t|
1116
# One of them needs to be set will be enforced later
@@ -61,6 +66,12 @@ def change
6166

6267
add_column :runtime_function_definitions, :generic_keys, 'text[]', null: false, default: []
6368

69+
add_check_constraint :runtime_function_definitions,
70+
"NOT EXISTS (
71+
SELECT 1 FROM unnest(generic_keys) AS key
72+
WHERE length(key) > 50
73+
)", name: 'generic_keys_max_length'
74+
6475
remove_reference :runtime_parameter_definitions, :data_type,
6576
foreign_key: { to_table: :data_types, on_delete: :restrict }
6677
add_reference :runtime_parameter_definitions, :data_type,

spec/models/data_type_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
describe 'validations' do
1616
it { is_expected.to allow_values(*described_class::VARIANTS.keys).for(:variant) }
1717

18+
context 'when generic keys are too long' do
19+
let(:data_type) { build(:data_type, generic_keys: Array.new(31, 'a' * 51)) } # 31 keys, each 51 characters long
20+
21+
it 'is expected to be invalid' do
22+
expect(data_type).not_to be_valid
23+
expect(data_type.errors[:generic_keys]).to include('each key must be 50 characters or fewer')
24+
expect(data_type.errors[:generic_keys]).to include('must be 30 or fewer')
25+
end
26+
end
27+
1828
it 'detects recursions' do
1929
dt1 = create(:data_type)
2030
dt2 = create(:data_type, parent_type: create(:data_type_identifier, data_type: dt1))

spec/models/runtime_function_definition_spec.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,26 @@
33
require 'rails_helper'
44

55
RSpec.describe RuntimeFunctionDefinition do
6-
subject { create(:runtime_function_definition) }
6+
subject(:function) { create(:runtime_function_definition) }
77

88
describe 'validations' do
99
it { is_expected.to have_many(:parameters).inverse_of(:runtime_function_definition) }
1010

1111
it { is_expected.to validate_presence_of(:runtime_name) }
1212
it { is_expected.to validate_uniqueness_of(:runtime_name).case_insensitive.scoped_to(:runtime_id) }
1313
it { is_expected.to validate_length_of(:runtime_name).is_at_most(50) }
14+
15+
context 'when generic keys are too long' do
16+
before do
17+
function.generic_keys = Array.new(31, 'a' * 51) # 31 keys, each 51 characters long
18+
end
19+
20+
it 'is expected to be invalid' do
21+
expect(function).not_to be_valid
22+
expect(function.errors[:generic_keys]).to include('each key must be 50 characters or fewer')
23+
expect(function.errors[:generic_keys]).to include('must be 30 or fewer')
24+
end
25+
end
1426
end
1527

1628
describe 'associations' do

0 commit comments

Comments
 (0)