rtype 0.3.0 → 0.4.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/README.md +78 -10
- data/lib/rtype/behavior/core_ext.rb +22 -0
- data/lib/rtype/behavior/nilable.rb +1 -1
- data/lib/rtype/behavior/not.rb +1 -1
- data/lib/rtype/behavior/or.rb +1 -1
- data/lib/rtype/behavior/xor.rb +1 -1
- data/lib/rtype/behavior.rb +2 -1
- data/lib/rtype/version.rb +1 -1
- data/lib/rtype.rb +53 -8
- data/spec/rtype_spec.rb +192 -26
- metadata +4 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: c4bad8e7cdc12a3c4a598e806553fd89c184c212
         | 
| 4 | 
            +
              data.tar.gz: 67576b9e8839a9f1988ee4f561cb0474824ecb84
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4b82873431c88b2811b9ee34bdd84a3f23e683cbf4baaba9c57da29954b34869a3739db623496f0e07af92b8eab5750d10d523b3e93c3cf91080a5a36c5dd5fb
         | 
| 7 | 
            +
              data.tar.gz: 29a5f2356be7ed7637841a0a240689cd11f7d19f73ce5b5447c8ec99bb497ee931e2c48706048efacffe4d15c7a73619b184b49e53bbb9c920dfd328905e4954
         | 
    
        data/README.md
    CHANGED
    
    | @@ -31,15 +31,16 @@ Test::invert(state: 0) | |
| 31 31 |  | 
| 32 32 | 
             
            ## Requirements
         | 
| 33 33 | 
             
            - Ruby >= 2.1
         | 
| 34 | 
            -
            - MRI | 
| 34 | 
            +
            - MRI
         | 
| 35 35 | 
             
              - If C native extension is used, otherwise it is not required
         | 
| 36 36 | 
             
            - JRuby
         | 
| 37 37 | 
             
              - If Java extension is used, otherwise it is not required
         | 
| 38 38 |  | 
| 39 39 | 
             
            ## Features
         | 
| 40 | 
            -
            - Provide type checking for  | 
| 40 | 
            +
            - Provide type checking for arguments and return
         | 
| 41 41 | 
             
            - Support type checking for [keyword argument](#keyword-argument)
         | 
| 42 42 | 
             
            - [Type checking for array elements](#array)
         | 
| 43 | 
            +
            - [Type checking for hash elements](#hash)
         | 
| 43 44 | 
             
            - [Duck typing](#duck-typing)
         | 
| 44 45 | 
             
            - Custom type behavior
         | 
| 45 46 |  | 
| @@ -54,7 +55,7 @@ require 'rtype' | |
| 54 55 | 
             
            ### Native extension
         | 
| 55 56 | 
             
            Rtype itself is pure-ruby gem. but you can make it more faster by using native extension.
         | 
| 56 57 |  | 
| 57 | 
            -
            #### Native extension for MRI | 
| 58 | 
            +
            #### Native extension for MRI
         | 
| 58 59 | 
             
            Just run
         | 
| 59 60 | 
             
            ```ruby
         | 
| 60 61 | 
             
            gem install rtype-native
         | 
| @@ -96,6 +97,18 @@ then, Rtype use it. (Do not `require 'rtype-java'`) | |
| 96 97 | 
             
              - Of course, nested array works
         | 
| 97 98 | 
             
              - Example: [Array](#array)
         | 
| 98 99 | 
             
              - This can be used as a tuple
         | 
| 100 | 
            +
            - `Hash`
         | 
| 101 | 
            +
              - Value must be an hash
         | 
| 102 | 
            +
              - Each of value’s elements must be valid
         | 
| 103 | 
            +
              - Value's key list must be equal to the hash's key list
         | 
| 104 | 
            +
              - **String** key is **different** from **symbol** key
         | 
| 105 | 
            +
              - The type signature could not be positioned at last index
         | 
| 106 | 
            +
                - `[{}]` is **not** hash type argument. it is keyword argument because its position is last
         | 
| 107 | 
            +
                - `[{}, {}]` is empty hash type argument (first) and one empty keyword argument (second)
         | 
| 108 | 
            +
                - `[{}, {}, {}]` is two empty hash type argument (first, second) and empty keyword argument (last)
         | 
| 109 | 
            +
                - `{}` is keyword argument. non-keyword arguments must be in array.
         | 
| 110 | 
            +
              - Of course, nested hash works
         | 
| 111 | 
            +
              - Example: [Hash](#hash)
         | 
| 99 112 | 
             
            - `Proc`
         | 
| 100 113 | 
             
              - Value must return a truthy value for this proc
         | 
| 101 114 | 
             
            - `true`
         | 
| @@ -106,15 +119,36 @@ then, Rtype use it. (Do not `require 'rtype-java'`) | |
| 106 119 | 
             
              - Only available for **return type**. void return type in other languages
         | 
| 107 120 | 
             
            - Special Behaviors
         | 
| 108 121 | 
             
              - `Rtype::and(*types)` : Ensure value is valid for all the types
         | 
| 109 | 
            -
                -  | 
| 122 | 
            +
                - `Rtype::and(*types)`
         | 
| 123 | 
            +
                - `Rtype::Behavior::And[*types]`
         | 
| 124 | 
            +
                - `include Rtype::Behavior; And[...]`
         | 
| 125 | 
            +
                - `obj.and(*others)` (core extension)
         | 
| 126 | 
            +
             | 
| 110 127 | 
             
              - `Rtype::or(*types)` : Ensure value is valid for at least one of the types
         | 
| 111 | 
            -
                -  | 
| 128 | 
            +
                - `Rtype::or(*types)`
         | 
| 129 | 
            +
                - `Rtype::Behavior::Or[*types]`
         | 
| 130 | 
            +
                - `include Rtype::Behavior; Or[...]`
         | 
| 131 | 
            +
                - `obj.or(*others)` (core extension)
         | 
| 132 | 
            +
             | 
| 112 133 | 
             
              - `Rtype::xor(*types)` : Ensure value is valid for only one of the types
         | 
| 113 | 
            -
                -  | 
| 134 | 
            +
                - `Rtype::xor(*types)`
         | 
| 135 | 
            +
                - `Rtype::Behavior::Xor[*types]`
         | 
| 136 | 
            +
                - `include Rtype::Behavior; Xor[...]`
         | 
| 137 | 
            +
                - `obj.xor(*others)` (core extension)
         | 
| 138 | 
            +
             | 
| 114 139 | 
             
              - `Rtype::not(*types)` : Ensure value is not valid for all the types
         | 
| 115 | 
            -
                -  | 
| 140 | 
            +
                - `Rtype::not(*types)`
         | 
| 141 | 
            +
                - `Rtype::Behavior::Not[*types]`
         | 
| 142 | 
            +
                - `include Rtype::Behavior; Not[...]`
         | 
| 143 | 
            +
                - `obj.not` (core extension)
         | 
| 144 | 
            +
             | 
| 116 145 | 
             
              - `Rtype::nilable(type)` : Ensure value can be nil
         | 
| 117 | 
            -
                -  | 
| 146 | 
            +
                - `Rtype::nilable(type)`
         | 
| 147 | 
            +
                - `Rtype::Behavior::Nilable[type]`
         | 
| 148 | 
            +
                - `include Rtype::Behavior; Nilable[...]`
         | 
| 149 | 
            +
                - `obj.nilable` (core extension)
         | 
| 150 | 
            +
                - `obj.or_nil` (core extension)
         | 
| 151 | 
            +
             | 
| 118 152 | 
             
              - You can create custom behavior by extending `Rtype::Behavior::Base`
         | 
| 119 153 |  | 
| 120 154 | 
             
            ### Examples
         | 
| @@ -219,6 +253,38 @@ func [1] | |
| 219 253 | 
             
            func [1, 2] # Your location is (1, 2). I will look for you. I will find you
         | 
| 220 254 | 
             
            ```
         | 
| 221 255 |  | 
| 256 | 
            +
            #### Hash
         | 
| 257 | 
            +
            ```ruby
         | 
| 258 | 
            +
            # last hash element is keyword arguments
         | 
| 259 | 
            +
            rtype :func, [{msg: String}, {}] => Any
         | 
| 260 | 
            +
            def func(hash)
         | 
| 261 | 
            +
              puts hash[:msg]
         | 
| 262 | 
            +
            end
         | 
| 263 | 
            +
             | 
| 264 | 
            +
            # last hash is keyword arguments
         | 
| 265 | 
            +
            func({}, {})
         | 
| 266 | 
            +
            # (Rtype::ArgumentTypeError) for 1st argument:
         | 
| 267 | 
            +
            # Expected {} to be an hash with 1 elements:
         | 
| 268 | 
            +
            # - msg : Expected nil to be a String
         | 
| 269 | 
            +
             | 
| 270 | 
            +
            func({msg: 123}, {})
         | 
| 271 | 
            +
            # (Rtype::ArgumentTypeError) for 1st argument:
         | 
| 272 | 
            +
            # Expected {:msg=>123} to be an hash with 1 elements:
         | 
| 273 | 
            +
            # - msg : Expected 123 to be a String
         | 
| 274 | 
            +
             | 
| 275 | 
            +
            func({msg: "hello", key: 'value'}, {})
         | 
| 276 | 
            +
            # (Rtype::ArgumentTypeError) for 1st argument:
         | 
| 277 | 
            +
            # Expected {:msg=>"hello", :key=>"value"} to be an hash with 1 elements:
         | 
| 278 | 
            +
            # - msg : Expected "hello" to be a String
         | 
| 279 | 
            +
             | 
| 280 | 
            +
            func({"msg" => "hello hash"}, {})
         | 
| 281 | 
            +
            # (Rtype::ArgumentTypeError) for 1st argument:
         | 
| 282 | 
            +
            # Expected {"msg"=>"hello hash"} to be an hash with 1 elements:
         | 
| 283 | 
            +
            # - msg : Expected nil to be a String
         | 
| 284 | 
            +
             | 
| 285 | 
            +
            func({msg: "hello hash"}, {}) # hello hash
         | 
| 286 | 
            +
            ```
         | 
| 287 | 
            +
             | 
| 222 288 | 
             
            #### rtype with attr_accessor
         | 
| 223 289 | 
             
            `rtype_accessor`
         | 
| 224 290 |  | 
| @@ -250,7 +316,9 @@ Example.new.value | |
| 250 316 | 
             
            require 'rtype'
         | 
| 251 317 |  | 
| 252 318 | 
             
            class Example
         | 
| 253 | 
            -
              rtype :and_test, [ | 
| 319 | 
            +
              rtype :and_test, [String.and(:func)] => Any
         | 
| 320 | 
            +
              # also works:
         | 
| 321 | 
            +
              # rtype :and_test, [Rtype::and(String, :func)] => Any
         | 
| 254 322 | 
             
              def and_test(arg)
         | 
| 255 323 | 
             
              end
         | 
| 256 324 | 
             
            end
         | 
| @@ -344,7 +412,7 @@ end | |
| 344 412 | 
             
            say "Hello" # Hello
         | 
| 345 413 | 
             
            ```
         | 
| 346 414 |  | 
| 347 | 
            -
            #### Static method
         | 
| 415 | 
            +
            #### Static(singleton) method
         | 
| 348 416 | 
             
            Use `rtype_self`
         | 
| 349 417 |  | 
| 350 418 | 
             
            ```ruby
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            class Object
         | 
| 2 | 
            +
            	def and(*others)
         | 
| 3 | 
            +
            		::Rtype::and(self, *others)
         | 
| 4 | 
            +
            	end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            	def nilable
         | 
| 7 | 
            +
            		::Rtype::nilable(self)
         | 
| 8 | 
            +
            	end
         | 
| 9 | 
            +
            	alias_method :or_nil, :nilable
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            	def not
         | 
| 12 | 
            +
            		::Rtype::not(self)
         | 
| 13 | 
            +
            	end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            	def or(*others)
         | 
| 16 | 
            +
            		::Rtype::or(self, *others)
         | 
| 17 | 
            +
            	end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            	def xor(*others)
         | 
| 20 | 
            +
            		::Rtype::xor(self, *others)
         | 
| 21 | 
            +
            	end
         | 
| 22 | 
            +
            end
         | 
    
        data/lib/rtype/behavior/not.rb
    CHANGED
    
    
    
        data/lib/rtype/behavior/or.rb
    CHANGED
    
    
    
        data/lib/rtype/behavior/xor.rb
    CHANGED
    
    
    
        data/lib/rtype/behavior.rb
    CHANGED
    
    
    
        data/lib/rtype/version.rb
    CHANGED
    
    
    
        data/lib/rtype.rb
    CHANGED
    
    | @@ -40,7 +40,7 @@ module Rtype | |
| 40 40 | 
             
            		return_sig = el[1]
         | 
| 41 41 |  | 
| 42 42 | 
             
            		if arg_sig.is_a?(Array)
         | 
| 43 | 
            -
            			expected_args = arg_sig
         | 
| 43 | 
            +
            			expected_args = arg_sig.dup
         | 
| 44 44 | 
             
            			if expected_args.last.is_a?(Hash)
         | 
| 45 45 | 
             
            				expected_kwargs = expected_args.pop
         | 
| 46 46 | 
             
            			else
         | 
| @@ -51,12 +51,12 @@ module Rtype | |
| 51 51 | 
             
            			expected_kwargs = arg_sig
         | 
| 52 52 | 
             
            		end
         | 
| 53 53 |  | 
| 54 | 
            -
            		expected_args.each { |e|  | 
| 54 | 
            +
            		expected_args.each { |e| check_valid_argument_type_sig(e) }
         | 
| 55 55 | 
             
            		if expected_kwargs.keys.any? { |e| !e.is_a?(Symbol) }
         | 
| 56 56 | 
             
            			raise TypeSignatureError, "Invalid type signature: keyword arguments contain non-symbol key"
         | 
| 57 57 | 
             
            		end
         | 
| 58 | 
            -
            		expected_kwargs.each_value { |e|  | 
| 59 | 
            -
            		 | 
| 58 | 
            +
            		expected_kwargs.each_value { |e| check_valid_argument_type_sig(e) }
         | 
| 59 | 
            +
            		check_valid_return_type_sig(return_sig)
         | 
| 60 60 |  | 
| 61 61 | 
             
            		sig = TypeSignature.new
         | 
| 62 62 | 
             
            		sig.argument_type = arg_sig
         | 
| @@ -123,7 +123,7 @@ module Rtype | |
| 123 123 | 
             
            		when Array
         | 
| 124 124 | 
             
            			if value.is_a?(Array)
         | 
| 125 125 | 
             
            				arr = expected.map.with_index do |e, idx|
         | 
| 126 | 
            -
            					if e.is_a?(Array)
         | 
| 126 | 
            +
            					if e.is_a?(Array) || e.is_a?(Hash)
         | 
| 127 127 | 
             
            						"- [#{idx}] index : {\n" + type_error_message(e, value[idx]) + "\n}"
         | 
| 128 128 | 
             
            					else
         | 
| 129 129 | 
             
            						"- [#{idx}] index : " + type_error_message(e, value[idx])
         | 
| @@ -133,6 +133,20 @@ module Rtype | |
| 133 133 | 
             
            			else
         | 
| 134 134 | 
             
            				"Expected #{value.inspect} to be an array"
         | 
| 135 135 | 
             
            			end
         | 
| 136 | 
            +
            		when Hash
         | 
| 137 | 
            +
            			if value.is_a?(Hash)
         | 
| 138 | 
            +
            				arr = []
         | 
| 139 | 
            +
            				expected.each do |k, v|
         | 
| 140 | 
            +
            					if v.is_a?(Array) || v.is_a?(Hash)
         | 
| 141 | 
            +
            						arr << "- #{k} : {\n" + type_error_message(v, value[k]) + "\n}"
         | 
| 142 | 
            +
            					else
         | 
| 143 | 
            +
            						arr << "- #{k} : " + type_error_message(v, value[k])
         | 
| 144 | 
            +
            					end
         | 
| 145 | 
            +
            				end
         | 
| 146 | 
            +
            				"Expected #{value.inspect} to be an hash with #{expected.length} elements:\n" + arr.join("\n")
         | 
| 147 | 
            +
            			else
         | 
| 148 | 
            +
            				"Expected #{value.inspect} to be an hash"
         | 
| 149 | 
            +
            			end
         | 
| 136 150 | 
             
            		when Proc
         | 
| 137 151 | 
             
            			"Expected #{value.inspect} to return a truthy value for proc #{expected}"
         | 
| 138 152 | 
             
            		when true
         | 
| @@ -166,7 +180,34 @@ private | |
| 166 180 | 
             
            		end
         | 
| 167 181 | 
             
            		nil
         | 
| 168 182 | 
             
            	end
         | 
| 169 | 
            -
             | 
| 183 | 
            +
             | 
| 184 | 
            +
            	def check_valid_argument_type_sig(sig)
         | 
| 185 | 
            +
            		case sig
         | 
| 186 | 
            +
            		when Rtype::Behavior::Base
         | 
| 187 | 
            +
            		when Module
         | 
| 188 | 
            +
            		when Symbol
         | 
| 189 | 
            +
            		when Regexp
         | 
| 190 | 
            +
            		when Range
         | 
| 191 | 
            +
            		when Array
         | 
| 192 | 
            +
            			sig.each do |e|
         | 
| 193 | 
            +
            				check_valid_argument_type_sig(e)
         | 
| 194 | 
            +
            			end
         | 
| 195 | 
            +
            		when Hash
         | 
| 196 | 
            +
            			sig.each_value do |e|
         | 
| 197 | 
            +
            				check_valid_argument_type_sig(e)
         | 
| 198 | 
            +
            			end
         | 
| 199 | 
            +
            		when Proc
         | 
| 200 | 
            +
            		when true
         | 
| 201 | 
            +
            		when false
         | 
| 202 | 
            +
            		else
         | 
| 203 | 
            +
            			raise TypeSignatureError, "Invalid type signature: Unknown type behavior #{sig}"
         | 
| 204 | 
            +
            		end
         | 
| 205 | 
            +
            	end
         | 
| 206 | 
            +
             | 
| 207 | 
            +
            	def check_valid_return_type_sig(sig)
         | 
| 208 | 
            +
            		check_valid_argument_type_sig(sig) unless sig.nil?
         | 
| 209 | 
            +
            	end
         | 
| 210 | 
            +
             | 
| 170 211 | 
             
            public
         | 
| 171 212 | 
             
            	unless respond_to?(:valid?)
         | 
| 172 213 | 
             
            	# validate argument type
         | 
| @@ -180,6 +221,10 @@ public | |
| 180 221 | 
             
            			!!(expected =~ value.to_s)
         | 
| 181 222 | 
             
            		when Range
         | 
| 182 223 | 
             
            			expected.include?(value)
         | 
| 224 | 
            +
            		when Hash
         | 
| 225 | 
            +
            			return false unless value.is_a?(Hash)
         | 
| 226 | 
            +
            			return false unless expected.keys == value.keys
         | 
| 227 | 
            +
            			expected.all? { |k, v| valid?(v, value[k]) }
         | 
| 183 228 | 
             
            		when Array
         | 
| 184 229 | 
             
            			return false unless value.is_a?(Array)
         | 
| 185 230 | 
             
            			return false unless expected.length == value.length
         | 
| @@ -207,7 +252,7 @@ public | |
| 207 252 | 
             
            			value = args[i]
         | 
| 208 253 | 
             
            			unless expected.nil?
         | 
| 209 254 | 
             
            				unless valid?(expected, value)
         | 
| 210 | 
            -
            					raise ArgumentTypeError, " | 
| 255 | 
            +
            					raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
         | 
| 211 256 | 
             
            				end
         | 
| 212 257 | 
             
            			end
         | 
| 213 258 | 
             
            		end
         | 
| @@ -222,7 +267,7 @@ public | |
| 222 267 | 
             
            			value = args[i]
         | 
| 223 268 | 
             
            			unless expected.nil?
         | 
| 224 269 | 
             
            				unless valid?(expected, value)
         | 
| 225 | 
            -
            					raise ArgumentTypeError, "#{arg_message( | 
| 270 | 
            +
            					raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
         | 
| 226 271 | 
             
            				end
         | 
| 227 272 | 
             
            			end
         | 
| 228 273 | 
             
            		end
         | 
    
        data/spec/rtype_spec.rb
    CHANGED
    
    | @@ -13,6 +13,9 @@ describe Rtype do | |
| 13 13 | 
             
            				obj
         | 
| 14 14 | 
             
            			end
         | 
| 15 15 |  | 
| 16 | 
            +
            			def two_args(a, b)
         | 
| 17 | 
            +
            			end
         | 
| 18 | 
            +
             | 
| 16 19 | 
             
            			def three_args(a, b, c)
         | 
| 17 20 | 
             
            			end
         | 
| 18 21 |  | 
| @@ -207,10 +210,26 @@ describe Rtype do | |
| 207 210 | 
             
            			it "is right" do
         | 
| 208 211 | 
             
            				klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
         | 
| 209 212 | 
             
            				instance.return_arg([123, 456])
         | 
| 213 | 
            +
             | 
| 214 | 
            +
            				klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
         | 
| 215 | 
            +
            				instance.two_args([123], [456])
         | 
| 210 216 | 
             
            			end
         | 
| 211 217 | 
             
            			it "is wrong args" do
         | 
| 212 218 | 
             
            				klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
         | 
| 213 | 
            -
            				expect { | 
| 219 | 
            +
            				expect {
         | 
| 220 | 
            +
            					instance.return_arg([123, [true]])
         | 
| 221 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 222 | 
            +
            				expect {
         | 
| 223 | 
            +
            					instance.return_arg([123, true])
         | 
| 224 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 225 | 
            +
             | 
| 226 | 
            +
            				klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
         | 
| 227 | 
            +
            				expect {
         | 
| 228 | 
            +
            					instance.two_args([123, 123], [123])
         | 
| 229 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 230 | 
            +
            				expect {
         | 
| 231 | 
            +
            					instance.two_args([123], 123)
         | 
| 232 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 214 233 | 
             
            			end
         | 
| 215 234 | 
             
            			it "is wrong result" do
         | 
| 216 235 | 
             
            				klass.send :rtype, :return_arg, [Any] => [:to_i, :to_i]
         | 
| @@ -218,6 +237,23 @@ describe Rtype do | |
| 218 237 | 
             
            			end
         | 
| 219 238 | 
             
            		end
         | 
| 220 239 |  | 
| 240 | 
            +
            		describe 'Hash' do
         | 
| 241 | 
            +
            			it "is right" do
         | 
| 242 | 
            +
            				klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
         | 
| 243 | 
            +
            				instance.return_arg({k: 123}, {})
         | 
| 244 | 
            +
            			end
         | 
| 245 | 
            +
            			it "is wrong args" do
         | 
| 246 | 
            +
            				klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
         | 
| 247 | 
            +
            				expect {
         | 
| 248 | 
            +
            					instance.return_arg({k: "str"}, {})
         | 
| 249 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 250 | 
            +
            			end
         | 
| 251 | 
            +
            			it "is wrong result" do
         | 
| 252 | 
            +
            				klass.send :rtype, :return_arg, [Any] => {k: Integer}
         | 
| 253 | 
            +
            				expect { instance.return_arg({k: "str"}) }.to raise_error Rtype::ReturnTypeError
         | 
| 254 | 
            +
            			end
         | 
| 255 | 
            +
            		end
         | 
| 256 | 
            +
             | 
| 221 257 | 
             
            		describe 'Proc' do
         | 
| 222 258 | 
             
            			it "is right" do
         | 
| 223 259 | 
             
            				klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
         | 
| @@ -285,36 +321,117 @@ describe Rtype do | |
| 285 321 | 
             
            		end
         | 
| 286 322 |  | 
| 287 323 | 
             
            		describe 'Special type behaviors' do
         | 
| 288 | 
            -
            			 | 
| 289 | 
            -
            				 | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
| 324 | 
            +
            			describe 'Rtype::Behavior::And' do
         | 
| 325 | 
            +
            				it 'module singleton method' do
         | 
| 326 | 
            +
            					klass.send :rtype, :return_nil, [Rtype::and(:to_i, :chars)] => nil
         | 
| 327 | 
            +
            					instance.return_nil("Hello")
         | 
| 328 | 
            +
            					expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
         | 
| 329 | 
            +
            				end
         | 
| 330 | 
            +
             | 
| 331 | 
            +
            				it 'class singleton [] method' do
         | 
| 332 | 
            +
            					klass.send :rtype, :return_nil, [ Rtype::Behavior::And[:to_i, :chars] ] => nil
         | 
| 333 | 
            +
            					instance.return_nil("Hello")
         | 
| 334 | 
            +
            					expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
         | 
| 335 | 
            +
            				end
         | 
| 336 | 
            +
             | 
| 337 | 
            +
            				it 'core extension method' do
         | 
| 338 | 
            +
            					klass.send :rtype, :return_nil, [ :to_i.and(:chars) ] => nil
         | 
| 339 | 
            +
            					instance.return_nil("Hello")
         | 
| 340 | 
            +
            					expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
         | 
| 341 | 
            +
            				end
         | 
| 292 342 | 
             
            			end
         | 
| 293 343 |  | 
| 294 | 
            -
            			 | 
| 295 | 
            -
            				 | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 298 | 
            -
             | 
| 344 | 
            +
            			describe 'Rtype::Behavior::Or' do
         | 
| 345 | 
            +
            				it 'module singleton method' do
         | 
| 346 | 
            +
            					klass.send :rtype, :return_nil, [Rtype::or(Integer, String)] => nil
         | 
| 347 | 
            +
            					instance.return_nil(123)
         | 
| 348 | 
            +
            					instance.return_nil("abc")
         | 
| 349 | 
            +
            					expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
         | 
| 350 | 
            +
            				end
         | 
| 351 | 
            +
             | 
| 352 | 
            +
            				it 'class singleton [] method' do
         | 
| 353 | 
            +
            					klass.send :rtype, :return_nil, [ Rtype::Behavior::Or[Integer, String] ] => nil
         | 
| 354 | 
            +
            					instance.return_nil(123)
         | 
| 355 | 
            +
            					instance.return_nil("abc")
         | 
| 356 | 
            +
            					expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
         | 
| 357 | 
            +
            				end
         | 
| 358 | 
            +
             | 
| 359 | 
            +
            				it 'core extension method' do
         | 
| 360 | 
            +
            					klass.send :rtype, :return_nil, [ Integer.or(String) ] => nil
         | 
| 361 | 
            +
            					instance.return_nil(123)
         | 
| 362 | 
            +
            					instance.return_nil("abc")
         | 
| 363 | 
            +
            					expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
         | 
| 364 | 
            +
            				end
         | 
| 299 365 | 
             
            			end
         | 
| 300 366 |  | 
| 301 | 
            -
            			 | 
| 302 | 
            -
            				 | 
| 303 | 
            -
             | 
| 304 | 
            -
             | 
| 305 | 
            -
             | 
| 367 | 
            +
            			describe 'Rtype::Behavior::Nilable' do
         | 
| 368 | 
            +
            				it 'module singleton method' do
         | 
| 369 | 
            +
            					klass.send :rtype, :return_nil, [Rtype::nilable(Integer)] => nil
         | 
| 370 | 
            +
            					instance.return_nil(nil)
         | 
| 371 | 
            +
            					instance.return_nil(123)
         | 
| 372 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 373 | 
            +
            				end
         | 
| 374 | 
            +
             | 
| 375 | 
            +
            				it 'class singleton [] method' do
         | 
| 376 | 
            +
            					klass.send :rtype, :return_nil, [ Rtype::Behavior::Nilable[Integer] ] => nil
         | 
| 377 | 
            +
            					instance.return_nil(nil)
         | 
| 378 | 
            +
            					instance.return_nil(123)
         | 
| 379 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 380 | 
            +
            				end
         | 
| 381 | 
            +
             | 
| 382 | 
            +
            				it 'core extension method :nilable' do
         | 
| 383 | 
            +
            					klass.send :rtype, :return_nil, [Integer.nilable] => nil
         | 
| 384 | 
            +
            					instance.return_nil(nil)
         | 
| 385 | 
            +
            					instance.return_nil(123)
         | 
| 386 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 387 | 
            +
            				end
         | 
| 388 | 
            +
             | 
| 389 | 
            +
            				it 'core extension method :or_nil' do
         | 
| 390 | 
            +
            					klass.send :rtype, :return_nil, [Integer.or_nil] => nil
         | 
| 391 | 
            +
            					instance.return_nil(nil)
         | 
| 392 | 
            +
            					instance.return_nil(123)
         | 
| 393 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 394 | 
            +
            				end
         | 
| 306 395 | 
             
            			end
         | 
| 307 396 |  | 
| 308 | 
            -
            			 | 
| 309 | 
            -
            				 | 
| 310 | 
            -
             | 
| 311 | 
            -
             | 
| 397 | 
            +
            			describe 'Rtype::Behavior::Not' do
         | 
| 398 | 
            +
            				it 'module singleton method' do
         | 
| 399 | 
            +
            					klass.send :rtype, :return_nil, [Rtype::not(String)] => nil
         | 
| 400 | 
            +
            					instance.return_nil(123)
         | 
| 401 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 402 | 
            +
            				end
         | 
| 403 | 
            +
             | 
| 404 | 
            +
            				it 'class singleton [] method' do
         | 
| 405 | 
            +
            					klass.send :rtype, :return_nil, [ Rtype::Behavior::Not[String] ] => nil
         | 
| 406 | 
            +
            					instance.return_nil(123)
         | 
| 407 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 408 | 
            +
            				end
         | 
| 409 | 
            +
             | 
| 410 | 
            +
            				it 'core extension method' do
         | 
| 411 | 
            +
            					klass.send :rtype, :return_nil, [ String.not ] => nil
         | 
| 412 | 
            +
            					instance.return_nil(123)
         | 
| 413 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 414 | 
            +
            				end
         | 
| 312 415 | 
             
            			end
         | 
| 313 416 |  | 
| 314 | 
            -
            			 | 
| 315 | 
            -
            				 | 
| 316 | 
            -
             | 
| 317 | 
            -
             | 
| 417 | 
            +
            			describe 'Rtype::Behavior::Xor' do
         | 
| 418 | 
            +
            				it 'module singleton method' do
         | 
| 419 | 
            +
            					klass.send :rtype, :return_nil, [Rtype::xor(:to_i, String)] => nil
         | 
| 420 | 
            +
            					instance.return_nil(123)
         | 
| 421 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 422 | 
            +
            				end
         | 
| 423 | 
            +
             | 
| 424 | 
            +
            				it 'class singleton [] method' do
         | 
| 425 | 
            +
            					klass.send :rtype, :return_nil, [ Rtype::Behavior::Xor[:to_i, String] ] => nil
         | 
| 426 | 
            +
            					instance.return_nil(123)
         | 
| 427 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 428 | 
            +
            				end
         | 
| 429 | 
            +
             | 
| 430 | 
            +
            				it 'core extension method' do
         | 
| 431 | 
            +
            					klass.send :rtype, :return_nil, [ :to_i.xor(String) ] => nil
         | 
| 432 | 
            +
            					instance.return_nil(123)
         | 
| 433 | 
            +
            					expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
         | 
| 434 | 
            +
            				end
         | 
| 318 435 | 
             
            			end
         | 
| 319 436 | 
             
            		end
         | 
| 320 437 | 
             
            	end
         | 
| @@ -334,6 +451,27 @@ describe Rtype do | |
| 334 451 | 
             
            				expect {instance.sum(1, 2.0)}.to raise_error Rtype::ArgumentTypeError
         | 
| 335 452 | 
             
            			end
         | 
| 336 453 |  | 
| 454 | 
            +
            			it 'two array' do
         | 
| 455 | 
            +
            				klass.send :rtype, :sum, [[Integer], [Integer]] => Any
         | 
| 456 | 
            +
            				instance.sum([1], [2])
         | 
| 457 | 
            +
            				expect {instance.sum([1], 2)}.to raise_error Rtype::ArgumentTypeError
         | 
| 458 | 
            +
            				expect {instance.sum([1], ["str"])}.to raise_error Rtype::ArgumentTypeError
         | 
| 459 | 
            +
            			end
         | 
| 460 | 
            +
             | 
| 461 | 
            +
            			it 'two hash' do
         | 
| 462 | 
            +
            				klass.send :rtype, :two_args, [{k: Integer}, {k: Integer}, {}] => Any
         | 
| 463 | 
            +
            				instance.two_args({k: 123}, {k: 456}, {})
         | 
| 464 | 
            +
            				expect {
         | 
| 465 | 
            +
            					instance.two_args({k: 123}, {}, {})
         | 
| 466 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 467 | 
            +
            				expect {
         | 
| 468 | 
            +
            					instance.two_args({k: 123}, 456, {})
         | 
| 469 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 470 | 
            +
            				expect {
         | 
| 471 | 
            +
            					instance.two_args({k: 123}, {k: "str"}, {})
         | 
| 472 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 473 | 
            +
            			end
         | 
| 474 | 
            +
             | 
| 337 475 | 
             
            			it 'one keyword argument' do
         | 
| 338 476 | 
             
            				klass.send :rtype, :kwarg, {a: Float} => Any
         | 
| 339 477 | 
             
            				expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
         | 
| @@ -370,6 +508,25 @@ describe Rtype do | |
| 370 508 | 
             
            				expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
         | 
| 371 509 | 
             
            				expect {instance.kwarg(:a => 1)}.to raise_error Rtype::ArgumentTypeError
         | 
| 372 510 | 
             
            			end
         | 
| 511 | 
            +
             | 
| 512 | 
            +
            			context 'when hash is not last element' do
         | 
| 513 | 
            +
            				it 'is hash-type argument, not keyword argument' do
         | 
| 514 | 
            +
            					klass.send :rtype, :return_arg, [{a: String}, {}] => Any
         | 
| 515 | 
            +
            					expect {
         | 
| 516 | 
            +
            						instance.return_arg({a: 123}, {})
         | 
| 517 | 
            +
            					}.to raise_error Rtype::ArgumentTypeError
         | 
| 518 | 
            +
            				end
         | 
| 519 | 
            +
            			end
         | 
| 520 | 
            +
             | 
| 521 | 
            +
            			it 'hash-type argument and keyword argument' do
         | 
| 522 | 
            +
            				klass.send :rtype, :arg_and_kwarg, [{a: String}, {b: String}] => Any
         | 
| 523 | 
            +
            				expect {
         | 
| 524 | 
            +
            					instance.arg_and_kwarg({a: 123}, b: "str")
         | 
| 525 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 526 | 
            +
            				expect {
         | 
| 527 | 
            +
            					instance.arg_and_kwarg({a: "str"}, b: 123)
         | 
| 528 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 529 | 
            +
            			end
         | 
| 373 530 | 
             
            		end
         | 
| 374 531 |  | 
| 375 532 | 
             
            		describe 'check return' do
         | 
| @@ -400,13 +557,13 @@ describe Rtype do | |
| 400 557 | 
             
            				end
         | 
| 401 558 | 
             
            				it 'invalid return signature' do
         | 
| 402 559 | 
             
            					expect {
         | 
| 403 | 
            -
            						klass.send :rtype, :return_arg, [] =>  | 
| 560 | 
            +
            						klass.send :rtype, :return_arg, [] => 123
         | 
| 404 561 | 
             
            					}.to raise_error Rtype::TypeSignatureError
         | 
| 405 562 | 
             
            				end
         | 
| 406 563 |  | 
| 407 564 | 
             
            				it 'invalid type behavior in arguments' do
         | 
| 408 565 | 
             
            					expect {
         | 
| 409 | 
            -
            						klass.send :rtype, :sum_kwargs, [{a:  | 
| 566 | 
            +
            						klass.send :rtype, :sum_kwargs, [{a: 123}, {b: Integer}] => Any
         | 
| 410 567 | 
             
            					}.to raise_error Rtype::TypeSignatureError
         | 
| 411 568 | 
             
            					expect {
         | 
| 412 569 | 
             
            						klass.send :rtype, :return_arg, [123] => Any
         | 
| @@ -418,7 +575,7 @@ describe Rtype do | |
| 418 575 | 
             
            						klass.send :rtype, :kwarg, {a: 123} => Any
         | 
| 419 576 | 
             
            					}.to raise_error Rtype::TypeSignatureError
         | 
| 420 577 | 
             
            					expect {
         | 
| 421 | 
            -
            						klass.send :rtype, :kwarg, {a: {b:  | 
| 578 | 
            +
            						klass.send :rtype, :kwarg, {a: {b: 123}} => Any
         | 
| 422 579 | 
             
            					}.to raise_error Rtype::TypeSignatureError
         | 
| 423 580 | 
             
            					expect {
         | 
| 424 581 | 
             
            						klass.send :rtype, :kwarg, {Object.new => Integer} => Any
         | 
| @@ -506,6 +663,15 @@ describe Rtype do | |
| 506 663 | 
             
            				instance.three_kwargs(a: "abc", b: 123, c: 456)
         | 
| 507 664 | 
             
            			end
         | 
| 508 665 | 
             
            		end
         | 
| 666 | 
            +
             | 
| 667 | 
            +
            		context 'when hash type argument contain a key not configured to rtype' do
         | 
| 668 | 
            +
            			it 'raises error' do
         | 
| 669 | 
            +
            				klass.send :rtype, :return_arg, [{a: String}, {}] => Any
         | 
| 670 | 
            +
            				expect {
         | 
| 671 | 
            +
            					instance.return_arg({a: "str", b: "str"}, {})
         | 
| 672 | 
            +
            				}.to raise_error Rtype::ArgumentTypeError
         | 
| 673 | 
            +
            			end
         | 
| 674 | 
            +
            		end
         | 
| 509 675 | 
             
            	end
         | 
| 510 676 |  | 
| 511 677 | 
             
            	describe "Call Rtype`s static method directly" do
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rtype
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Sputnik Gugja
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016- | 
| 11 | 
            +
            date: 2016-04-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rake
         | 
| @@ -52,7 +52,7 @@ dependencies: | |
| 52 52 | 
             
                - - ">="
         | 
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 54 | 
             
                    version: '0'
         | 
| 55 | 
            -
            description:  | 
| 55 | 
            +
            description: The fastest type checking gem
         | 
| 56 56 | 
             
            email:
         | 
| 57 57 | 
             
            - sputnikgugja@gmail.com
         | 
| 58 58 | 
             
            executables: []
         | 
| @@ -69,6 +69,7 @@ files: | |
| 69 69 | 
             
            - lib/rtype/behavior.rb
         | 
| 70 70 | 
             
            - lib/rtype/behavior/and.rb
         | 
| 71 71 | 
             
            - lib/rtype/behavior/base.rb
         | 
| 72 | 
            +
            - lib/rtype/behavior/core_ext.rb
         | 
| 72 73 | 
             
            - lib/rtype/behavior/nilable.rb
         | 
| 73 74 | 
             
            - lib/rtype/behavior/not.rb
         | 
| 74 75 | 
             
            - lib/rtype/behavior/or.rb
         |