eapi 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/Gemfile +1 -0
- data/README.md +495 -2
- data/eapi.gemspec +0 -1
- data/lib/eapi.rb +10 -2
- data/lib/eapi/children.rb +30 -0
- data/lib/eapi/common.rb +8 -15
- data/lib/eapi/definition_runner.rb +109 -0
- data/lib/eapi/methods/names.rb +0 -4
- data/lib/eapi/methods/properties.rb +1 -109
- data/lib/eapi/methods/types.rb +52 -5
- data/lib/eapi/type_checker.rb +16 -0
- data/lib/eapi/value_converter.rb +40 -0
- data/lib/eapi/version.rb +1 -1
- data/spec/basic_spec.rb +58 -0
- data/spec/definition_spec.rb +26 -0
- data/spec/function_spec.rb +71 -0
- data/spec/list_spec.rb +124 -0
- data/spec/spec_helper.rb +2 -2
- data/spec/to_h_spec.rb +87 -0
- data/spec/type_spec.rb +86 -0
- data/spec/{eapi_validations_spec.rb → validations_spec.rb} +59 -21
- metadata +20 -25
- data/.coveralls.yml +0 -1
- data/spec/eapi_basic_spec.rb +0 -39
- data/spec/eapi_list_spec.rb +0 -92
- data/spec/eapi_to_h_spec.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4eaa6b7386dfe974f725d80fa008f3d8dbe5ee46
|
4
|
+
data.tar.gz: a9b8fb3d839460128e7595c11db9754b18ac0347
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6cd68cc945520b4e4eaf62a8f60be1f53e06bd21226befb7817cfcefeb01168d04dd75cb7491eae835cd2aa1b24cf3321d838fa56bae973f709b05b191c5db2
|
7
|
+
data.tar.gz: d5688563cada1584200aa2ca6febca6303fba83115484a3dfe80e103dda2282fdb5a7dc3871aa9858415a9eb8f478669ffd255ed674bbb6b63a9a5d00fc67d06
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
ruby gem for building complex structures that will end up in hashes (initially devised for ElasticSearch search requests)
|
4
4
|
|
5
|
-
[![
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/eapi.svg)](http://badge.fury.io/rb/eapi)
|
6
6
|
[![Build Status](https://travis-ci.org/eturino/eapi.svg?branch=master)](https://travis-ci.org/eturino/eapi)
|
7
|
+
[![Code Climate](https://codeclimate.com/github/eturino/eapi.png)](https://codeclimate.com/github/eturino/eapi)
|
8
|
+
[![Code Climate Coverage](https://codeclimate.com/github/eturino/eapi/coverage.png)](https://codeclimate.com/github/eturino/eapi)
|
7
9
|
|
8
10
|
## Installation
|
9
11
|
|
@@ -19,9 +21,500 @@ Or install it yourself as:
|
|
19
21
|
|
20
22
|
$ gem install eapi
|
21
23
|
|
24
|
+
## Dependencies
|
25
|
+
|
26
|
+
### Ruby version
|
27
|
+
|
28
|
+
Works with ruby 2. Tested with MRI 2.1.1 and 2.0.0
|
29
|
+
|
30
|
+
### Gem dependencies
|
31
|
+
|
32
|
+
This gem uses ActiveSupport (version 4) and also the ActiveModel Validations (version 4)
|
33
|
+
|
34
|
+
Extracted from the gemspec:
|
35
|
+
```
|
36
|
+
spec.add_dependency 'activesupport', '~> 4'
|
37
|
+
spec.add_dependency 'activemodel', '~> 4'
|
38
|
+
```
|
39
|
+
|
22
40
|
## Usage
|
23
41
|
|
24
|
-
|
42
|
+
### including EAPI into your class
|
43
|
+
|
44
|
+
Just include the module `Eapi::Common` into your class.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
class MyTestKlass
|
48
|
+
include Eapi::Common
|
49
|
+
|
50
|
+
property :something
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
### Initialize
|
55
|
+
|
56
|
+
`Eapi::Common` will add a `initialize` method to your class that will accept a hash. It will recognise the defined properties in that hash and will set them.
|
57
|
+
|
58
|
+
For now any unrecognised property in the hash will be ignored. This may change in the future.
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
class MyTestKlass
|
62
|
+
include Eapi::Common
|
63
|
+
|
64
|
+
property :something
|
65
|
+
end
|
66
|
+
|
67
|
+
x = MyTestKlass.new something: 1
|
68
|
+
x.something # => 1
|
69
|
+
```
|
70
|
+
|
71
|
+
### Object creation shortcut: calling methods in Eapi
|
72
|
+
|
73
|
+
Calling a method with the desired class name in `Eapi` module will do the same as `DesiredClass.new(...)`. The name can be the same as the class, or an underscorised version, or a simple underscored one.
|
74
|
+
|
75
|
+
The goal is to use `Eapi.esr_search(name: 'Paco')` as a shortcut to `Esr::Search.new(name: 'Paco')`. We can also use `Eapi.Esr_Search(...)` and other combinations.
|
76
|
+
|
77
|
+
To show this feature and all the combinations for method names, we'll use the 2 example classes that are used in the actual test rspec.
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
class MyTestKlassOutside
|
81
|
+
include Eapi::Common
|
82
|
+
|
83
|
+
property :something
|
84
|
+
end
|
85
|
+
|
86
|
+
module Somewhere
|
87
|
+
class TestKlassInModule
|
88
|
+
include Eapi::Common
|
89
|
+
|
90
|
+
property :something
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
As shown by rspec run:
|
96
|
+
|
97
|
+
```
|
98
|
+
initialise using method calls to Eapi
|
99
|
+
Eapi.MyTestKlassOutside(...)
|
100
|
+
calls MyTestKlassOutside.new
|
101
|
+
Eapi.my_test_klass_outside(...)
|
102
|
+
calls MyTestKlassOutside.new
|
103
|
+
Eapi.Somewhere__TestKlassInModule(...)
|
104
|
+
calls Somewhere::TestKlassInModule.new
|
105
|
+
Eapi.somewhere__test_klass_in_module(...)
|
106
|
+
calls Somewhere::TestKlassInModule.new
|
107
|
+
Eapi.Somewhere_TestKlassInModule(...)
|
108
|
+
calls Somewhere::TestKlassInModule.new
|
109
|
+
Eapi.somewhere_test_klass_in_module(...)
|
110
|
+
calls Somewhere::TestKlassInModule.new
|
111
|
+
```
|
112
|
+
|
113
|
+
### Defining properties
|
114
|
+
|
115
|
+
We define properties in our class with the instruction `property` as shown:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
class MyTestKlass
|
119
|
+
include Eapi::Common
|
120
|
+
|
121
|
+
property :one
|
122
|
+
property :two
|
123
|
+
end
|
124
|
+
```
|
125
|
+
#### Setting proeprties on object creation
|
126
|
+
We can then assign the properties on object creation:
|
127
|
+
```ruby
|
128
|
+
x = MyTestKlass.new one: 1, two: 2
|
129
|
+
```
|
130
|
+
#### Getters
|
131
|
+
|
132
|
+
A getter method will be created for each property
|
133
|
+
```ruby
|
134
|
+
x = MyTestKlass.new one: 1, two: 2
|
135
|
+
x.one # => 1
|
136
|
+
x.two # => 2
|
137
|
+
```
|
138
|
+
|
139
|
+
#### Setters
|
140
|
+
|
141
|
+
Also, a setter will be created for each property
|
142
|
+
```ruby
|
143
|
+
x = MyTestKlass.new one: 1, two: 2
|
144
|
+
x.one = :other
|
145
|
+
x.one # => :other
|
146
|
+
```
|
147
|
+
|
148
|
+
#### Fluent setters (for method chaining)
|
149
|
+
Besides the normal setter, a fluent setter (`set_my_prop`) will be created for each property. `self` is returned on this setters, enabling Method Chaining.
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
x = MyTestKlass.new one: 1, two: 2
|
153
|
+
res = x.set_one(:other)
|
154
|
+
x.one # => :other
|
155
|
+
res.equal? x # => true
|
156
|
+
|
157
|
+
x.set_one(:hey).set_two(:you)
|
158
|
+
x.one # => :hey
|
159
|
+
x.two # => :you
|
160
|
+
```
|
161
|
+
|
162
|
+
#### Getter method as fluent setter
|
163
|
+
|
164
|
+
The getter method also works as fluent setter. If we pass an argument to it, it will call the fluent setter
|
165
|
+
```ruby
|
166
|
+
x = MyTestKlass.new
|
167
|
+
res = x.one :fluent
|
168
|
+
x.one # => :fluent
|
169
|
+
res.equal? x # => true
|
170
|
+
```
|
171
|
+
|
172
|
+
### Convert to hashes: `to_h` and `create_hash`
|
173
|
+
|
174
|
+
All Eapi classes respond to `to_h` and return a hash, as it is the main purpose of this gem. It will execute any validation (see property definition), and if everything is ok, it will convert it to a simple hash structure.
|
175
|
+
|
176
|
+
#### Methods involved
|
177
|
+
|
178
|
+
Inside, `to_h` will call `valid?`, raise an error of type `Eapi::Errors::InvalidElementError` if something is not right, and if everything is ok it will call `create_hash`.
|
179
|
+
|
180
|
+
The `create_hash` method will create a hash with the properties as keys. Each value will be "converted".
|
181
|
+
|
182
|
+
#### Values conversion
|
183
|
+
|
184
|
+
By default, each property will be converted into a simple element (Array, Hash, or simple value).
|
185
|
+
|
186
|
+
If a value is an Array or a Set, `to_a` will be invoked and all values will be "converted" in the same way.
|
187
|
+
|
188
|
+
If a value respond to `to_h`, it will be called. That way, if the value of a property (or an element of an Array) is an Eapi object, it will be validated and converted into a simple hash structure.
|
189
|
+
|
190
|
+
important: *any nil value will be omitted* in the final hash.
|
191
|
+
|
192
|
+
#### Example
|
193
|
+
|
194
|
+
To demonstrate this behaviour we'll have an Eapi enabled class `ExampleEapi` and another `ComplexValue` class that responds to `to_h`. We'll set into the `ExampleEapi` object complex properties to demonstrate the conversion into a simple structure.
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
class ComplexValue
|
198
|
+
def to_h
|
199
|
+
{
|
200
|
+
a: Set.new(['hello', 'world', MyTestObject.new])
|
201
|
+
}
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class ExampleEapi
|
206
|
+
include Eapi::Common
|
207
|
+
|
208
|
+
property :something, required: true
|
209
|
+
property :other
|
210
|
+
end
|
211
|
+
|
212
|
+
# TESTING `to_h`
|
213
|
+
|
214
|
+
list = Set.new [
|
215
|
+
OpenStruct.new(a: 1, 'b' => 2),
|
216
|
+
{c: 3, 'd' => 4},
|
217
|
+
nil
|
218
|
+
]
|
219
|
+
|
220
|
+
eapi = ExampleEapi.new something: list, other: ComplexValue.new
|
221
|
+
eapi.to_h # =>
|
222
|
+
# {
|
223
|
+
# something: [
|
224
|
+
# {a: 1, b: 2},
|
225
|
+
# {c: 3, d: 4},
|
226
|
+
# ],
|
227
|
+
#
|
228
|
+
# other: {
|
229
|
+
# a: [
|
230
|
+
# 'hello',
|
231
|
+
# 'world',
|
232
|
+
# {a: 'hello'}
|
233
|
+
# ]
|
234
|
+
# }
|
235
|
+
# }
|
236
|
+
```
|
237
|
+
|
238
|
+
### Property definition
|
239
|
+
|
240
|
+
When defining the property, we can specify some options to specify what values are expected in that property. This serves for validation and automatic initialisation.
|
241
|
+
|
242
|
+
It uses `ActiveModel::Validations`. When `to_h` is called in an Eapi object, the `valid?` method will be called and if the object is not valid an `Eapi::Errors::InvalidElementError` error will raise.
|
243
|
+
|
244
|
+
#### Mark a property as Required with `required` option
|
245
|
+
|
246
|
+
A required property will fail if the value is not present. It will use `ActiveModel::Validations` inside and will effectively do a `validates_presence_of :property_name`.
|
247
|
+
|
248
|
+
example:
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
class TestKlass
|
252
|
+
include Eapi::Common
|
253
|
+
|
254
|
+
property :something, required: true
|
255
|
+
end
|
256
|
+
|
257
|
+
eapi = TestKlass.new
|
258
|
+
eapi.valid? # => false
|
259
|
+
eapi.errors.full_messages # => ["Something can't be blank"]
|
260
|
+
eapi.errors.messages # => {something: ["can't be blank"]}
|
261
|
+
```
|
262
|
+
|
263
|
+
#### Specify the property's Type with `type` option
|
264
|
+
|
265
|
+
If a property is defined to be of a specific type, the value will be validated to meet that criteria. It means that the value must be of the specified type. It will use `value.kind_of?(type)` and if that fails it will use `value.is?(type)` if defined.
|
266
|
+
|
267
|
+
example:
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
class TestKlass
|
271
|
+
include Eapi::Common
|
272
|
+
|
273
|
+
property :something, type: Hash
|
274
|
+
end
|
275
|
+
|
276
|
+
eapi = TestKlass.new something: 1
|
277
|
+
eapi.valid? # => false
|
278
|
+
eapi.errors.full_messages # => ["Something must be a Hash"]
|
279
|
+
eapi.errors.messages # => {something: ["must be a Hash"]}
|
280
|
+
```
|
281
|
+
|
282
|
+
Also, if a type is specified, then a `init_property_name` method is created that will set a new object of the given type in the property.
|
283
|
+
|
284
|
+
```ruby
|
285
|
+
class TestKlass
|
286
|
+
include Eapi::Common
|
287
|
+
|
288
|
+
property :something, type: Hash
|
289
|
+
end
|
290
|
+
|
291
|
+
eapi = TestKlass.new
|
292
|
+
eapi.something # => nil
|
293
|
+
eapi.init_something
|
294
|
+
eapi.something # => {}
|
295
|
+
```
|
296
|
+
|
297
|
+
To trigger the error, the value must not be an instance of the given Type, and also must not respond `true` to `value.is?(type)`
|
298
|
+
|
299
|
+
#### Custom validation with `validate_with` option
|
300
|
+
|
301
|
+
A more specific validation can be used using `validate_with`, that works the same way as `ActiveModel::Validations`.
|
302
|
+
|
303
|
+
example:
|
304
|
+
|
305
|
+
```ruby
|
306
|
+
class TestKlass
|
307
|
+
include Eapi::Common
|
308
|
+
|
309
|
+
property :something, validate_with: ->(record, attr, value) do
|
310
|
+
record.errors.add(attr, "must pass my custom validation") unless value == :valid_val
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
eapi = TestKlass.new something: 1
|
315
|
+
eapi.valid? # => false
|
316
|
+
eapi.errors.full_messages # => ["Something must pass my custom validation"]
|
317
|
+
eapi.errors.messages # => {something: ["must pass my custom validation"]}
|
318
|
+
```
|
319
|
+
|
320
|
+
#### Validations from `ActiveModel::Validations`
|
321
|
+
|
322
|
+
All other ActiveModel::Validations can be used:
|
323
|
+
|
324
|
+
```ruby
|
325
|
+
class TestKlass
|
326
|
+
include Eapi::Common
|
327
|
+
|
328
|
+
property :something
|
329
|
+
validates :something, numericality: true
|
330
|
+
end
|
331
|
+
|
332
|
+
eapi = TestKlass.new something: 'something'
|
333
|
+
eapi.valid? # => false
|
334
|
+
eapi.errors.full_messages # => ["Something is not a number"]
|
335
|
+
eapi.errors.messages # => {something: ["must is not a number"]}
|
336
|
+
```
|
337
|
+
|
338
|
+
#### Unrecognised property definition options
|
339
|
+
|
340
|
+
If the definition contained any unrecognised options, it will still be stored. No error is reported yet, but this behaviour may change in the future.
|
341
|
+
|
342
|
+
#### See property definition with `.definition_for` class method
|
343
|
+
|
344
|
+
You can see (but not edit) the definition of a property calling the `definition_for` class method. It will also contain the unrecognised options.
|
345
|
+
|
346
|
+
```ruby
|
347
|
+
class TestKlass
|
348
|
+
include Eapi::Common
|
349
|
+
|
350
|
+
property :something, type: Hash, unrecognised_option: 1
|
351
|
+
end
|
352
|
+
|
353
|
+
definition = TestKlass.definition_for :something # => { type: Hash, unrecognised_option: 1 }
|
354
|
+
|
355
|
+
# attempt to change the definition...
|
356
|
+
definition[:type] = Array
|
357
|
+
|
358
|
+
# ...has no effect
|
359
|
+
TestKlass.definition_for :something # => { type: Hash, unrecognised_option: 1 }
|
360
|
+
```
|
361
|
+
|
362
|
+
### List properties
|
363
|
+
|
364
|
+
a property can be defined as a multiple property. This will affect the methods defined in the class (it will create a fluent 'adder' method `add_property_name`), and also the automatic initialisation.
|
365
|
+
|
366
|
+
#### Define property as multiple with `multiple` option
|
367
|
+
|
368
|
+
A property marked as `multiple` will be initialised with an empty array. If no type is specified then it will use Array as a type, only for purposes of the `init_property_name` method.
|
369
|
+
|
370
|
+
```ruby
|
371
|
+
class TestKlass
|
372
|
+
include Eapi::Common
|
373
|
+
|
374
|
+
property :something, multiple: true
|
375
|
+
end
|
376
|
+
```
|
377
|
+
|
378
|
+
#### Adder method `add_property_name`
|
379
|
+
|
380
|
+
For a property marked as multiple, an extra fluent method called `add_property_name` will be created. This work very similar to the fluent setter `set_property_name` but inside it will append the value (using the shovel method `<<`) instead of setting it.
|
381
|
+
|
382
|
+
If the property is `nil` when `add_property_name` is called, then it will call `init_property_name` before.
|
383
|
+
|
384
|
+
```ruby
|
385
|
+
class TestKlass
|
386
|
+
include Eapi::Common
|
387
|
+
|
388
|
+
property :something, multiple: true
|
389
|
+
end
|
390
|
+
|
391
|
+
x = TestKlass.new
|
392
|
+
x.add_something(1).add_something(2)
|
393
|
+
x.something # => [1, 2]
|
394
|
+
```
|
395
|
+
|
396
|
+
#### Implicit `multiple` depending on Type
|
397
|
+
|
398
|
+
Even without `multiple` option specified, if the `type` option is:
|
399
|
+
* `Array`
|
400
|
+
* `Set`
|
401
|
+
* a class that responds to `is_multiple?` with true
|
402
|
+
|
403
|
+
then the property is marked as multiple.
|
404
|
+
|
405
|
+
example: (all `TestKlass` properties are marked as multiple)
|
406
|
+
```ruby
|
407
|
+
class MyCustomList
|
408
|
+
def self.is_multiple?
|
409
|
+
true
|
410
|
+
end
|
411
|
+
|
412
|
+
def <<(val)
|
413
|
+
@list |= []
|
414
|
+
@list << val
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
class TestKlass
|
419
|
+
include Eapi::Common
|
420
|
+
|
421
|
+
property :p1, multiple: true
|
422
|
+
property :p2, type: Array
|
423
|
+
property :p3, type: Set
|
424
|
+
property :p4, type: MyCustomList
|
425
|
+
end
|
426
|
+
|
427
|
+
x = TestKlass.new
|
428
|
+
x.add_p1(1).add_p2(2).add_p3(3).add_p4(4)
|
429
|
+
```
|
430
|
+
|
431
|
+
#### Element validation
|
432
|
+
|
433
|
+
Same as property validation, but for specific the elements in the list.
|
434
|
+
|
435
|
+
We can use `element_type` option in the definition, and it will check the type of each element in the list, same as `type` option does with the type of the property's value.
|
436
|
+
|
437
|
+
We can also specify `validate_element_with` option, and it will act the same as `validate_with` but for each element in the list.
|
438
|
+
|
439
|
+
```ruby
|
440
|
+
class TestKlass
|
441
|
+
include Eapi::Common
|
442
|
+
|
443
|
+
property :something, multiple: true, element_type: Hash
|
444
|
+
property :other, multiple: true, validate_element_with: ->(record, attr, value) do
|
445
|
+
record.errors.add(attr, "element must pass my custom validation") unless value == :valid_val
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
eapi = TestKlass.new
|
450
|
+
eapi.add_something 1
|
451
|
+
|
452
|
+
eapi.valid? # => false
|
453
|
+
eapi.errors.full_messages # => ["Something element must be a Hash"]
|
454
|
+
eapi.errors.messages # => {something: ["must element be a Hash"]}
|
455
|
+
|
456
|
+
eapi.something [{a: :b}]
|
457
|
+
eapi.valid? # => true
|
458
|
+
|
459
|
+
eapi.add_other 1
|
460
|
+
eapi.valid? # => false
|
461
|
+
eapi.errors.full_messages # => ["Other element must pass my custom validation"]
|
462
|
+
eapi.errors.messages # => {other: ["element must pass my custom validation"]}
|
463
|
+
|
464
|
+
eapi.other [:valid_val]
|
465
|
+
eapi.valid? # => true
|
466
|
+
```
|
467
|
+
|
468
|
+
### Pose as other types
|
469
|
+
|
470
|
+
An Eapi class can poses as other types, for purposes of `type` checking in a property definition. We use the class method `is` for this.
|
471
|
+
|
472
|
+
the `is?` method is also available as an instance method.
|
473
|
+
|
474
|
+
Eapi also creates specific instance and class methods like `is_a_some_type?` or `is_an_another_type?`.
|
475
|
+
|
476
|
+
example:
|
477
|
+
|
478
|
+
```ruby
|
479
|
+
class SuperTestKlass
|
480
|
+
include Eapi::Common
|
481
|
+
end
|
482
|
+
|
483
|
+
class TestKlass < SuperTestKlass
|
484
|
+
is :one_thing, :other_thing, OtherType
|
485
|
+
end
|
486
|
+
|
487
|
+
TestKlass.is? TestKlass # => true
|
488
|
+
TestKlass.is? 'TestKlass' # => true
|
489
|
+
TestKlass.is? :TestKlass # => true
|
490
|
+
|
491
|
+
TestKlass.is? SuperTestKlass # => true
|
492
|
+
TestKlass.is? 'SuperTestKlass' # => true
|
493
|
+
TestKlass.is? :SuperTestKlass # => true
|
494
|
+
|
495
|
+
TestKlass.is? :one_thing # => true
|
496
|
+
TestKlass.is? :other_thing # => true
|
497
|
+
TestKlass.is? :other_thing # => true
|
498
|
+
TestKlass.is? OtherType # => true
|
499
|
+
TestKlass.is? :OtherType # => true
|
500
|
+
|
501
|
+
TestKlass.is? SomethingElse # => false
|
502
|
+
TestKlass.is? :SomethingElse # => false
|
503
|
+
|
504
|
+
# also works on instance
|
505
|
+
obj = TestKlass.new
|
506
|
+
obj.is? TestKlass # => true
|
507
|
+
obj.is? :one_thing # => true
|
508
|
+
|
509
|
+
# specific type test methods
|
510
|
+
TestKlass.is_a_test_klass? # => true
|
511
|
+
TestKlass.is_an_one_thing? # => true
|
512
|
+
TestKlass.is_a_super_duper_thing? # => false
|
513
|
+
|
514
|
+
obj.is_a_test_klass? # => true
|
515
|
+
obj.is_an_one_thing? # => true
|
516
|
+
obj.is_a_super_duper_thing? # => false
|
517
|
+
```
|
25
518
|
|
26
519
|
## Contributing
|
27
520
|
|