schemacop 3.0.35 → 3.0.36

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: 80f588e0e3422fa0fea90f6725f48cb7eab64b7b2d6158e93e05496bc51f7565
4
- data.tar.gz: 18b0514093843e7b1065e3b2c102263cbb4afa708cf8fa13f7c404cbec037abe
3
+ metadata.gz: 9494f9a5a921664fae74b99ecba0830775d160ae91250465b4b88ba1d1fdf970
4
+ data.tar.gz: 2263f93913342b872ac56c52ddd65dd6c34f34711d3624c52c6ffc2d5a9a516a
5
5
  SHA512:
6
- metadata.gz: f54e94a656fa9df82c4adde9f81d60a5f93b673018a8f9d50a80c755aa2b67ec362eeace426a1b4fcd9cbd4a0af8100b845b876afc37a2de5dac82a8b14acd6f
7
- data.tar.gz: 8e362b61caf5ba6f885cef3014e53677e3d76775f31945fc70b0a7400cf465d5c28a0a6c053288e38a4642f8dd13b60cd35047dfe58a5fb8c88eecafc65c9499
6
+ metadata.gz: 3712232ba9d867f723ee462d80db875d6e0adbd6cd0579d798908df58f9fd9b5448389e2cc9829fe979bdcd972efa209a4b2ae6a27766d8d7884fa3a7189c4ab
7
+ data.tar.gz: fd5c87120fb0c2d1a1e13122013b08d902d37a32154d1196385ad6f2fb5fec28b54c0170f129533c7ce116ccadd13c7c653832f2102cfc4c63da62257170ee3a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Change log
2
2
 
3
+ ## 3.0.36 (2026-01-05)
4
+
5
+ * Fix `v3_default_options` not being applied when schemas are eager loaded in
6
+ production mode. The Railtie now explicitly loads `config/schemacop.rb`
7
+ during initialization, before eager loading schemas. This ensures that
8
+ default options like `cast_str` are applied to all schemas.
9
+
10
+ For Rails applications, place your Schemacop configuration in
11
+ `config/schemacop.rb` (not in the `initializers/` subdirectory) to benefit
12
+ from this fix. Configuration in `config/initializers/schemacop.rb` will
13
+ continue to work in development mode but will not be applied to eager-loaded
14
+ schemas in production mode (same behavior as in 3.0.35 and earlier).
15
+
16
+ Internal reference: `#144209`.
17
+
18
+ * Fix test compatibility with Ruby 3.2+ by updating JSON parse error regex
19
+ patterns to match the new error message format introduced in Ruby 3.2.
20
+
3
21
  ## 3.0.35 (2025-07-31)
4
22
 
5
23
  * Add option `max_precision` to `number` nodes for Schemacop V3 schemas to validate
data/README_V2.md CHANGED
@@ -61,7 +61,7 @@ gem 'schemacop'
61
61
  ## Basics
62
62
 
63
63
  Since there is no explicit typing in Ruby, it can be hard to make sure that a
64
- method is recieving exactly the right kind of data it needs. The idea of this
64
+ method is receiving exactly the right kind of data it needs. The idea of this
65
65
  gem is to define a schema at boot time that will validate the data being passed
66
66
  around at runtime. Those two steps look as follows:
67
67
 
@@ -84,7 +84,7 @@ my_schema.validate!(
84
84
  `validate!` will fail if the data given to it does not match what was specified
85
85
  in the schema.
86
86
 
87
- ### Type lines vs. Field lines
87
+ ### Type Lines vs. Field Lines
88
88
 
89
89
  Schemacop uses a DSL (domain-specific language) to let you describe your
90
90
  schemas. We distinguish between two kinds of identifiers:
@@ -309,7 +309,7 @@ end
309
309
  You might find the notation cumbersome, and you'd be right to say so. Luckily
310
310
  there are plenty of short forms available which we will see below.
311
311
 
312
- #### Handling hashes with indifferent access
312
+ #### Handling Hashes with Indifferent Access
313
313
 
314
314
  Schemacop has special handling for objects of the class
315
315
  `ActiveSupport::HashWithIndifferentAccess`: You may specify the keys as symbols
@@ -403,12 +403,12 @@ The following types are supported by Schemacop by default:
403
403
  All types support the options `if` and `check` (see the section about Type Lines
404
404
  above).
405
405
 
406
- ## Short forms
406
+ ## Short Forms
407
407
 
408
408
  For convenience, the following short forms may be used (and combined if
409
409
  possible).
410
410
 
411
- ### Passing a type to a Field Line or schema
411
+ ### Passing a Type to a Field Line or Schema
412
412
 
413
413
  Instead of adding a Type Line in the block of a Field Line, you can omit `do
414
414
  type ... end` and directly write the type after the key of the field.
@@ -444,7 +444,7 @@ Schema.new(:string, min: 2, max: 5)
444
444
  This means that the data given to the schema must be a String that is between 2
445
445
  and 5 characters long.
446
446
 
447
- ### Passing multiple types at once
447
+ ### Passing Multiple Types at Once
448
448
 
449
449
  You can specify several types at once by putting them in an array.
450
450
 
@@ -522,7 +522,7 @@ Note that this does not allow you to specify any options for the hash itself.
522
522
  You still need to specify `:hash` as a type if you want to pass any options to
523
523
  the hash (i.e. a `default`).
524
524
 
525
- ### Shortform for subtypes
525
+ ### Shortform for Subtypes
526
526
 
527
527
  In case of nested arrays, you can group all Type Lines to a single one.
528
528
 
@@ -638,14 +638,14 @@ Schema.new do
638
638
  end
639
639
  ```
640
640
 
641
- ### Required data points
641
+ ### Required Data Points
642
642
 
643
643
  Note that any *required* validation is done before applying the defaults. If you
644
644
  specify a `req` field, it must always be given, no matter if you have specified
645
645
  a default or not. Therefore, specifying `req` fields do not make sense in
646
646
  conjunction with defaults, as the default is always ignored.
647
647
 
648
- ## Type casting
648
+ ## Type Casting
649
649
 
650
650
  Starting from version 2.4.0, Schemacop allows you to specify type castings that
651
651
  can alter the validated data. Consider the following:
@@ -663,7 +663,7 @@ Note that Schemacop never modifies the data you pass to it. If you want to
663
663
  benefit from Schemacop-applied castings, you need to access the cloned, modified
664
664
  data returned by `validate` or `validate!`.
665
665
 
666
- ### Specifying type castings
666
+ ### Specifying Type Castings
667
667
 
668
668
  Type castings can be specified using two forms: Either as a hash or as an array.
669
669
  While using an array only allows you to specify the supported source types to be
@@ -689,7 +689,7 @@ Schema.new do
689
689
  end
690
690
  ```
691
691
 
692
- ### Built-in casters
692
+ ### Built-in Casters
693
693
 
694
694
  Schemacop comes with the following casters:
695
695
 
@@ -702,7 +702,7 @@ an error if casted to an Integer. When casting float values and strings
702
702
  containing float values to integers, the decimal places will be discarded
703
703
  however.
704
704
 
705
- ### Execution order
705
+ ### Execution Order
706
706
 
707
707
  The casting is done *before* the options `if` and `check` are evaluated.
708
708
  Example:
@@ -748,7 +748,7 @@ Schemacop will throw one of the following checked exceptions:
748
748
  This exception is thrown when the given data does not comply with the given
749
749
  schema definition.
750
750
 
751
- ## Known limitations
751
+ ## Known Limitations
752
752
 
753
753
  * Schemacop does not yet allow cyclic structures with infinite depth.
754
754
 
data/README_V3.md CHANGED
@@ -1,4 +1,4 @@
1
- # Schemacop schema V3
1
+ # Schemacop Schema V3
2
2
 
3
3
  ## Table of Contents
4
4
 
@@ -282,11 +282,11 @@ transformed into various types.
282
282
  #### Custom Formats
283
283
 
284
284
  You can also implement your custom formats or override the behavior of the
285
- standard formats. This can be done in the initializer configuration (in case of
286
- a Rails appliation):
285
+ standard formats. For Rails applications, this can be done in
286
+ `config/schemacop.rb`:
287
287
 
288
288
  ```ruby
289
- # config/initializers/schemacop.rb
289
+ # config/schemacop.rb
290
290
  Schemacop.register_string_formatter(
291
291
  :character_array, # Formatter name
292
292
  pattern: /^[a-zA-Z](,[a-zA-Z])*/, # Regex pattern for validation
@@ -424,7 +424,7 @@ and subclasses are valid:
424
424
  * `Rational`
425
425
  * `BigDecimal`
426
426
 
427
- As some subclasses of `Numeric`, such as `Complex` don't support all required oeprations,
427
+ As some subclasses of `Numeric`, such as `Complex` don't support all required operations,
428
428
  only the above list is supported. If you need support for additional number classes, please
429
429
  contact the Gem maintainers.
430
430
 
@@ -507,7 +507,7 @@ and validating a blank string will return `nil`.
507
507
  If you need a value, use the `required` option:
508
508
 
509
509
  ```ruby
510
- schema = Schemacop::Schema3.new(:number, cast_str: true, minimum: 0.0, maximum: (50r), multiple_of: BigDecimal('0.5'), require: true)
510
+ schema = Schemacop::Schema3.new(:number, cast_str: true, minimum: 0.0, maximum: (50r), multiple_of: BigDecimal('0.5'), required: true)
511
511
  schema.validate!('42.5') # => 42.5
512
512
  schema.validate!(nil) # => Schemacop::Exceptions::ValidationError: /: Value must be given.
513
513
  schema.validate!('') # => Schemacop::Exceptions::ValidationError: /: Value must be given.
@@ -636,7 +636,7 @@ It consists of one or multiple values, which can be validated using arbitrary no
636
636
  must contain to pass the validation.
637
637
 
638
638
  * `unique_items`
639
- This option specifies wether the items in the array must all be distinct from
639
+ This option specifies whether the items in the array must all be distinct from
640
640
  each other, or if there may be duplicate values. By default, this is false,
641
641
  i.e. duplicate values are allowed
642
642
 
@@ -704,13 +704,13 @@ schema.validate!([1, 2, 3]) # => Schemacop::Exceptions::ValidationError: /: At l
704
704
  schema.validate!([1, 3, 5]) # => [1, 3, 5]
705
705
  ```
706
706
 
707
- #### Specifying properties
707
+ #### Specifying Properties
708
708
 
709
709
  Array nodes support a block in which you can specify the required array contents.
710
710
  The array nodes support either list validation, or tuple validation, depending on
711
711
  how you specify your array contents.
712
712
 
713
- ##### List validation
713
+ ##### List Validation
714
714
 
715
715
  List validation validates a sequence of arbitrary length where each item matches
716
716
  the same schema. Unless you specify a `min_items` count on the array node, an
@@ -759,7 +759,7 @@ end
759
759
  # => Schemacop::Exceptions::InvalidSchemaError: You can only use "list" once.
760
760
  ```
761
761
 
762
- ##### Tuple validation
762
+ ##### Tuple Validation
763
763
 
764
764
  On the other hand, tuple validation validates a sequence of fixed length, where
765
765
  each item has its own schema that it has to match. Here, the order of the items
@@ -850,8 +850,8 @@ Using the options `filter` and `reject`, arrays can be filtered. Filtering
850
850
  happens before validation. Both options behave in the same way, with the only
851
851
  difference being that `filter` uses a inclusive approach and `reject` an
852
852
  exclusive (see [filter](https://apidock.com/ruby/Array/filter) and
853
- [reject](https://apidock.com/ruby/Array/reject] in the Ruby API, as they behave
854
- in a similar manor).
853
+ [reject](https://apidock.com/ruby/Array/reject) in the Ruby API, as they behave
854
+ in a similar manner).
855
855
 
856
856
  You can either pass a Symbol which specifies the name of the method that is
857
857
  called on each array item:
@@ -951,11 +951,11 @@ It consists of key-value-pairs that can be validated using arbitrary nodes.
951
951
 
952
952
  Defaults to `false`.
953
953
 
954
- #### Specifying properties
954
+ #### Specifying Properties
955
955
 
956
956
  Hash nodes support a block in which you can specify the required hash contents.
957
957
 
958
- ##### Standard properties
958
+ ##### Standard Properties
959
959
 
960
960
  It supports all type nodes, but requires the suffix `?` or `!` for each
961
961
  property, which specifies whether a property is required (`!`) or optional
@@ -1078,7 +1078,7 @@ schema.validate!({foo: 1}) # => {"foo"=>1}
1078
1078
  schema.validate!({foo: 'bar'}) # => {"foo"=>"bar"}
1079
1079
  ```
1080
1080
 
1081
- ##### Pattern properties
1081
+ ##### Pattern Properties
1082
1082
 
1083
1083
  In addition to symbols, property keys can also be a regular expression. Here,
1084
1084
  you may only use the optional `?` suffix for the property. This allows any
@@ -1098,7 +1098,7 @@ schema.validate!({id_foo: 1, id_bar: 2}) # => {"id_foo"=>1, "id_bar"=>2}
1098
1098
  schema.validate!({foo: 3}) # => Schemacop::Exceptions::ValidationError: /: Obsolete property "foo".
1099
1099
  ```
1100
1100
 
1101
- ##### Additional properties & property names
1101
+ ##### Additional Properties & Property Names
1102
1102
 
1103
1103
  In addition to standard properties, you can allow the hash to contain
1104
1104
  additional, unspecified properties. By default, this is turned off if you have
@@ -1158,7 +1158,7 @@ schema.validate!({foo: :bar}) # => Schemacop::Exceptions::ValidationError:
1158
1158
  schema.validate!({Foo: :bar}) # => Schemacop::Exceptions::ValidationError: /: Property name :Foo does not match "^[a-z]+$". /Foo: Invalid type, got type "Symbol", expected "array".
1159
1159
  ```
1160
1160
 
1161
- ##### Ignoring obsolete properties
1161
+ ##### Ignoring Obsolete Properties
1162
1162
 
1163
1163
  By enabling `ignore_obsolete_properties`, you can filter out any unspecified params,
1164
1164
  while still passing validation:
@@ -1559,7 +1559,7 @@ to use other data in the second context than in the first.
1559
1559
 
1560
1560
  ## External schemas
1561
1561
 
1562
- Finally, Schemacop features the possibility to specify schemas in seperate
1562
+ Finally, Schemacop features the possibility to specify schemas in separate
1563
1563
  files. This is especially useful is you have schemas in your application which
1564
1564
  are used multiple times throughout the application.
1565
1565
 
@@ -1582,7 +1582,7 @@ Where:
1582
1582
  * context schemas: Defined in the current context using `context.schema`
1583
1583
  * global schemas: Defined in a ruby file in the load path
1584
1584
 
1585
- ### External schemas in Rails applications
1585
+ ### External Schemas in Rails Applications
1586
1586
 
1587
1587
  In Rails applications, your schemas are automatically eager-loaded from the load
1588
1588
  path `'app/schemas'` when your application is started, unless your application
@@ -1633,7 +1633,7 @@ schema.validate!({usr: {first_name: 'Joe', last_name: 'Doe', groups: [{name: 'fo
1633
1633
  # => {"usr"=>{"first_name"=>"Joe", "last_name"=>"Doe", "groups"=>[{"name"=>"foo"}, {"name"=>"bar"}]}}
1634
1634
  ```
1635
1635
 
1636
- ### External schemas in Non-Rails applications
1636
+ ### External Schemas in Non-Rails Applications
1637
1637
 
1638
1638
  Usage in non-Rails applications is the same as with usage in Rails applications,
1639
1639
  however you might need to eager load the schemas yourself:
@@ -1651,11 +1651,24 @@ to eager-load them on start of your application / script.
1651
1651
  Using the setting `Schemacop.v3_default_options`, you can specify a hash
1652
1652
  containing default options that will be used for every schemacop node (options
1653
1653
  not supported by a particular node are automatically ignored). Options passed
1654
- directly to a node still take precedence. The setting can be set in an
1655
- initializer:
1654
+ directly to a node still take precedence.
1655
+
1656
+ ### Rails applications
1657
+
1658
+ For Rails applications, configure default options in `config/schemacop.rb`
1659
+ (note: not in the `initializers/` subdirectory). This ensures that options are
1660
+ applied before schemas are eager loaded in production mode:
1661
+
1662
+ ```ruby
1663
+ # config/schemacop.rb
1664
+ Schemacop.v3_default_options = { cast_str: true }.freeze
1665
+ ```
1666
+
1667
+ ### Non-Rails applications
1668
+
1669
+ For non-Rails applications, set the options before loading any schemas:
1656
1670
 
1657
1671
  ```ruby
1658
- # config/initializers/schemacop.rb
1659
1672
  Schemacop.v3_default_options = { cast_str: true }.freeze
1660
1673
 
1661
1674
  # Example schema: As cast_str is enabled in the default options, strings will
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.35
1
+ 3.0.36
@@ -1,6 +1,13 @@
1
1
  module Schemacop
2
2
  class Railtie < Rails::Railtie
3
3
  initializer 'schemacop' do
4
+ # Load configuration
5
+ config_path = Rails.root.join('config', 'schemacop.rb')
6
+
7
+ if config_path.exist?
8
+ load config_path
9
+ end
10
+
4
11
  # Load global schemas
5
12
  unless Rails.env.development?
6
13
  V3::GlobalContext.eager_load!
data/schemacop.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: schemacop 3.0.35 ruby lib
2
+ # stub: schemacop 3.0.36 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "schemacop".freeze
6
- s.version = "3.0.35".freeze
6
+ s.version = "3.0.36".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
10
10
  s.authors = ["Sitrox".freeze]
11
- s.date = "2025-07-31"
11
+ s.date = "2026-01-05"
12
12
  s.files = [".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, ".yardopts".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "README_V2.md".freeze, "README_V3.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "lib/schemacop.rb".freeze, "lib/schemacop/base_schema.rb".freeze, "lib/schemacop/exceptions.rb".freeze, "lib/schemacop/railtie.rb".freeze, "lib/schemacop/schema.rb".freeze, "lib/schemacop/schema2.rb".freeze, "lib/schemacop/schema3.rb".freeze, "lib/schemacop/scoped_env.rb".freeze, "lib/schemacop/v2.rb".freeze, "lib/schemacop/v2/caster.rb".freeze, "lib/schemacop/v2/collector.rb".freeze, "lib/schemacop/v2/dupper.rb".freeze, "lib/schemacop/v2/field_node.rb".freeze, "lib/schemacop/v2/node.rb".freeze, "lib/schemacop/v2/node_resolver.rb".freeze, "lib/schemacop/v2/node_supporting_field.rb".freeze, "lib/schemacop/v2/node_supporting_type.rb".freeze, "lib/schemacop/v2/node_with_block.rb".freeze, "lib/schemacop/v2/validator/array_validator.rb".freeze, "lib/schemacop/v2/validator/boolean_validator.rb".freeze, "lib/schemacop/v2/validator/float_validator.rb".freeze, "lib/schemacop/v2/validator/hash_validator.rb".freeze, "lib/schemacop/v2/validator/integer_validator.rb".freeze, "lib/schemacop/v2/validator/nil_validator.rb".freeze, "lib/schemacop/v2/validator/number_validator.rb".freeze, "lib/schemacop/v2/validator/object_validator.rb".freeze, "lib/schemacop/v2/validator/string_validator.rb".freeze, "lib/schemacop/v2/validator/symbol_validator.rb".freeze, "lib/schemacop/v3.rb".freeze, "lib/schemacop/v3/all_of_node.rb".freeze, "lib/schemacop/v3/any_of_node.rb".freeze, "lib/schemacop/v3/array_node.rb".freeze, "lib/schemacop/v3/boolean_node.rb".freeze, "lib/schemacop/v3/combination_node.rb".freeze, "lib/schemacop/v3/context.rb".freeze, "lib/schemacop/v3/dsl_scope.rb".freeze, "lib/schemacop/v3/global_context.rb".freeze, "lib/schemacop/v3/hash_node.rb".freeze, "lib/schemacop/v3/integer_node.rb".freeze, "lib/schemacop/v3/is_not_node.rb".freeze, "lib/schemacop/v3/node.rb".freeze, "lib/schemacop/v3/node_registry.rb".freeze, "lib/schemacop/v3/number_node.rb".freeze, "lib/schemacop/v3/numeric_node.rb".freeze, "lib/schemacop/v3/object_node.rb".freeze, "lib/schemacop/v3/one_of_node.rb".freeze, "lib/schemacop/v3/reference_node.rb".freeze, "lib/schemacop/v3/result.rb".freeze, "lib/schemacop/v3/string_node.rb".freeze, "lib/schemacop/v3/symbol_node.rb".freeze, "schemacop.gemspec".freeze, "test/lib/test_helper.rb".freeze, "test/schemas/nested/group.rb".freeze, "test/schemas/user.rb".freeze, "test/unit/schemacop/v2/casting_test.rb".freeze, "test/unit/schemacop/v2/collector_test.rb".freeze, "test/unit/schemacop/v2/custom_check_test.rb".freeze, "test/unit/schemacop/v2/custom_if_test.rb".freeze, "test/unit/schemacop/v2/defaults_test.rb".freeze, "test/unit/schemacop/v2/empty_test.rb".freeze, "test/unit/schemacop/v2/nil_dis_allow_test.rb".freeze, "test/unit/schemacop/v2/node_resolver_test.rb".freeze, "test/unit/schemacop/v2/short_forms_test.rb".freeze, "test/unit/schemacop/v2/types_test.rb".freeze, "test/unit/schemacop/v2/validator_array_test.rb".freeze, "test/unit/schemacop/v2/validator_boolean_test.rb".freeze, "test/unit/schemacop/v2/validator_float_test.rb".freeze, "test/unit/schemacop/v2/validator_hash_test.rb".freeze, "test/unit/schemacop/v2/validator_integer_test.rb".freeze, "test/unit/schemacop/v2/validator_nil_test.rb".freeze, "test/unit/schemacop/v2/validator_number_test.rb".freeze, "test/unit/schemacop/v2/validator_object_test.rb".freeze, "test/unit/schemacop/v2/validator_string_test.rb".freeze, "test/unit/schemacop/v2/validator_symbol_test.rb".freeze, "test/unit/schemacop/v3/all_of_node_test.rb".freeze, "test/unit/schemacop/v3/any_of_node_test.rb".freeze, "test/unit/schemacop/v3/array_node_test.rb".freeze, "test/unit/schemacop/v3/boolean_node_test.rb".freeze, "test/unit/schemacop/v3/global_context_test.rb".freeze, "test/unit/schemacop/v3/hash_node_test.rb".freeze, "test/unit/schemacop/v3/integer_node_test.rb".freeze, "test/unit/schemacop/v3/is_not_node_test.rb".freeze, "test/unit/schemacop/v3/node_test.rb".freeze, "test/unit/schemacop/v3/number_node_test.rb".freeze, "test/unit/schemacop/v3/object_node_test.rb".freeze, "test/unit/schemacop/v3/one_of_node_test.rb".freeze, "test/unit/schemacop/v3/reference_node_test.rb".freeze, "test/unit/schemacop/v3/string_node_test.rb".freeze, "test/unit/schemacop/v3/symbol_node_test.rb".freeze]
13
13
  s.homepage = "https://github.com/sitrox/schemacop".freeze
14
14
  s.licenses = ["MIT".freeze]
@@ -988,7 +988,7 @@ module Schemacop
988
988
  end
989
989
 
990
990
  assert_validation('{42]') do
991
- error '/', /JSON parse error: "(\d+: )?unexpected token at '{42]'"\./
991
+ error '/', /JSON parse error: "((\d+: )?unexpected token at '{42]'|expected object key, got '42]' at line \d+ column \d+)"\./
992
992
  end
993
993
 
994
994
  assert_validation('"foo"') do
@@ -161,6 +161,104 @@ module Schemacop
161
161
  GlobalContext.instance.schema_for('user')
162
162
  end
163
163
  end
164
+
165
+ def test_v3_default_options_with_lazy_load
166
+ dir = Dir.mktmpdir
167
+ Schemacop.load_paths << dir
168
+ File.write(File.join(dir, 'test_schema.rb'), %(schema :integer))
169
+
170
+ Schemacop.v3_default_options = { cast_str: true }.freeze
171
+
172
+ schema = GlobalContext.instance.schema_for('test_schema')
173
+ result = schema.validate('42')
174
+
175
+ assert result.valid?, "Expected string '42' to be cast to integer 42, but got errors: #{result.errors}"
176
+ assert_equal 42, result.data
177
+ ensure
178
+ Schemacop.v3_default_options = {}
179
+ end
180
+
181
+ def test_v3_default_options_with_eager_load
182
+ dir = Dir.mktmpdir
183
+ Schemacop.load_paths << dir
184
+ File.write(File.join(dir, 'test_schema.rb'), %(schema :integer))
185
+
186
+ Schemacop.v3_default_options = { cast_str: true }.freeze
187
+
188
+ GlobalContext.instance.eager_load!
189
+ schema = GlobalContext.instance.schema_for('test_schema')
190
+ result = schema.validate('42')
191
+
192
+ assert result.valid?, "Expected string '42' to be cast to integer 42, but got errors: #{result.errors}"
193
+ assert_equal 42, result.data
194
+ ensure
195
+ Schemacop.v3_default_options = {}
196
+ end
197
+
198
+ def test_v3_default_options_with_nested_schema
199
+ dir = Dir.mktmpdir
200
+ Schemacop.load_paths << dir
201
+ File.write(File.join(dir, 'form_schema.rb'), <<~SCHEMA)
202
+ schema do
203
+ int! :age
204
+ str! :name
205
+ end
206
+ SCHEMA
207
+
208
+ Schemacop.v3_default_options = { cast_str: true }.freeze
209
+
210
+ schema = GlobalContext.instance.schema_for('form_schema')
211
+ result = schema.validate({ age: '25', name: 'John' })
212
+
213
+ assert result.valid?, "Expected string '25' to be cast to integer 25, but got errors: #{result.errors}"
214
+ assert_equal 25, result.data[:age]
215
+ assert_equal 'John', result.data[:name]
216
+ ensure
217
+ Schemacop.v3_default_options = {}
218
+ end
219
+
220
+ def test_v3_default_options_set_before_eager_load
221
+ dir = Dir.mktmpdir
222
+ Schemacop.load_paths << dir
223
+ File.write(File.join(dir, 'test_schema.rb'), %(schema :integer))
224
+
225
+ # Set default options BEFORE eager loading (simulates production mode)
226
+ Schemacop.v3_default_options = { cast_str: true }.freeze
227
+
228
+ GlobalContext.instance.eager_load!
229
+ schema = GlobalContext.instance.schema_for('test_schema')
230
+ result = schema.validate('42')
231
+
232
+ assert result.valid?, "Expected string '42' to be cast to integer 42, but got errors: #{result.errors}"
233
+ assert_equal 42, result.data
234
+ ensure
235
+ Schemacop.v3_default_options = {}
236
+ end
237
+
238
+ def test_v3_default_options_set_after_eager_load
239
+ dir = Dir.mktmpdir
240
+ Schemacop.load_paths << dir
241
+ File.write(File.join(dir, 'test_schema.rb'), %(schema :integer))
242
+
243
+ # Eager load schemas BEFORE setting default options
244
+ GlobalContext.instance.eager_load!
245
+
246
+ Schemacop.v3_default_options = { cast_str: true }.freeze
247
+
248
+ schema = GlobalContext.instance.schema_for('test_schema')
249
+ result = schema.validate('42')
250
+
251
+ # NOTE: Setting v3_default_options AFTER eager loading does not work
252
+ # because schemas are already cached. In Rails applications, the
253
+ # Railtie explicitly loads 'config/schemacop.rb' before eager loading,
254
+ # ensuring options are set before schemas are loaded.
255
+ #
256
+ # This test verifies that the options don't retroactively apply.
257
+ refute result.valid?, 'Options set after eager_load! should not affect already-loaded schemas'
258
+ assert_equal({ [] => ['Invalid type, got type "String", expected "integer".'] }, result.errors)
259
+ ensure
260
+ Schemacop.v3_default_options = {}
261
+ end
164
262
  end
165
263
  end
166
264
  end
@@ -32,7 +32,7 @@ module Schemacop
32
32
  end
33
33
 
34
34
  assert_validation('{42]') do
35
- error '/', /JSON parse error: "(\d+: )?unexpected token at '{42]'"\./
35
+ error '/', /JSON parse error: "((\d+: )?unexpected token at '{42]'|expected object key, got '42]' at line \d+ column \d+)"\./
36
36
  end
37
37
 
38
38
  assert_validation('"foo"') do
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schemacop
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.35
4
+ version: 3.0.36
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sitrox
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-07-31 00:00:00.000000000 Z
10
+ date: 2026-01-05 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -38,8 +37,6 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: 0.0.4
41
- description:
42
- email:
43
40
  executables: []
44
41
  extensions: []
45
42
  extra_rdoc_files: []
@@ -151,7 +148,6 @@ homepage: https://github.com/sitrox/schemacop
151
148
  licenses:
152
149
  - MIT
153
150
  metadata: {}
154
- post_install_message:
155
151
  rdoc_options: []
156
152
  require_paths:
157
153
  - lib
@@ -166,8 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
162
  - !ruby/object:Gem::Version
167
163
  version: '0'
168
164
  requirements: []
169
- rubygems_version: 3.4.6
170
- signing_key:
165
+ rubygems_version: 4.0.2
171
166
  specification_version: 4
172
167
  summary: Schemacop validates ruby structures consisting of nested hashes and arrays
173
168
  against simple schema definitions.