rtype 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c238c2b45a71c23c3d5c3a4f442d7c71f512b05b
4
- data.tar.gz: a4068b256226cc7b8b16e1dbb31c1c086e892fb1
3
+ metadata.gz: 580a93433f2e77fc81b6a9abd7b14d390952f05d
4
+ data.tar.gz: 78f18ddfed8634652bc9c0da161dec708db99293
5
5
  SHA512:
6
- metadata.gz: a71adbd7caa172f8aeda43b017f9e8a28ff57851c96e21a4461177b24fa0e242624db8193482e07bfda8999b687179507648693eac8fd9eedcd8bbbedee84f4a
7
- data.tar.gz: 0d308aeadfa63866b391c219c2d3e162722221aed6c8e6480ebc72b7fb0f934f32d173a12cef40c23a6d909425efea898dbe56129f5877c1f1ff848cd402395f
6
+ metadata.gz: e6df637fa65774fcf9addcf06dc4b8fc526587e1cfe448229644b8756f17129f603086a90a68d16422900f5b20020927bd67e403f8550ffb1823b4484d365d39
7
+ data.tar.gz: 653c366459022762cf1e5ded44eac4452365b6549f23efad8c1f875eb785ed14d56788d72efe222d6a76906367f908b7594f22c6372707c931079d2af104a5bb
data/README.md CHANGED
@@ -31,7 +31,10 @@ Test::invert(state: 0)
31
31
 
32
32
  ## Requirements
33
33
  - Ruby >= 2.1
34
- - MRI or RBX if native extension is used. Rtype itself without it is pure-ruby gem, therefore you can use Rtype in JRuby, etc.
34
+ - MRI or RBX
35
+ - If C native extension is used, otherwise it is not required
36
+ - JRuby
37
+ - If Java extension is used, otherwise it is not required
35
38
 
36
39
  ## Features
37
40
  - Provide type checking for argument and return
@@ -49,12 +52,29 @@ require 'rtype'
49
52
  ```
50
53
 
51
54
  ### Native extension
52
- Rtype itself is pure-ruby gem. but you can make it more faster by native extension.
55
+ Rtype itself is pure-ruby gem. but you can make it more faster by using native extension.
53
56
 
54
- Just run `gem install rtype-native` or add `gem 'rtype-native'` to your `Gemfile`, then Rtype use it.
55
- (Do not `require 'rtype-native'`)
57
+ #### Native extension for MRI, RBX
58
+ Just run
59
+ ```ruby
60
+ gem install rtype-native
61
+ ```
62
+ or add to your `Gemfile`:
63
+ ```ruby
64
+ gem 'rtype-native'
65
+ ```
66
+ then, Rtype use it. (Do not `require 'rtype-native'`)
56
67
 
57
- It is only for MRI or RBX. JRuby extension not supported yet.
68
+ #### Java extension for JRuby
69
+ Just run
70
+ ```ruby
71
+ gem install rtype-java
72
+ ```
73
+ or add to your `Gemfile`:
74
+ ```ruby
75
+ gem 'rtype-java'
76
+ ```
77
+ then, Rtype use it. (Do not `require 'rtype-java'`)
58
78
 
59
79
  ## Usage
60
80
 
@@ -370,68 +390,70 @@ Result of `rake benchmark` ([source](https://github.com/sputnikgugja/rtype/tree/
370
390
 
371
391
  ### MRI
372
392
  ```
393
+ Rtype with C native extension
373
394
  Ruby version: 2.1.7
374
395
  Ruby engine: ruby
375
396
  Ruby description: ruby 2.1.7p400 (2015-08-18 revision 51632) [x64-mingw32]
376
- Rtype version: 0.2.0
397
+ Rtype version: 0.3.0
377
398
  Rubype version: 0.3.1
378
399
  Sig version: 1.0.1
379
400
  Contracts version: 0.13.0
380
401
  Typecheck version: 0.1.2
381
402
  Warming up --------------------------------------
382
- pure 85.600k i/100ms
383
- rtype 25.735k i/100ms
384
- rubype 20.922k i/100ms
385
- sig 8.960k i/100ms
386
- contracts 4.659k i/100ms
387
- typecheck 1.102k i/100ms
403
+ pure 85.328k i/100ms
404
+ rtype 25.665k i/100ms
405
+ rubype 21.414k i/100ms
406
+ sig 8.921k i/100ms
407
+ contracts 4.638k i/100ms
408
+ typecheck 1.110k i/100ms
388
409
  Calculating -------------------------------------
389
- pure 3.273M (± 2.4%) i/s - 16.435M
390
- rtype 340.376k1.9%) i/s - 1.724M
391
- rubype 268.253k4.2%) i/s - 1.339M
392
- sig 100.050k (± 1.9%) i/s - 501.760k
393
- contracts 50.027k2.0%) i/s - 251.586k
394
- typecheck 11.317k (± 1.4%) i/s - 57.304k
410
+ pure 3.282M (± 2.7%) i/s - 16.468M
411
+ rtype 339.065k2.6%) i/s - 1.720M
412
+ rubype 266.893k5.9%) i/s - 1.349M
413
+ sig 99.952k2.1%) i/s - 499.576k
414
+ contracts 49.693k1.5%) i/s - 250.452k
415
+ typecheck 11.356k (± 1.6%) i/s - 57.720k
395
416
 
396
417
  Comparison:
397
- pure: 3272978.0 i/s
398
- rtype: 340375.8 i/s - 9.62x slower
399
- rubype: 268252.5 i/s - 12.20x slower
400
- sig: 100050.1 i/s - 32.71x slower
401
- contracts: 50026.9 i/s - 65.42x slower
402
- typecheck: 11317.1 i/s - 289.21x slower
418
+ pure: 3282431.9 i/s
419
+ rtype: 339064.9 i/s - 9.68x slower
420
+ rubype: 266892.9 i/s - 12.30x slower
421
+ sig: 99952.2 i/s - 32.84x slower
422
+ contracts: 49693.0 i/s - 66.05x slower
423
+ typecheck: 11355.9 i/s - 289.05x slower
403
424
  ```
404
425
 
405
426
  ### JRuby
406
427
  Without Rubype that doesn't support JRuby
407
428
 
408
429
  ```
430
+ Rtype with Java extension
409
431
  Ruby version: 2.2.3
410
432
  Ruby engine: jruby
411
433
  Ruby description: jruby 9.0.5.0 (2.2.3) 2016-01-26 7bee00d Java HotSpot(TM) 64-Bit Server VM 25.60-b23 on 1.8.0_60-b27 +jit [Windows 10-amd64]
412
- Rtype version: 0.2.0
434
+ Rtype version: 0.3.0
413
435
  Sig version: 1.0.1
414
436
  Contracts version: 0.13.0
415
437
  Typecheck version: 0.1.2
416
438
  Warming up --------------------------------------
417
- pure 29.127k i/100ms
418
- rtype 4.566k i/100ms
419
- sig 4.162k i/100ms
420
- contracts 776.000 i/100ms
421
- typecheck 981.000 i/100ms
439
+ pure 9.994k i/100ms
440
+ rtype 6.181k i/100ms
441
+ sig 4.041k i/100ms
442
+ contracts 951.000 i/100ms
443
+ typecheck 970.000 i/100ms
422
444
  Calculating -------------------------------------
423
- pure 6.705M (±12.0%) i/s - 32.826M
424
- rtype 89.262k (± 3.3%) i/s - 447.468k
425
- sig 74.070k (± 2.0%) i/s - 370.418k
426
- contracts 25.399k (± 2.9%) i/s - 127.264k
427
- typecheck 12.461k (± 9.0%) i/s - 61.803k
445
+ pure 7.128M (?±35.6%) i/s - 30.831M
446
+ rtype 121.556k ( 6.2%) i/s - 605.738k
447
+ sig 72.187k ( 6.4%) i/s - 359.649k
448
+ contracts 24.984k ( 3.9%) i/s - 125.532k
449
+ typecheck 12.041k ( 9.5%) i/s - 60.140k
428
450
 
429
451
  Comparison:
430
- pure: 6705166.5 i/s
431
- rtype: 89262.5 i/s - 75.12x slower
432
- sig: 74070.1 i/s - 90.52x slower
433
- contracts: 25398.9 i/s - 263.99x slower
434
- typecheck: 12460.7 i/s - 538.10x slower
452
+ pure: 7128373.0 i/s
453
+ rtype: 121555.8 i/s - 58.64x slower
454
+ sig: 72186.8 i/s - 98.75x slower
455
+ contracts: 24984.5 i/s - 285.31x slower
456
+ typecheck: 12041.0 i/s - 592.01x slower
435
457
  ```
436
458
 
437
459
  ## Rubype, Sig
data/lib/rtype/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rtype
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
data/lib/rtype.rb CHANGED
@@ -1,8 +1,18 @@
1
- begin
2
- require "rtype/rtype_native"
3
- puts "Rtype with native extension"
4
- rescue LoadError
5
- puts "Rtype without native extension"
1
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
2
+ begin
3
+ require 'java'
4
+ require 'rtype/rtype_java'
5
+ puts "Rtype with Java extension"
6
+ rescue LoadError
7
+ puts "Rtype without native extension"
8
+ end
9
+ else
10
+ begin
11
+ require "rtype/rtype_native"
12
+ puts "Rtype with C native extension"
13
+ rescue LoadError
14
+ puts "Rtype without native extension"
15
+ end
6
16
  end
7
17
 
8
18
  require_relative 'rtype/core_ext'
@@ -14,152 +24,153 @@ require_relative 'rtype/type_signature'
14
24
  require_relative 'rtype/behavior'
15
25
 
16
26
  module Rtype
27
+ extend self
28
+
17
29
  # This is just the 'information'
18
30
  # Any change of this doesn't affect type checking
19
31
  @@type_signatures = Hash.new({})
20
32
 
21
- class << self
22
- def define_typed_method(owner, method_name, type_sig_info)
23
- raise TypeSignatureError, "Invalid type signature" unless valid_type_sig_info_form?(type_sig_info)
24
- method_name = method_name.to_sym
25
- raise ArgumentError, "method_name is nil" if method_name.nil?
26
-
27
- el = type_sig_info.first
28
- arg_sig = el[0]
29
- return_sig = el[1]
30
-
31
- if arg_sig.is_a?(Array)
32
- expected_args = arg_sig
33
- if expected_args.last.is_a?(Hash)
34
- expected_kwargs = expected_args.pop
35
- else
36
- expected_kwargs = {}
37
- end
38
- elsif arg_sig.is_a?(Hash)
39
- expected_args = []
40
- expected_kwargs = arg_sig
33
+ def define_typed_method(owner, method_name, type_sig_info)
34
+ raise TypeSignatureError, "Invalid type signature" unless valid_type_sig_info_form?(type_sig_info)
35
+ method_name = method_name.to_sym
36
+ raise ArgumentError, "method_name is nil" if method_name.nil?
37
+
38
+ el = type_sig_info.first
39
+ arg_sig = el[0]
40
+ return_sig = el[1]
41
+
42
+ if arg_sig.is_a?(Array)
43
+ expected_args = arg_sig
44
+ if expected_args.last.is_a?(Hash)
45
+ expected_kwargs = expected_args.pop
46
+ else
47
+ expected_kwargs = {}
41
48
  end
49
+ elsif arg_sig.is_a?(Hash)
50
+ expected_args = []
51
+ expected_kwargs = arg_sig
52
+ end
42
53
 
43
- expected_args.each { |e| valid?(e, nil) }
44
- if expected_kwargs.keys.any? { |e| !e.is_a?(Symbol) }
45
- raise TypeSignatureError, "Invalid type signature: keyword arguments contain non-symbol key"
46
- end
47
- expected_kwargs.each_value { |e| valid?(e, nil) }
48
- valid?(return_sig, nil) unless return_sig.nil?
54
+ expected_args.each { |e| valid?(e, nil) }
55
+ if expected_kwargs.keys.any? { |e| !e.is_a?(Symbol) }
56
+ raise TypeSignatureError, "Invalid type signature: keyword arguments contain non-symbol key"
57
+ end
58
+ expected_kwargs.each_value { |e| valid?(e, nil) }
59
+ valid?(return_sig, nil) unless return_sig.nil?
49
60
 
50
- sig = TypeSignature.new
51
- sig.argument_type = arg_sig
52
- sig.return_type = return_sig
53
- @@type_signatures[owner][method_name] = sig
61
+ sig = TypeSignature.new
62
+ sig.argument_type = arg_sig
63
+ sig.return_type = return_sig
64
+ @@type_signatures[owner][method_name] = sig
54
65
 
55
- define_typed_method_to_proxy(owner, method_name, expected_args, expected_kwargs, return_sig)
56
- end
66
+ define_typed_method_to_proxy(owner, method_name, expected_args, expected_kwargs, return_sig)
67
+ end
57
68
 
58
- def define_typed_accessor(owner, accessor_name, type_behavior)
59
- getter = accessor_name.to_sym
60
- setter = :"#{accessor_name}="
61
- valid?(type_behavior, nil)
62
- define_typed_method owner, getter, [] => type_behavior
63
- define_typed_method owner, setter, [type_behavior] => Any
64
- end
69
+ def define_typed_accessor(owner, accessor_name, type_behavior)
70
+ getter = accessor_name.to_sym
71
+ setter = :"#{accessor_name}="
72
+ valid?(type_behavior, nil)
73
+ define_typed_method owner, getter, [] => type_behavior
74
+ define_typed_method owner, setter, [type_behavior] => Any
75
+ end
65
76
 
66
- def type_signatures
67
- @@type_signatures
68
- end
77
+ def type_signatures
78
+ @@type_signatures
79
+ end
69
80
 
70
81
  =begin
71
- def assert_keyword_arguments_type(expected_kwargs, kwargs)
72
- kwargs.each do |key, value|
73
- expected = expected_kwargs[key]
74
- unless expected.nil?
75
- unless valid?(expected, value)
76
- raise ArgumentTypeError, "for '#{key}' argument:\n" + type_error_message(expected, value)
77
- end
82
+ def assert_keyword_arguments_type(expected_kwargs, kwargs)
83
+ kwargs.each do |key, value|
84
+ expected = expected_kwargs[key]
85
+ unless expected.nil?
86
+ unless valid?(expected, value)
87
+ raise ArgumentTypeError, "for '#{key}' argument:\n" + type_error_message(expected, value)
78
88
  end
79
89
  end
80
90
  end
91
+ end
81
92
  =end
82
93
 
83
- def arg_type_error_message(idx, expected, value)
84
- "#{arg_message(idx)}\n" + type_error_message(expected, value)
85
- end
94
+ def arg_type_error_message(idx, expected, value)
95
+ "#{arg_message(idx)}\n" + type_error_message(expected, value)
96
+ end
86
97
 
87
- def kwarg_type_error_message(key, expected, value)
88
- "#{kwarg_message(key)}\n" + type_error_message(expected, value)
89
- end
98
+ def kwarg_type_error_message(key, expected, value)
99
+ "#{kwarg_message(key)}\n" + type_error_message(expected, value)
100
+ end
90
101
 
91
- def arg_message(idx)
92
- "for #{(idx+1).ordinalize} argument:"
93
- end
102
+ def arg_message(idx)
103
+ "for #{(idx+1).ordinalize} argument:"
104
+ end
94
105
 
95
- def kwarg_message(key)
96
- "for '#{key}' argument:"
97
- end
106
+ def kwarg_message(key)
107
+ "for '#{key}' argument:"
108
+ end
98
109
 
99
110
 
100
- def type_error_message(expected, value)
101
- case expected
102
- when Rtype::Behavior::Base
103
- expected.error_message(value)
104
- when Module
105
- "Expected #{value.inspect} to be a #{expected}"
106
- when Symbol
107
- "Expected #{value.inspect} to respond to :#{expected}"
108
- when Regexp
109
- "Expected stringified #{value.inspect} to match regexp #{expected.inspect}"
110
- when Range
111
- "Expected #{value.inspect} to be included in range #{expected.inspect}"
112
- when Array
113
- if value.is_a?(Array)
114
- arr = expected.map.with_index do |e, idx|
115
- if e.is_a?(Array)
116
- "- [#{idx}] index : {\n" + type_error_message(e, value[idx]) + "\n}"
117
- else
118
- "- [#{idx}] index : " + type_error_message(e, value[idx])
119
- end
111
+ def type_error_message(expected, value)
112
+ case expected
113
+ when Rtype::Behavior::Base
114
+ expected.error_message(value)
115
+ when Module
116
+ "Expected #{value.inspect} to be a #{expected}"
117
+ when Symbol
118
+ "Expected #{value.inspect} to respond to :#{expected}"
119
+ when Regexp
120
+ "Expected stringified #{value.inspect} to match regexp #{expected.inspect}"
121
+ when Range
122
+ "Expected #{value.inspect} to be included in range #{expected.inspect}"
123
+ when Array
124
+ if value.is_a?(Array)
125
+ arr = expected.map.with_index do |e, idx|
126
+ if e.is_a?(Array)
127
+ "- [#{idx}] index : {\n" + type_error_message(e, value[idx]) + "\n}"
128
+ else
129
+ "- [#{idx}] index : " + type_error_message(e, value[idx])
120
130
  end
121
- "Expected #{value.inspect} to be an array with #{expected.length} elements:\n" + arr.join("\n")
122
- else
123
- "Expected #{value.inspect} to be an array"
124
131
  end
125
- when Proc
126
- "Expected #{value.inspect} to return a truthy value for proc #{expected}"
127
- when true
128
- "Expected #{value.inspect} to be a truthy value"
129
- when false
130
- "Expected #{value.inspect} to be a falsy value"
131
- when nil # for return
132
- "Expected #{value.inspect} to be nil"
132
+ "Expected #{value.inspect} to be an array with #{expected.length} elements:\n" + arr.join("\n")
133
+ else
134
+ "Expected #{value.inspect} to be an array"
133
135
  end
136
+ when Proc
137
+ "Expected #{value.inspect} to return a truthy value for proc #{expected}"
138
+ when true
139
+ "Expected #{value.inspect} to be a truthy value"
140
+ when false
141
+ "Expected #{value.inspect} to be a falsy value"
142
+ when nil # for return
143
+ "Expected #{value.inspect} to be nil"
134
144
  end
145
+ end
135
146
 
136
- private
137
- def valid_type_sig_info_form?(hash)
138
- return false unless hash.is_a?(Hash)
139
- arg_sig = hash.first[0]
140
- arg_sig.is_a?(Array) || arg_sig.is_a?(Hash)
141
- end
147
+ private
148
+ def valid_type_sig_info_form?(hash)
149
+ return false unless hash.is_a?(Hash)
150
+ arg_sig = hash.first[0]
151
+ arg_sig.is_a?(Array) || arg_sig.is_a?(Hash)
152
+ end
142
153
 
143
- def define_typed_method_to_proxy(owner, method_name, expected_args, expected_kwargs, return_sig)
144
- # `send` is faster than `method(...).call`
145
- owner.send(:_rtype_proxy).send :define_method, method_name do |*args, **kwargs, &block|
146
- if kwargs.empty?
147
- ::Rtype.assert_arguments_type(expected_args, args)
148
- result = super(*args, &block)
149
- else
150
- ::Rtype.assert_arguments_type_with_keywords(expected_args, args, expected_kwargs, kwargs)
151
- result = super(*args, **kwargs, &block)
152
- end
153
- ::Rtype.assert_return_type(return_sig, result)
154
- result
154
+ def define_typed_method_to_proxy(owner, method_name, expected_args, expected_kwargs, return_sig)
155
+ # `send` is faster than `method(...).call`
156
+ owner.send(:_rtype_proxy).send :define_method, method_name do |*args, **kwargs, &block|
157
+ if kwargs.empty?
158
+ ::Rtype.assert_arguments_type(expected_args, args)
159
+ result = super(*args, &block)
160
+ else
161
+ ::Rtype.assert_arguments_type_with_keywords(expected_args, args, expected_kwargs, kwargs)
162
+ result = super(*args, **kwargs, &block)
155
163
  end
156
- nil
164
+ ::Rtype.assert_return_type(return_sig, result)
165
+ result
157
166
  end
167
+ nil
158
168
  end
159
-
160
- unless self.respond_to?(:valid?)
169
+
170
+ public
171
+ unless respond_to?(:valid?)
161
172
  # validate argument type
162
- def self.valid?(expected, value)
173
+ def valid?(expected, value)
163
174
  case expected
164
175
  when Module
165
176
  value.is_a? expected
@@ -188,8 +199,8 @@ module Rtype
188
199
  end
189
200
  end
190
201
 
191
- unless self.respond_to?(:assert_arguments_type)
192
- def self.assert_arguments_type(expected_args, args)
202
+ unless respond_to?(:assert_arguments_type)
203
+ def assert_arguments_type(expected_args, args)
193
204
  # `length.times` is faster than `each_with_index`
194
205
  args.length.times do |i|
195
206
  expected = expected_args[i]
@@ -203,8 +214,8 @@ module Rtype
203
214
  end
204
215
  end
205
216
 
206
- unless self.respond_to?(:assert_arguments_type_with_keywords)
207
- def self.assert_arguments_type_with_keywords(expected_args, args, expected_kwargs, kwargs)
217
+ unless respond_to?(:assert_arguments_type_with_keywords)
218
+ def assert_arguments_type_with_keywords(expected_args, args, expected_kwargs, kwargs)
208
219
  # `length.times` is faster than `each_with_index`
209
220
  args.length.times do |i|
210
221
  expected = expected_args[i]
@@ -226,8 +237,8 @@ module Rtype
226
237
  end
227
238
  end
228
239
 
229
- unless self.respond_to?(:assert_return_type)
230
- def self.assert_return_type(expected, result)
240
+ unless respond_to?(:assert_return_type)
241
+ def assert_return_type(expected, result)
231
242
  if expected.nil?
232
243
  unless result.nil?
233
244
  raise ReturnTypeError, "for return:\n" + type_error_message(expected, result)
data/spec/rtype_spec.rb CHANGED
@@ -236,29 +236,35 @@ describe Rtype do
236
236
  describe 'true' do
237
237
  it "is right" do
238
238
  klass.send :rtype, :return_arg, [true] => Any
239
+ instance.return_arg(true)
239
240
  instance.return_arg(123)
240
241
  end
241
242
  it "is wrong args" do
242
243
  klass.send :rtype, :return_arg, [true] => Any
244
+ expect {instance.return_arg(false)}.to raise_error Rtype::ArgumentTypeError
243
245
  expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
244
246
  end
245
247
  it "is wrong result" do
246
- klass.send :rtype, :return_nil, [Any] => true
247
- expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
248
+ klass.send :rtype, :return_arg, [Any] => true
249
+ expect {instance.return_arg(false)}.to raise_error Rtype::ReturnTypeError
250
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ReturnTypeError
248
251
  end
249
252
  end
250
253
 
251
254
  describe 'false' do
252
255
  it "is right" do
253
256
  klass.send :rtype, :return_arg, [false] => Any
257
+ instance.return_arg(false)
254
258
  instance.return_arg(nil)
255
259
  end
256
260
  it "is wrong args" do
257
261
  klass.send :rtype, :return_arg, [false] => Any
262
+ expect {instance.return_arg(true)}.to raise_error Rtype::ArgumentTypeError
258
263
  expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
259
264
  end
260
265
  it "is wrong result" do
261
266
  klass.send :rtype, :return_arg, [Any] => false
267
+ expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
262
268
  expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
263
269
  end
264
270
  end
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.2.0
4
+ version: 0.3.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-03-26 00:00:00.000000000 Z
11
+ date: 2016-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake