schemacop 1.0.2 → 2.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 +4 -4
- data/.gitignore +2 -1
- data/.rubocop.yml +59 -1
- data/CHANGELOG.md +10 -0
- data/README.md +389 -199
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/doc/Schemacop.html +41 -130
- data/doc/Schemacop/ArrayValidator.html +329 -0
- data/doc/Schemacop/BooleanValidator.html +145 -0
- data/doc/Schemacop/Collector.html +535 -0
- data/doc/Schemacop/Exceptions.html +39 -39
- data/doc/Schemacop/Exceptions/InvalidSchemaError.html +124 -0
- data/doc/Schemacop/Exceptions/ValidationError.html +124 -0
- data/doc/Schemacop/FieldNode.html +409 -0
- data/doc/Schemacop/FloatValidator.html +158 -0
- data/doc/Schemacop/HashValidator.html +263 -0
- data/doc/Schemacop/IntegerValidator.html +158 -0
- data/doc/Schemacop/NilValidator.html +145 -0
- data/doc/Schemacop/Node.html +1426 -0
- data/doc/Schemacop/NodeResolver.html +242 -0
- data/doc/Schemacop/NodeSupportingField.html +590 -0
- data/doc/Schemacop/NodeSupportingType.html +614 -0
- data/doc/Schemacop/NodeWithBlock.html +289 -0
- data/doc/Schemacop/NumberValidator.html +232 -0
- data/doc/Schemacop/ObjectValidator.html +288 -0
- data/doc/Schemacop/RootNode.html +171 -0
- data/doc/Schemacop/Schema.html +697 -0
- data/doc/Schemacop/StringValidator.html +295 -0
- data/doc/ScopedEnv.html +351 -0
- data/doc/_index.html +190 -47
- data/doc/class_list.html +24 -31
- data/doc/css/full_list.css +32 -31
- data/doc/css/style.css +244 -91
- data/doc/file.README.html +428 -232
- data/doc/file_list.html +26 -30
- data/doc/frames.html +7 -16
- data/doc/index.html +428 -232
- data/doc/inheritance.graphml +524 -0
- data/doc/inheritance.pdf +825 -0
- data/doc/js/app.js +106 -77
- data/doc/js/full_list.js +170 -135
- data/doc/method_list.html +494 -38
- data/doc/top-level-namespace.html +36 -36
- data/lib/schemacop.rb +22 -7
- data/lib/schemacop/collector.rb +34 -0
- data/lib/schemacop/exceptions.rb +2 -8
- data/lib/schemacop/field_node.rb +26 -0
- data/lib/schemacop/node.rb +127 -0
- data/lib/schemacop/node_resolver.rb +14 -0
- data/lib/schemacop/node_supporting_field.rb +62 -0
- data/lib/schemacop/node_supporting_type.rb +112 -0
- data/lib/schemacop/node_with_block.rb +16 -0
- data/lib/schemacop/root_node.rb +4 -0
- data/lib/schemacop/schema.rb +61 -0
- data/lib/schemacop/scoped_env.rb +18 -0
- data/lib/schemacop/validator/array_validator.rb +30 -0
- data/lib/schemacop/validator/boolean_validator.rb +5 -0
- data/lib/schemacop/validator/float_validator.rb +5 -0
- data/lib/schemacop/validator/hash_validator.rb +18 -0
- data/lib/schemacop/validator/integer_validator.rb +5 -0
- data/lib/schemacop/validator/nil_validator.rb +5 -0
- data/lib/schemacop/validator/number_validator.rb +19 -0
- data/lib/schemacop/validator/object_validator.rb +21 -0
- data/lib/schemacop/validator/string_validator.rb +37 -0
- data/schemacop.gemspec +7 -5
- data/test/custom_check_test.rb +86 -0
- data/test/custom_if_test.rb +95 -0
- data/test/nil_dis_allow_test.rb +41 -0
- data/test/short_forms_test.rb +316 -0
- data/test/test_helper.rb +6 -0
- data/test/types_test.rb +83 -0
- data/test/validator_array_test.rb +97 -0
- data/test/validator_boolean_test.rb +15 -0
- data/test/validator_float_test.rb +57 -0
- data/test/validator_hash_test.rb +71 -0
- data/test/validator_integer_test.rb +46 -0
- data/test/validator_nil_test.rb +13 -0
- data/test/validator_number_test.rb +60 -0
- data/test/validator_object_test.rb +87 -0
- data/test/validator_string_test.rb +76 -0
- metadata +78 -14
- data/doc/Schemacop/Exceptions/Base.html +0 -127
- data/doc/Schemacop/Exceptions/InvalidSchema.html +0 -141
- data/doc/Schemacop/Exceptions/Validation.html +0 -142
- data/doc/Schemacop/MethodValidation.html +0 -120
- data/doc/Schemacop/MethodValidation/ClassMethods.html +0 -196
- data/doc/Schemacop/Validator.html +0 -254
- data/lib/schemacop/validator.rb +0 -145
- data/test/schemacop_validator_test.rb +0 -257
| @@ -0,0 +1,112 @@ | |
| 1 | 
            +
            module Schemacop
         | 
| 2 | 
            +
              class NodeSupportingType < NodeWithBlock
         | 
| 3 | 
            +
                block_method :type
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def self.build(options, &block)
         | 
| 6 | 
            +
                  new(nil, options, &block)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(options = {}, &block)
         | 
| 10 | 
            +
                  super(options)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  @types = []
         | 
| 13 | 
            +
                  exec_block(&block)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  if @types.none?
         | 
| 16 | 
            +
                    fail Exceptions::InvalidSchemaError, 'Block must contain a type definition or not be given at all.' if block_given?
         | 
| 17 | 
            +
                    type :object
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  # if @types.none?
         | 
| 21 | 
            +
                  #   super(options)
         | 
| 22 | 
            +
                  #   exec_block(&block)
         | 
| 23 | 
            +
                  #   if @types.none?
         | 
| 24 | 
            +
                  #     fail Exceptions::InvalidSchemaError, 'Block must contain a type definition or not be given at all.' if block_given?
         | 
| 25 | 
            +
                  #   end
         | 
| 26 | 
            +
                  # else
         | 
| 27 | 
            +
                  #   super({})
         | 
| 28 | 
            +
                  # end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def exec_block(&block)
         | 
| 32 | 
            +
                  super
         | 
| 33 | 
            +
                rescue NoMethodError
         | 
| 34 | 
            +
                  @types = []
         | 
| 35 | 
            +
                  type :hash, {}, &block
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                # required signature:
         | 
| 39 | 
            +
                # First argument must be a type or an array of types
         | 
| 40 | 
            +
                # Following arguments may be subtypes
         | 
| 41 | 
            +
                # Last argument may be an options hash.
         | 
| 42 | 
            +
                # Options and given block are passed to the last specified type.
         | 
| 43 | 
            +
                # Not permitted to give subtypes / options / a block if an array of types is given.
         | 
| 44 | 
            +
                #
         | 
| 45 | 
            +
                # TODO: Probably change this method so that the 'rescue NoMethodError'
         | 
| 46 | 
            +
                # happens in here directly and not in the constructor. This way we can
         | 
| 47 | 
            +
                # always call 'type', even if we don't have one and the type is auto-guessed
         | 
| 48 | 
            +
                # as it formerly was the case in the constructor.
         | 
| 49 | 
            +
                def type(*args, &block)
         | 
| 50 | 
            +
                  options = args.last.is_a?(Hash) ? args.pop : {}
         | 
| 51 | 
            +
                  types = [*args.shift]
         | 
| 52 | 
            +
                  subtypes = args
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  unless types.any?
         | 
| 55 | 
            +
                    fail Exceptions::InvalidSchemaError, 'At least one type must be given.'
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  if subtypes.any? && types.size > 1
         | 
| 59 | 
            +
                    fail Exceptions::InvalidSchemaError, "First given type can't be an array if subtypes are given."
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  if types.size > 1 && options.any?
         | 
| 63 | 
            +
                    fail Exceptions::InvalidSchemaError, 'No options can be specified if multiple types are given.'
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  types.each do |type|
         | 
| 67 | 
            +
                    klass = resolve_type_klass(type)
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    if subtypes.any?
         | 
| 70 | 
            +
                      unless klass <= NodeSupportingType
         | 
| 71 | 
            +
                        fail "Node #{klass} does not support subtypes."
         | 
| 72 | 
            +
                      end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                      child = klass.new do
         | 
| 75 | 
            +
                        self.type(*subtypes, options, &block)
         | 
| 76 | 
            +
                      end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      # child = klass.build(options)
         | 
| 79 | 
            +
                      #
         | 
| 80 | 
            +
                      #
         | 
| 81 | 
            +
                      # child.type(*subtypes, &block)
         | 
| 82 | 
            +
                    else
         | 
| 83 | 
            +
                      if klass == ObjectValidator && type.is_a?(Class)
         | 
| 84 | 
            +
                        options[:classes] = type
         | 
| 85 | 
            +
                      end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                      child = klass.new(options, &block)
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                    @types << child
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                def validate(data, collector)
         | 
| 95 | 
            +
                  super
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  validate_types(data, collector)
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                protected
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                def validate_types(data, collector)
         | 
| 103 | 
            +
                  unless (match = @types.find { |t| t.type_matches?(data) })
         | 
| 104 | 
            +
                    allowed_types = @types.map(&:type_label)
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    collector.error "Data type not matching: #{data.class}, allowed types: #{allowed_types.join('; ')}"
         | 
| 107 | 
            +
                    return
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
                  match.validate(data, collector)
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
              end
         | 
| 112 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            module Schemacop
         | 
| 2 | 
            +
              class NodeWithBlock < Node
         | 
| 3 | 
            +
                class_attribute :block_methods
         | 
| 4 | 
            +
                self.block_methods = [].freeze
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def self.block_method(name)
         | 
| 7 | 
            +
                  self.block_methods += [name]
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def exec_block(&block)
         | 
| 11 | 
            +
                  return unless block_given?
         | 
| 12 | 
            +
                  se = ScopedEnv.new(self, self.class.block_methods)
         | 
| 13 | 
            +
                  se.instance_exec(&block)
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            module Schemacop
         | 
| 2 | 
            +
              class Schema
         | 
| 3 | 
            +
                # Create a new Schema
         | 
| 4 | 
            +
                #
         | 
| 5 | 
            +
                # For detailed usage, please refer to README.md in the root of this project.
         | 
| 6 | 
            +
                #
         | 
| 7 | 
            +
                # @param args [Array] An array of arguments to apply to the root node of the
         | 
| 8 | 
            +
                #   Schema.
         | 
| 9 | 
            +
                # @param block A block with further Schema specification.
         | 
| 10 | 
            +
                # @raise [Schemacop::Exceptions::InvalidSchemaError] If the Schema defined
         | 
| 11 | 
            +
                #   is invalid.
         | 
| 12 | 
            +
                def initialize(*args, &block)
         | 
| 13 | 
            +
                  @root = HashValidator.new do
         | 
| 14 | 
            +
                    req :root, *args, &block
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                # Query data validity
         | 
| 19 | 
            +
                #
         | 
| 20 | 
            +
                # @param data The data to validate.
         | 
| 21 | 
            +
                # @return [Boolean] True if the data is valid, false otherwise.
         | 
| 22 | 
            +
                def valid?(data)
         | 
| 23 | 
            +
                  validate(data).valid?
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                # Query data validity
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                # @param data The data to validate.
         | 
| 29 | 
            +
                # @return [Boolean] True if data is invalid, false otherwise.
         | 
| 30 | 
            +
                def invalid?(data)
         | 
| 31 | 
            +
                  !valid?(data)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                # Validate data for the defined Schema
         | 
| 35 | 
            +
                #
         | 
| 36 | 
            +
                # @param data The data to validate.
         | 
| 37 | 
            +
                # @return [Schemacop::Collector] The object that collected errors
         | 
| 38 | 
            +
                #   throughout the validation.
         | 
| 39 | 
            +
                def validate(data)
         | 
| 40 | 
            +
                  collector = Collector.new
         | 
| 41 | 
            +
                  @root.fields[:root].validate({ root: data }, collector)
         | 
| 42 | 
            +
                  return collector
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                # Validate data for the defined Schema
         | 
| 46 | 
            +
                #
         | 
| 47 | 
            +
                # @param data The data to validate.
         | 
| 48 | 
            +
                # @raise [Schemacop::Exceptions::ValidationError] If the data is invalid,
         | 
| 49 | 
            +
                #   this exception is thrown.
         | 
| 50 | 
            +
                # @return nil
         | 
| 51 | 
            +
                def validate!(data)
         | 
| 52 | 
            +
                  collector = validate(data)
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  unless collector.valid?
         | 
| 55 | 
            +
                    fail Exceptions::ValidationError, collector.exception_message
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  return nil
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            class ScopedEnv
         | 
| 2 | 
            +
              def initialize(delegation_object, methods)
         | 
| 3 | 
            +
                @delegation_object = delegation_object
         | 
| 4 | 
            +
                @methods = methods
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def method_missing(symbol, *args, &block)
         | 
| 8 | 
            +
                if @methods.include?(symbol)
         | 
| 9 | 
            +
                  @delegation_object.send(symbol, *args, &block)
         | 
| 10 | 
            +
                else
         | 
| 11 | 
            +
                  super
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              def respond_to_missing?(symbol, include_private = false)
         | 
| 16 | 
            +
                @methods.include?(symbol) || super
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            module Schemacop
         | 
| 2 | 
            +
              class ArrayValidator < NodeSupportingType
         | 
| 3 | 
            +
                register symbols: :array, klasses: Array
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                option :min # Minimal number of elements
         | 
| 6 | 
            +
                option :max # Maximal number of elements
         | 
| 7 | 
            +
                option :nil # Whether to allow nil values
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(*args)
         | 
| 10 | 
            +
                  super
         | 
| 11 | 
            +
                  type(:nil) if option(:nil)
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def validate(data, collector)
         | 
| 15 | 
            +
                  validate_custom_check(data, collector)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  if option?(:min) && data.size < option(:min)
         | 
| 18 | 
            +
                    collector.error "Array must have more (>=) than #{option(:min)} elements."
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  if option?(:max) && data.size > option(:max)
         | 
| 21 | 
            +
                    collector.error "Array must have less (<=) than #{option(:max)} elements."
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                  data.each_with_index do |entry, index|
         | 
| 24 | 
            +
                    collector.path("[#{index}]") do
         | 
| 25 | 
            +
                      validate_types(entry, collector)
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module Schemacop
         | 
| 2 | 
            +
              class HashValidator < NodeSupportingField
         | 
| 3 | 
            +
                register symbols: :hash, klasses: Hash
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def validate(data, collector)
         | 
| 6 | 
            +
                  super
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  allowed_fields = @fields.keys
         | 
| 9 | 
            +
                  obsolete_keys = data.keys - allowed_fields
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  collector.error "Obsolete keys: #{obsolete_keys.inspect}." if obsolete_keys.any?
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  @fields.values.each do |field|
         | 
| 14 | 
            +
                    field.validate(data, collector)
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            module Schemacop
         | 
| 2 | 
            +
              class NumberValidator < Node
         | 
| 3 | 
            +
                register symbols: :number, klasses: [Integer, Float]
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                option :min
         | 
| 6 | 
            +
                option :max
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def validate(data, collector)
         | 
| 9 | 
            +
                  super
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  if option?(:min) && data < option(:min)
         | 
| 12 | 
            +
                    collector.error "Value must be >= #{option(:min)}."
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                  if option?(:max) && data > option(:max)
         | 
| 15 | 
            +
                    collector.error "Value must be <= #{option(:max)}."
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            module Schemacop
         | 
| 2 | 
            +
              class ObjectValidator < Node
         | 
| 3 | 
            +
                register symbols: :object, klasses: Object
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                option :classes
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def type_label
         | 
| 8 | 
            +
                  "#{super} (#{classes.join(', ')})"
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def type_matches?(data)
         | 
| 12 | 
            +
                  super && (classes.empty? || classes.include?(data.class)) && !data.nil?
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                private
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def classes
         | 
| 18 | 
            +
                  [*option(:classes)]
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            module Schemacop
         | 
| 2 | 
            +
              class StringValidator < Node
         | 
| 3 | 
            +
                register symbols: :string, klasses: String
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                option :min
         | 
| 6 | 
            +
                option :max
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def initialize(options = {})
         | 
| 9 | 
            +
                  super(options)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  validate_options!
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def validate(data, collector)
         | 
| 15 | 
            +
                  super
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  if option?(:min) && data.size < option(:min)
         | 
| 18 | 
            +
                    collector.error "String must be longer (>=) than #{option(:min)} characters."
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  if option?(:max) && data.size > option(:max)
         | 
| 21 | 
            +
                    collector.error "String must be shorter (<=) than #{option(:max)} characters."
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                protected
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def validate_options!
         | 
| 28 | 
            +
                  option_schema = Schema.new :integer, min: 0
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  if option?(:min) && option_schema.invalid?(option(:min))
         | 
| 31 | 
            +
                    fail Exceptions::InvalidSchemaError, 'String option :min must be an integer >= 0.'
         | 
| 32 | 
            +
                  elsif option?(:max) && option_schema.invalid?(option(:max))
         | 
| 33 | 
            +
                    fail Exceptions::InvalidSchemaError, 'String option :max must be an integer >= 0.'
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
    
        data/schemacop.gemspec
    CHANGED
    
    | @@ -1,18 +1,20 @@ | |
| 1 1 | 
             
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            -
            # stub: schemacop  | 
| 2 | 
            +
            # stub: schemacop 2.0.0 ruby lib
         | 
| 3 3 |  | 
| 4 4 | 
             
            Gem::Specification.new do |s|
         | 
| 5 5 | 
             
              s.name = "schemacop".freeze
         | 
| 6 | 
            -
              s.version = " | 
| 6 | 
            +
              s.version = "2.0.0"
         | 
| 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 = " | 
| 12 | 
            -
              s.files = [".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, ".travis.yml".freeze, ".yardopts".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "doc/Schemacop.html".freeze, "doc/Schemacop/Exceptions.html".freeze, "doc/Schemacop/Exceptions/ | 
| 11 | 
            +
              s.date = "2017-05-15"
         | 
| 12 | 
            +
              s.files = [".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, ".travis.yml".freeze, ".yardopts".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "doc/Schemacop.html".freeze, "doc/Schemacop/ArrayValidator.html".freeze, "doc/Schemacop/BooleanValidator.html".freeze, "doc/Schemacop/Collector.html".freeze, "doc/Schemacop/Exceptions.html".freeze, "doc/Schemacop/Exceptions/InvalidSchemaError.html".freeze, "doc/Schemacop/Exceptions/ValidationError.html".freeze, "doc/Schemacop/FieldNode.html".freeze, "doc/Schemacop/FloatValidator.html".freeze, "doc/Schemacop/HashValidator.html".freeze, "doc/Schemacop/IntegerValidator.html".freeze, "doc/Schemacop/NilValidator.html".freeze, "doc/Schemacop/Node.html".freeze, "doc/Schemacop/NodeResolver.html".freeze, "doc/Schemacop/NodeSupportingField.html".freeze, "doc/Schemacop/NodeSupportingType.html".freeze, "doc/Schemacop/NodeWithBlock.html".freeze, "doc/Schemacop/NumberValidator.html".freeze, "doc/Schemacop/ObjectValidator.html".freeze, "doc/Schemacop/RootNode.html".freeze, "doc/Schemacop/Schema.html".freeze, "doc/Schemacop/StringValidator.html".freeze, "doc/ScopedEnv.html".freeze, "doc/_index.html".freeze, "doc/class_list.html".freeze, "doc/css/common.css".freeze, "doc/css/full_list.css".freeze, "doc/css/style.css".freeze, "doc/file.README.html".freeze, "doc/file_list.html".freeze, "doc/frames.html".freeze, "doc/index.html".freeze, "doc/inheritance.graphml".freeze, "doc/inheritance.pdf".freeze, "doc/js/app.js".freeze, "doc/js/full_list.js".freeze, "doc/js/jquery.js".freeze, "doc/method_list.html".freeze, "doc/top-level-namespace.html".freeze, "lib/schemacop.rb".freeze, "lib/schemacop/collector.rb".freeze, "lib/schemacop/exceptions.rb".freeze, "lib/schemacop/field_node.rb".freeze, "lib/schemacop/node.rb".freeze, "lib/schemacop/node_resolver.rb".freeze, "lib/schemacop/node_supporting_field.rb".freeze, "lib/schemacop/node_supporting_type.rb".freeze, "lib/schemacop/node_with_block.rb".freeze, "lib/schemacop/root_node.rb".freeze, "lib/schemacop/schema.rb".freeze, "lib/schemacop/scoped_env.rb".freeze, "lib/schemacop/validator/array_validator.rb".freeze, "lib/schemacop/validator/boolean_validator.rb".freeze, "lib/schemacop/validator/float_validator.rb".freeze, "lib/schemacop/validator/hash_validator.rb".freeze, "lib/schemacop/validator/integer_validator.rb".freeze, "lib/schemacop/validator/nil_validator.rb".freeze, "lib/schemacop/validator/number_validator.rb".freeze, "lib/schemacop/validator/object_validator.rb".freeze, "lib/schemacop/validator/string_validator.rb".freeze, "schemacop.gemspec".freeze, "test/custom_check_test.rb".freeze, "test/custom_if_test.rb".freeze, "test/nil_dis_allow_test.rb".freeze, "test/short_forms_test.rb".freeze, "test/test_helper.rb".freeze, "test/types_test.rb".freeze, "test/validator_array_test.rb".freeze, "test/validator_boolean_test.rb".freeze, "test/validator_float_test.rb".freeze, "test/validator_hash_test.rb".freeze, "test/validator_integer_test.rb".freeze, "test/validator_nil_test.rb".freeze, "test/validator_number_test.rb".freeze, "test/validator_object_test.rb".freeze, "test/validator_string_test.rb".freeze]
         | 
| 13 | 
            +
              s.homepage = "https://github.com/sitrox/schemacop".freeze
         | 
| 14 | 
            +
              s.licenses = ["MIT".freeze]
         | 
| 13 15 | 
             
              s.rubygems_version = "2.6.6".freeze
         | 
| 14 16 | 
             
              s.summary = "Schemacop validates ruby structures consisting of nested hashes and arrays against simple schema definitions.".freeze
         | 
| 15 | 
            -
              s.test_files = ["test/ | 
| 17 | 
            +
              s.test_files = ["test/custom_check_test.rb".freeze, "test/custom_if_test.rb".freeze, "test/nil_dis_allow_test.rb".freeze, "test/short_forms_test.rb".freeze, "test/test_helper.rb".freeze, "test/types_test.rb".freeze, "test/validator_array_test.rb".freeze, "test/validator_boolean_test.rb".freeze, "test/validator_float_test.rb".freeze, "test/validator_hash_test.rb".freeze, "test/validator_integer_test.rb".freeze, "test/validator_nil_test.rb".freeze, "test/validator_number_test.rb".freeze, "test/validator_object_test.rb".freeze, "test/validator_string_test.rb".freeze]
         | 
| 16 18 |  | 
| 17 19 | 
             
              if s.respond_to? :specification_version then
         | 
| 18 20 | 
             
                s.specification_version = 4
         | 
| @@ -0,0 +1,86 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Schemacop
         | 
| 4 | 
            +
              class CustomCheckTest < Minitest::Test
         | 
| 5 | 
            +
                def test_integer_check_short_form
         | 
| 6 | 
            +
                  s = Schema.new :integer, check: proc { |i| i.even? }
         | 
| 7 | 
            +
                  assert_nil s.validate!(2)
         | 
| 8 | 
            +
                  assert_nil s.validate!(-8)
         | 
| 9 | 
            +
                  assert_nil s.validate!(0)
         | 
| 10 | 
            +
                  assert_verr { s.validate!(1) }
         | 
| 11 | 
            +
                  assert_verr { s.validate!(-7) }
         | 
| 12 | 
            +
                  assert_verr { s.validate!(2.1) }
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def test_integer_check_with_lambda
         | 
| 16 | 
            +
                  s = Schema.new do
         | 
| 17 | 
            +
                    type :integer, check: ->(i) { i.even? }
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  assert_nil s.validate!(2)
         | 
| 21 | 
            +
                  assert_nil s.validate!(-8)
         | 
| 22 | 
            +
                  assert_nil s.validate!(0)
         | 
| 23 | 
            +
                  assert_verr { s.validate!(1) }
         | 
| 24 | 
            +
                  assert_verr { s.validate!(-7) }
         | 
| 25 | 
            +
                  assert_verr { s.validate!(2.1) }
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def test_in_type_dsl
         | 
| 29 | 
            +
                  s = Schema.new do
         | 
| 30 | 
            +
                    type :number, check: proc { |x| x == 42 }
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                  assert_nil s.validate!(42)
         | 
| 33 | 
            +
                  assert_verr { s.validate!(42.1) }
         | 
| 34 | 
            +
                  assert_verr { s.validate!(0) }
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def test_with_array
         | 
| 38 | 
            +
                  s = Schema.new do
         | 
| 39 | 
            +
                    type :array, check: proc { |a| a.first == 1 } do
         | 
| 40 | 
            +
                      type :integer
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                  assert_nil s.validate!([1, 2, 3])
         | 
| 44 | 
            +
                  assert_verr { s.validate!([2, 3, 4]) }
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def test_with_array_nested
         | 
| 48 | 
            +
                  s = Schema.new do
         | 
| 49 | 
            +
                    type :array, check: proc { |a| a.first == 4 } do
         | 
| 50 | 
            +
                      type :integer, check: proc { |i| i >= 2 }
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  assert_nil s.validate!([4, 3, 2])
         | 
| 55 | 
            +
                  assert_verr { s.validate!([3, 2]) }
         | 
| 56 | 
            +
                  assert_verr { s.validate!([4, 1]) }
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def test_with_hash
         | 
| 60 | 
            +
                  s = Schema.new :hash, check: proc { |h| h.all? { |k, v| k == v } } do
         | 
| 61 | 
            +
                    opt 1, :integer
         | 
| 62 | 
            +
                    opt 'two', :string
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                  assert_nil s.validate!(1 => 1, 'two' => 'two')
         | 
| 65 | 
            +
                  assert_verr { s.validate!(1 => 2, 'two' => 'two') }
         | 
| 66 | 
            +
                  assert_verr { s.validate!(1 => 1, 'two' => 'one') }
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def test_mixed_if_check
         | 
| 70 | 
            +
                  s = Schema.new do
         | 
| 71 | 
            +
                    req :first_name,
         | 
| 72 | 
            +
                        :string,
         | 
| 73 | 
            +
                        if: proc { |str| str.start_with?('Sand') },
         | 
| 74 | 
            +
                        check: proc { |str| str == 'Sandy' }
         | 
| 75 | 
            +
                    req :first_name, :string, min: 3
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  assert_nil s.validate!(first_name: 'Bob')
         | 
| 79 | 
            +
                  assert_nil s.validate!(first_name: 'Sandy')
         | 
| 80 | 
            +
                  assert_nil s.validate!(first_name: 'Sansibar')
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  assert_verr { s.validate!(first_name: 'Sandkasten') }
         | 
| 83 | 
            +
                  assert_verr { s.validate!(first_name: 'a') }
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
            end
         |