rtype-native 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7da1eeceea62ee24758dd2af72476310ba28b645
4
- data.tar.gz: 4b5902e8d4a5f83939893a7d9bcee7b2d215ee5a
3
+ metadata.gz: 28069650cae37a261b249dc6a17e02fff057366a
4
+ data.tar.gz: 9aec95155efd5ce7bbde4ca1485b758b2cdce470
5
5
  SHA512:
6
- metadata.gz: e6c32b52f0d3c39da572c560007d09de8aef01ff1ca8165b5254c0814a18b7fe9eaf58f6db789034b3ece1c3120e984f4db760d80b9804c9a385f35eb6e7f3c7
7
- data.tar.gz: 9e32a39033098b5ac96290f6c6533ef16eaf683c713034f3c969a97b4466f685d41a0c2177d931b4cecde97622168cf98a749af523c353c2f37f30cf58cee59d
6
+ metadata.gz: e25171477b08e51f113596422ad0d895e183e0ded024b28029581b14eaaede365fa87947f001db53e94dc3d5b951959f9ac70913bfab794f2486eae2ea6874cd
7
+ data.tar.gz: 8ac147a3f4a894d8f53e160c95a516b1cea118e40bb59b8b1fdc20a8ff4e48d2a4d10c785cf481ad4b129664ffc13f86b972f5447512bd6da94a25071055ec32
data/README.md CHANGED
@@ -8,22 +8,22 @@ You can do the type checking in Ruby with this gem!
8
8
  ```ruby
9
9
  require 'rtype'
10
10
 
11
- rtype :sum, [:to_i, Numeric] => Numeric
12
- def sum(a, b)
13
- a.to_i + b
14
- end
15
-
16
- sum(123, "asd")
17
- # (Rtype::ArgumentTypeError) for 2nd argument:
18
- # Expected "asd" to be a Numeric
19
-
20
11
  class Test
21
- rtype_self :invert, {state: Boolean} => Boolean
12
+ rtype [:to_i, Numeric] => Numeric
13
+ def sum(a, b)
14
+ a.to_i + b
15
+ end
16
+
17
+ rtype {state: Boolean} => Boolean
22
18
  def self.invert(state:)
23
19
  !state
24
20
  end
25
21
  end
26
22
 
23
+ Test.new.sum(123, "asd")
24
+ # (Rtype::ArgumentTypeError) for 2nd argument:
25
+ # Expected "asd" to be a Numeric
26
+
27
27
  Test::invert(state: 0)
28
28
  # (Rtype::ArgumentTypeError) for 'state' argument:
29
29
  # Expected 0 to be a Boolean
@@ -102,7 +102,7 @@ then, Rtype use it. (Do not `require 'rtype-java'`)
102
102
  - Each of value’s elements must be valid
103
103
  - Value's key list must be equal to the hash's key list
104
104
  - **String** key is **different** from **symbol** key
105
- - The type signature could not be positioned at last index
105
+ - vs Keyword arguments
106
106
  - `[{}]` is **not** hash type argument. it is keyword argument because its position is last
107
107
  - `[{}, {}]` is empty hash type argument (first) and one empty keyword argument (second)
108
108
  - `[{}, {}, {}]` is two empty hash type argument (first, second) and empty keyword argument (last)
@@ -158,15 +158,15 @@ then, Rtype use it. (Do not `require 'rtype-java'`)
158
158
  require 'rtype'
159
159
 
160
160
  class Example
161
- rtype :test, [Integer] => nil
161
+ rtype [Integer] => nil
162
162
  def test(i)
163
163
  end
164
164
 
165
- rtype :any_type_arg, [Any] => nil
165
+ rtype [Any] => nil
166
166
  def any_type_arg(arg)
167
167
  end
168
168
 
169
- rtype :return_type_test, [] => Integer
169
+ rtype [] => Integer
170
170
  def return_type_test
171
171
  "not integer"
172
172
  end
@@ -189,13 +189,13 @@ e.return_type_test
189
189
  require 'rtype'
190
190
 
191
191
  class Example
192
- rtype :say_your_name, {name: String} => Any
192
+ rtype {name: String} => Any
193
193
  def say_your_name(name:)
194
194
  puts "My name is #{name}"
195
195
  end
196
196
 
197
197
  # Mixing positional arguments and keyword arguments
198
- rtype :name_and_age, [String, {age: Integer}] => Any
198
+ rtype [String, {age: Integer}] => Any
199
199
  def name_and_age(name, age:)
200
200
  puts "Name: #{name}, Age: #{age}"
201
201
  end
@@ -214,7 +214,7 @@ Example.new.say_your_name(name: 12345)
214
214
  require 'rtype'
215
215
 
216
216
  class Duck
217
- rtype :says, [:to_i] => Any
217
+ rtype [:to_i] => Any
218
218
  def says(i)
219
219
  puts "duck:" + " quack"*i.to_i
220
220
  end
@@ -286,7 +286,7 @@ func({msg: "hello hash"}, {}) # hello hash
286
286
  ```
287
287
 
288
288
  #### rtype with attr_accessor
289
- `rtype_accessor`
289
+ `rtype_accessor` : call attr_accessor and make it typed method
290
290
 
291
291
  You can use `rtype_accessor_self` for static accessor.
292
292
 
@@ -295,7 +295,7 @@ require 'rtype'
295
295
 
296
296
  class Example
297
297
  rtype_accessor :value, String
298
- attr_accessor :value
298
+
299
299
  def initialize
300
300
  @value = 456
301
301
  end
@@ -316,9 +316,9 @@ Example.new.value
316
316
  require 'rtype'
317
317
 
318
318
  class Example
319
- rtype :and_test, [String.and(:func)] => Any
319
+ rtype [String.and(:func)] => Any
320
320
  # also works:
321
- # rtype :and_test, [Rtype::and(String, :func)] => Any
321
+ # rtype [Rtype::and(String, :func)] => Any
322
322
  def and_test(arg)
323
323
  end
324
324
  end
@@ -354,7 +354,7 @@ module Game
354
354
  class Player < Entity
355
355
  include Rtype::Behavior
356
356
 
357
- rtype :attack, [And[*ENEMY]] => Any
357
+ rtype [And[*ENEMY]] => Any
358
358
  def attacks(enemy)
359
359
  "Player attacks '#{enemy.name}' (level #{enemy.level})!"
360
360
  end
@@ -375,12 +375,18 @@ Game::Player.new.attacks Game::Slime.new
375
375
  # Player attacks 'Powerful Slime' (level 123)!
376
376
  ```
377
377
 
378
- #### Position of `rtype` && (symbol || string)
378
+ #### Position of `rtype` && (Specify method name || annotation mode) && (Symbol || String)
379
379
  ```ruby
380
380
  require 'rtype'
381
381
 
382
382
  class Example
383
- # Works. Recommended
383
+ # Recommended. Annotation mode (no method name required)
384
+ rtype [Integer, String] => String
385
+ def hello_world(i, str)
386
+ puts "Hello? #{i} #{st
387
+ end
388
+
389
+ # Works (specifying method name)
384
390
  rtype :hello_world, [Integer, String] => String
385
391
  def hello_world(i, str)
386
392
  puts "Hello? #{i} #{st
@@ -397,11 +403,17 @@ class Example
397
403
  def hello_world_three(i, str)
398
404
  puts "Hello? #{i} #{str}"
399
405
  end
406
+
407
+ # Don't works. `rtype` works for next method
408
+ def hello_world_four(i, str)
409
+ puts "Hello? #{i} #{str}"
410
+ end
411
+ rtype [Integer, String] => String
400
412
  end
401
413
  ```
402
414
 
403
415
  #### Outside of module (root)
404
- Yes, it works
416
+ Outside of module, annotation mode don't works. You must specify method name.
405
417
 
406
418
  ```ruby
407
419
  rtype :say, [String] => Any
@@ -409,11 +421,29 @@ def say(message)
409
421
  puts message
410
422
  end
411
423
 
412
- say "Hello" # Hello
424
+ Test.new.say "Hello" # Hello
425
+
426
+ rtype [String] => Any
427
+ # (ArgumentError) Annotation mode not working out of module
413
428
  ```
414
429
 
415
430
  #### Static(singleton) method
416
- Use `rtype_self`
431
+ rtype annotation mode works both instance and class method
432
+
433
+ ```ruby
434
+ require 'rtype'
435
+
436
+ class Example
437
+ rtype [:to_i] => Any
438
+ def self.say_ya(i)
439
+ puts "say" + " ya"*i.to_i
440
+ end
441
+ end
442
+
443
+ Example::say_ya(3) #say ya ya ya
444
+ ```
445
+
446
+ however, if you specify method name, you must use `rtype_self` instead of `rtype`
417
447
 
418
448
  ```ruby
419
449
  require 'rtype'
@@ -437,7 +467,7 @@ Any change of this doesn't affect type checking
437
467
  require 'rtype'
438
468
 
439
469
  class Example
440
- rtype :test, [:to_i] => Any
470
+ rtype [:to_i] => Any
441
471
  def test(i)
442
472
  end
443
473
  end
@@ -34,17 +34,17 @@ end
34
34
  pure_obj = PureTest.new
35
35
 
36
36
  class RtypeTest
37
- rtype :sum, [Numeric, Numeric] => Numeric
37
+ rtype [Numeric, Numeric] => Numeric
38
38
  def sum(x, y)
39
39
  x + y
40
40
  end
41
41
 
42
- rtype :mul, [:to_i, :to_i] => Numeric
42
+ rtype [:to_i, :to_i] => Numeric
43
43
  def mul(x, y)
44
44
  x * y
45
45
  end
46
46
 
47
- rtype :args, [Integer, Numeric, String, :to_i] => Any
47
+ rtype [Integer, Numeric, String, :to_i] => Any
48
48
  def args(a, b, c, d)
49
49
  end
50
50
  end
data/ext/rtype/c/rtype.c CHANGED
@@ -1,6 +1,7 @@
1
1
  #include "rtype.h"
2
2
 
3
3
  VALUE rb_mRtype, rb_mRtypeBehavior, rb_cRtypeBehaviorBase, rb_eRtypeArgumentTypeError, rb_eRtypeTypeSignatureError, rb_eRtypeReturnTypeError;
4
+ static ID id_to_s, id_keys, id_eqeq, id_include, id_valid, id_call;
4
5
 
5
6
  VALUE
6
7
  rb_rtype_valid(VALUE self, VALUE expected, VALUE value) {
@@ -11,14 +12,14 @@ rb_rtype_valid(VALUE self, VALUE expected, VALUE value) {
11
12
  case T_SYMBOL:
12
13
  return rb_respond_to(value, rb_to_id(expected)) ? Qtrue : Qfalse;
13
14
  case T_REGEXP:
14
- return rb_reg_match( expected, rb_funcall(value, rb_intern("to_s"), 0) ) != Qnil ? Qtrue : Qfalse;
15
+ return rb_reg_match( expected, rb_funcall(value, id_to_s, 0) ) != Qnil ? Qtrue : Qfalse;
15
16
  case T_HASH:
16
17
  if( !RB_TYPE_P(value, T_HASH) ) {
17
18
  return Qfalse;
18
19
  }
19
- VALUE e_keys = rb_funcall(expected, rb_intern("keys"), 0);
20
- VALUE v_keys = rb_funcall(value, rb_intern("keys"), 0);
21
- if( !RTEST(rb_funcall(e_keys, rb_intern("=="), 1, v_keys)) ) {
20
+ VALUE e_keys = rb_funcall(expected, id_keys, 0);
21
+ VALUE v_keys = rb_funcall(value, id_keys, 0);
22
+ if( !RTEST(rb_funcall(e_keys, id_eqeq, 1, v_keys)) ) {
22
23
  return Qfalse;
23
24
  }
24
25
 
@@ -57,13 +58,13 @@ rb_rtype_valid(VALUE self, VALUE expected, VALUE value) {
57
58
  return !RTEST(value) ? Qtrue : Qfalse;
58
59
  default:
59
60
  if(rb_obj_is_kind_of(expected, rb_cRange)) {
60
- return rb_funcall(expected, rb_intern("include?"), 1, value);
61
+ return rb_funcall(expected, id_include, 1, value);
61
62
  }
62
63
  else if(rb_obj_is_kind_of(expected, rb_cProc)) {
63
- return RTEST(rb_funcall(expected, rb_intern("call"), 1, value)) ? Qtrue : Qfalse;
64
+ return RTEST(rb_funcall(expected, id_call, 1, value)) ? Qtrue : Qfalse;
64
65
  }
65
66
  else if( RTEST(rb_obj_is_kind_of(expected, rb_cRtypeBehaviorBase)) ) {
66
- return rb_funcall(expected, rb_intern("valid?"), 1, value);
67
+ return rb_funcall(expected, id_valid, 1, value);
67
68
  }
68
69
  else {
69
70
  VALUE str = rb_any_to_s(expected);
@@ -134,6 +135,13 @@ void Init_rtype_native(void) {
134
135
  rb_eRtypeTypeSignatureError = rb_define_class_under(rb_mRtype, "TypeSignatureError", rb_eArgError);
135
136
  rb_eRtypeReturnTypeError = rb_define_class_under(rb_mRtype, "ReturnTypeError", rb_eStandardError);
136
137
 
138
+ id_to_s = rb_intern("to_s");
139
+ id_keys = rb_intern("keys");
140
+ id_eqeq = rb_intern("==");
141
+ id_include = rb_intern("include?");
142
+ id_valid = rb_intern("valid?");
143
+ id_call = rb_intern("call");
144
+
137
145
  rb_define_method(rb_mRtype, "valid?", rb_rtype_valid, 2);
138
146
  rb_define_method(rb_mRtype, "assert_arguments_type", rb_rtype_assert_arguments_type, 2);
139
147
  rb_define_method(rb_mRtype, "assert_arguments_type_with_keywords", rb_rtype_assert_arguments_type_with_keywords, 4);
data/spec/rtype_spec.rb CHANGED
@@ -62,6 +62,38 @@ describe Rtype do
62
62
  end
63
63
 
64
64
  describe 'Kernel#rtype' do
65
+ context "with annotation mode" do
66
+ it "works with instance method" do
67
+ class AnnotationTest
68
+ rtype [String] => Any
69
+ def test(str)
70
+ end
71
+ end
72
+ expect {
73
+ AnnotationTest.new.test(123)
74
+ }.to raise_error Rtype::ArgumentTypeError
75
+ end
76
+ it "works with class method" do
77
+ class AnnotationTest
78
+ rtype [String] => Any
79
+ def self.class_method_test(str)
80
+ end
81
+ end
82
+ expect {
83
+ AnnotationTest::class_method_test(123)
84
+ }.to raise_error Rtype::ArgumentTypeError
85
+ end
86
+ context "outside of module" do
87
+ it "doesn't works" do
88
+ expect {
89
+ rtype [String] => Any
90
+ def annotation_test(str)
91
+ end
92
+ }.to raise_error ArgumentError
93
+ end
94
+ end
95
+ end
96
+
65
97
  it "outside of module" do
66
98
  rtype :test_args, [String] => Any
67
99
  def test_args(str)
@@ -119,7 +151,6 @@ describe Rtype do
119
151
  it 'Kernel#rtype_accessor' do
120
152
  class TestClass
121
153
  rtype_accessor :value, String
122
- attr_accessor :value
123
154
 
124
155
  def initialize
125
156
  @value = 123
@@ -134,12 +165,6 @@ describe Rtype do
134
165
  @@val = 123
135
166
 
136
167
  rtype_accessor_self :value, String
137
- def self.value=(val)
138
- @@val = val
139
- end
140
- def self.value
141
- @@val
142
- end
143
168
  end
144
169
  expect {TestClass::value = 123}.to raise_error Rtype::ArgumentTypeError
145
170
  expect {TestClass::value}.to raise_error Rtype::ReturnTypeError
@@ -198,11 +223,15 @@ describe Rtype do
198
223
  end
199
224
  it "is wrong args" do
200
225
  klass.send :rtype, :return_arg, [1..10] => Any
201
- expect {instance.return_arg(1001)}.to raise_error Rtype::ArgumentTypeError
226
+ expect {
227
+ instance.return_arg(1001)
228
+ }.to raise_error Rtype::ArgumentTypeError
202
229
  end
203
230
  it "is wrong result" do
204
231
  klass.send :rtype, :return_nil, [Any] => 1..10
205
- expect {instance.return_nil(5)}.to raise_error Rtype::ReturnTypeError
232
+ expect {
233
+ instance.return_nil(5)
234
+ }.to raise_error Rtype::ReturnTypeError
206
235
  end
207
236
  end
208
237
 
@@ -549,13 +578,13 @@ describe Rtype do
549
578
  end
550
579
 
551
580
  describe 'wrong case' do
552
- describe 'invalid signature form' do
553
- it 'invalid argument signature' do
581
+ describe 'invalid type signature' do
582
+ it 'invalid arguments type signature' do
554
583
  expect {
555
584
  klass.send :rtype, :return_arg, Any => nil
556
585
  }.to raise_error Rtype::TypeSignatureError
557
586
  end
558
- it 'invalid return signature' do
587
+ it 'invalid return type signature' do
559
588
  expect {
560
589
  klass.send :rtype, :return_arg, [] => 123
561
590
  }.to raise_error Rtype::TypeSignatureError
@@ -590,6 +619,18 @@ describe Rtype do
590
619
  klass.send :rtype, :return_arg, [] => "abc"
591
620
  }.to raise_error Rtype::TypeSignatureError
592
621
  end
622
+
623
+ context "with annotation mode" do
624
+ it 'works' do
625
+ expect {
626
+ class AnnotationTest
627
+ rtype [String, 123] => Any
628
+ def invalid_test(arg)
629
+ end
630
+ end
631
+ }.to raise_error Rtype::TypeSignatureError
632
+ end
633
+ end
593
634
  end
594
635
  end
595
636
  end
@@ -672,6 +713,40 @@ describe Rtype do
672
713
  }.to raise_error Rtype::ArgumentTypeError
673
714
  end
674
715
  end
716
+
717
+ it "One rtype annotation affect only one method" do
718
+ class AnnotationTest
719
+ rtype [String] => Any
720
+ def one(str)
721
+ end
722
+
723
+ def two(str)
724
+ end
725
+ end
726
+ expect {
727
+ AnnotationTest.new.one(123)
728
+ }.to raise_error Rtype::ArgumentTypeError
729
+ AnnotationTest.new.two(123)
730
+ end
731
+
732
+ it "One rtype annotation affect only one method, regardless of instance method or class method" do
733
+ class AnnotationTest2
734
+ rtype [String] => Any
735
+ def self.static_one(str)
736
+ end
737
+
738
+ def inst_one(str)
739
+ end
740
+
741
+ def self.static_two(str)
742
+ end
743
+ end
744
+ expect {
745
+ AnnotationTest2::static_one(123)
746
+ }.to raise_error Rtype::ArgumentTypeError
747
+ AnnotationTest2.new.inst_one(123)
748
+ AnnotationTest2::static_two(123)
749
+ end
675
750
  end
676
751
 
677
752
  describe "Call Rtype`s static method directly" do
@@ -687,6 +762,12 @@ describe Rtype do
687
762
  end
688
763
 
689
764
  it 'Rtype::valid?' do
765
+ expect(
766
+ Rtype::valid?(String, "str")
767
+ ).to be true
768
+ expect(
769
+ Rtype::valid?(Integer, "str")
770
+ ).to be false
690
771
  expect {
691
772
  Rtype::valid?("Invalid type behavior", "Test Value")
692
773
  }.to raise_error Rtype::TypeSignatureError
@@ -709,5 +790,33 @@ describe Rtype do
709
790
  Rtype::assert_return_type nil, "No nil"
710
791
  }.to raise_error Rtype::ReturnTypeError
711
792
  end
793
+
794
+ it 'Rtype::assert_valid_type_sig' do
795
+ Rtype::assert_valid_type_sig([Integer, String] => Any)
796
+ expect {
797
+ Rtype::assert_valid_type_sig([Integer, String])
798
+ }.to raise_error Rtype::TypeSignatureError
799
+ end
800
+
801
+ it 'Rtype::assert_valid_arguments_type_sig' do
802
+ Rtype::assert_valid_arguments_type_sig([Integer, String])
803
+ expect {
804
+ Rtype::assert_valid_arguments_type_sig("[Integer, String]")
805
+ }.to raise_error Rtype::TypeSignatureError
806
+ end
807
+
808
+ it 'Rtype::assert_valid_argument_type_sig_element' do
809
+ Rtype::assert_valid_argument_type_sig_element(Integer)
810
+ expect {
811
+ Rtype::assert_valid_argument_type_sig_element("Integer")
812
+ }.to raise_error Rtype::TypeSignatureError
813
+ end
814
+
815
+ it 'Rtype::assert_valid_return_type_sig' do
816
+ Rtype::assert_valid_return_type_sig(Integer)
817
+ expect {
818
+ Rtype::assert_valid_return_type_sig("Integer")
819
+ }.to raise_error Rtype::TypeSignatureError
820
+ end
712
821
  end
713
822
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rtype-native
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.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-04-01 00:00:00.000000000 Z
11
+ date: 2016-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rtype
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.4.0
19
+ version: 0.5.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.4.0
26
+ version: 0.5.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement