sinclair 1.12.0 → 1.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -1
- data/README.md +41 -3
- data/config/check_specs.yml +1 -1
- data/config/yardstick.yml +2 -0
- data/lib/sinclair/core_ext/object.rb +26 -0
- data/lib/sinclair/method_definition/parameter_helper.rb +22 -3
- data/lib/sinclair/method_definition/stringifier.rb +30 -0
- data/lib/sinclair/method_definition.rb +1 -0
- data/lib/sinclair/model/builder.rb +141 -0
- data/lib/sinclair/model.rb +58 -0
- data/lib/sinclair/version.rb +1 -1
- data/lib/sinclair.rb +1 -0
- data/spec/integration/readme/sinclair/model_spec.rb +24 -0
- data/spec/integration/yard/sinclair/core_ext/object_spec.rb +16 -0
- data/spec/integration/yard/sinclair/model_spec.rb +20 -0
- data/spec/lib/sinclair/core_ext/object_spec.rb +37 -0
- data/spec/lib/sinclair/method_definition/parameter_helper_spec.rb +47 -0
- data/spec/lib/sinclair/method_definition/stringifier_spec.rb +69 -0
- data/spec/lib/sinclair/model_spec.rb +138 -0
- data/spec/support/models/car.rb +4 -0
- data/spec/support/models/human.rb +4 -0
- data/spec/support/models/job.rb +4 -0
- data/spec/support/models/tv.rb +4 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46b430c9db3658979d128e45ecbbb03aab30bb993d8651ecc8cc3bd9fe1b18e3
|
4
|
+
data.tar.gz: fa78aa3bde540b7f90675566086e65d884cea51b2874b6cd5166ffc50018ab73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a290bcea44d39854bd7b8bd99b28c18d0a6c827b31f140fb339b82d49a9add6e505f738b4925b27c25ddedd695d06963a4221c55ff9b869157aaec5753a5747
|
7
|
+
data.tar.gz: dfdc3723b6a6d31611eceb727007680aafc3f56d9cda1e16922768df7e9ce14238d0c982ff7e4232a914015c8d22850b869ab08601b8121727ce0673c43ca10b
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -13,13 +13,13 @@ This gem helps the creation of complex gems/concerns
|
|
13
13
|
that enables creation of methods on the fly through class
|
14
14
|
methods
|
15
15
|
|
16
|
-
Current Release: [1.
|
16
|
+
Current Release: [1.13.0](https://github.com/darthjee/sinclair/tree/1.13.0)
|
17
17
|
|
18
|
-
[Next release](https://github.com/darthjee/sinclair/compare/1.
|
18
|
+
[Next release](https://github.com/darthjee/sinclair/compare/1.13.0...master)
|
19
19
|
|
20
20
|
Yard Documentation
|
21
21
|
-------------------
|
22
|
-
[https://www.rubydoc.info/gems/sinclair/1.
|
22
|
+
[https://www.rubydoc.info/gems/sinclair/1.13.0](https://www.rubydoc.info/gems/sinclair/1.13.0)
|
23
23
|
|
24
24
|
Installation
|
25
25
|
---------------
|
@@ -616,6 +616,44 @@ model1 == model2 # returns true
|
|
616
616
|
```
|
617
617
|
</details>
|
618
618
|
|
619
|
+
### Sinclair::Model
|
620
|
+
Model class for quickly creation of plain simple classes/models
|
621
|
+
|
622
|
+
When creating a model class, options can be passed
|
623
|
+
- writter: Adds writter/setter methods (defaults to true)
|
624
|
+
- comparable: Adds the fields when running a `==` method (defaults to true)
|
625
|
+
|
626
|
+
<details>
|
627
|
+
<summary>Example of simple usage</summary>
|
628
|
+
|
629
|
+
```ruby
|
630
|
+
class Human < Sinclair::Model.for(:name, :age, { gender: :undefined }, **{})
|
631
|
+
end
|
632
|
+
|
633
|
+
human1 = Human.new(name: 'John Doe', age: 22)
|
634
|
+
human2 = Human.new(name: 'John Doe', age: 22)
|
635
|
+
|
636
|
+
human1.name # returns 'John Doe'
|
637
|
+
human1.age # returns 22
|
638
|
+
human1.gender # returns :undefined
|
639
|
+
human1 == human2 # returns true
|
640
|
+
```
|
641
|
+
</details>
|
642
|
+
|
643
|
+
<details>
|
644
|
+
<summary>Example with options</summary>
|
645
|
+
|
646
|
+
```ruby
|
647
|
+
class Tv < Sinclair::Model.for(:model, writter: false, comparable: false)
|
648
|
+
end
|
649
|
+
|
650
|
+
tv1 = Tv.new(model: 'Sans Sunga Xt')
|
651
|
+
tv2 = Tv.new(model: 'Sans Sunga Xt')
|
652
|
+
|
653
|
+
tv1 == tv2 # returns false
|
654
|
+
```
|
655
|
+
</details>
|
656
|
+
|
619
657
|
RSspec matcher
|
620
658
|
---------------
|
621
659
|
|
data/config/check_specs.yml
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
ignore:
|
2
|
+
- lib/sinclair/model/builder.rb
|
2
3
|
- lib/sinclair/comparable/class_methods.rb
|
3
4
|
- lib/sinclair/exception.rb
|
4
5
|
- lib/sinclair/matchers/add_method.rb
|
@@ -6,5 +7,4 @@ ignore:
|
|
6
7
|
- lib/sinclair/matchers/base.rb
|
7
8
|
- lib/sinclair/matchers/change_method_on.rb
|
8
9
|
- lib/sinclair/matchers/method_to.rb
|
9
|
-
- lib/sinclair/method_definition/parameter_helper.rb
|
10
10
|
- lib/sinclair/version.rb
|
data/config/yardstick.yml
CHANGED
@@ -29,6 +29,7 @@ rules:
|
|
29
29
|
- Sinclair::Matchers#add_class_method
|
30
30
|
- Sinclair::Matchers#change_method
|
31
31
|
- Sinclair::Matchers#change_class_method
|
32
|
+
- Sinclair::Model.for
|
32
33
|
ReturnTag:
|
33
34
|
enabled: true
|
34
35
|
exclude:
|
@@ -63,6 +64,7 @@ rules:
|
|
63
64
|
- Sinclair::MethodDefinition::ParameterBuilder#initialize
|
64
65
|
- Sinclair::MethodDefinition::ParameterHelper#initialize
|
65
66
|
- Sinclair::MethodDefinition::StringDefinition#initialize
|
67
|
+
- Sinclair::Model::Builder#initialize
|
66
68
|
- Sinclair::Options#initialize
|
67
69
|
- Sinclair::Options::Builder#initialize
|
68
70
|
Summary::Length:
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api public
|
4
|
+
# @author darthjee
|
5
|
+
#
|
6
|
+
# Extension to core class Object
|
7
|
+
class Object
|
8
|
+
# rubocop:disable Naming/PredicateName
|
9
|
+
|
10
|
+
# @api public
|
11
|
+
# Checks if an object is an instance of any of the given classes
|
12
|
+
#
|
13
|
+
# @param classes [Array<Class>] classes to be checked against object
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# object = [1, 2, 3]
|
17
|
+
#
|
18
|
+
# object.is_any?(Hash, Class) # returns false
|
19
|
+
# object.is_any?(Hash, Array) # returns true
|
20
|
+
#
|
21
|
+
# @return [TrueClass,FalseClass]
|
22
|
+
def is_any?(*classes)
|
23
|
+
classes.any?(method(:is_a?))
|
24
|
+
end
|
25
|
+
# rubocop:enable Naming/PredicateName
|
26
|
+
end
|
@@ -45,6 +45,7 @@ class Sinclair
|
|
45
45
|
|
46
46
|
private
|
47
47
|
|
48
|
+
delegate :value_string, to: Stringifier
|
48
49
|
attr_reader :parameters_list, :named
|
49
50
|
alias named? named
|
50
51
|
|
@@ -114,11 +115,29 @@ class Sinclair
|
|
114
115
|
#
|
115
116
|
# @return [Array<String>]
|
116
117
|
def defaults_strings
|
117
|
-
|
118
|
-
|
119
|
-
"#{key}#{joinner}#{value}"
|
118
|
+
defaults.map do |parameter, value|
|
119
|
+
default_string(parameter, value)
|
120
120
|
end
|
121
121
|
end
|
122
|
+
|
123
|
+
# Returns the string for one default parameter
|
124
|
+
#
|
125
|
+
# @param parameter [Symbol] name of the parameter
|
126
|
+
# @param value [Object] default value
|
127
|
+
#
|
128
|
+
# @return [String]
|
129
|
+
def default_string(parameter, value)
|
130
|
+
"#{parameter}#{joinner}#{value_string(value)}"
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns the string used when joining a parameter with it's default value
|
134
|
+
#
|
135
|
+
# @see #named?
|
136
|
+
#
|
137
|
+
# @return [String]
|
138
|
+
def joinner
|
139
|
+
@joinner ||= named? ? ': ' : ' = '
|
140
|
+
end
|
122
141
|
end
|
123
142
|
end
|
124
143
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sinclair/core_ext/object'
|
4
|
+
|
5
|
+
class Sinclair
|
6
|
+
class MethodDefinition
|
7
|
+
# @api private
|
8
|
+
# @author darthjee
|
9
|
+
#
|
10
|
+
# Stringgify a value for {StringDefinition}
|
11
|
+
class Stringifier
|
12
|
+
# Convert a value to a string format
|
13
|
+
#
|
14
|
+
# The returned string can be evaluated as code, returning the
|
15
|
+
# original value
|
16
|
+
#
|
17
|
+
# @param value [Object] object to be converted
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
def self.value_string(value)
|
21
|
+
return 'nil' if value.nil?
|
22
|
+
return ":#{value}" if value.is_a?(Symbol)
|
23
|
+
|
24
|
+
return value.to_s if value.is_any?(Class, Hash, Array)
|
25
|
+
|
26
|
+
value.to_json
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -14,6 +14,7 @@ class Sinclair
|
|
14
14
|
autoload :StringDefinition, 'sinclair/method_definition/string_definition'
|
15
15
|
autoload :ParameterBuilder, 'sinclair/method_definition/parameter_builder'
|
16
16
|
autoload :ParameterHelper, 'sinclair/method_definition/parameter_helper'
|
17
|
+
autoload :Stringifier, 'sinclair/method_definition/stringifier'
|
17
18
|
|
18
19
|
# @method name
|
19
20
|
#
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
class Model
|
5
|
+
# @api private
|
6
|
+
# @author Darthjee
|
7
|
+
#
|
8
|
+
# Builder responsible for building methods to a new {Sinclair::Model} class
|
9
|
+
#
|
10
|
+
# The building adds readers/setters and an initializer with named parameters
|
11
|
+
class Builder < Sinclair
|
12
|
+
# @overload initialize(klass, *attributes, writter: true, comparable: true)
|
13
|
+
# @param klass [Class<Sinclair::Model>] the new class to receive the methods
|
14
|
+
# @param attributes [Array<Symbol>] attributes to be added in both the
|
15
|
+
# initialization and adding the methos to the model
|
16
|
+
# @param writter [TrueClass,FalseClass] flag informing if the writter/setter
|
17
|
+
# method should be added
|
18
|
+
# @param comparable [TrueClass,FalseClass] flag to make the class {Comparable}
|
19
|
+
# by the fields
|
20
|
+
# @overload initialize(klass, *attributes, defaults, writter: true, comparable: true)
|
21
|
+
# @param klass [Class<Sinclair::Model>] the new class to receive the methods
|
22
|
+
# @param attributes [Array<Symbol>] attributes to be added in both the
|
23
|
+
# initialization and adding the methos to the model
|
24
|
+
# @param defaults [Hash] attributes to be added with a default value in the initializer
|
25
|
+
# @param writter [TrueClass,FalseClass] flag informing if the writter/setter
|
26
|
+
# method should be added
|
27
|
+
# @param comparable [TrueClass,FalseClass] flag to make the class {Comparable}
|
28
|
+
# by the fields
|
29
|
+
def initialize(klass, *attributes, writter: true, comparable: true)
|
30
|
+
super(klass)
|
31
|
+
@attributes = attributes.flatten
|
32
|
+
@writter = writter
|
33
|
+
@comparable = comparable
|
34
|
+
|
35
|
+
add_methods
|
36
|
+
change_equals
|
37
|
+
change_initializer
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_reader :attributes, :writter, :comparable
|
43
|
+
alias writter? writter
|
44
|
+
alias comparable? comparable
|
45
|
+
|
46
|
+
# @!method attributes
|
47
|
+
# @api private
|
48
|
+
# @private
|
49
|
+
#
|
50
|
+
# Attributes to be added in the class
|
51
|
+
#
|
52
|
+
# Attributes without default values are symbols
|
53
|
+
# while attributes with defaults values are defined in a Hash
|
54
|
+
#
|
55
|
+
# @return [Array<Symbol,Hash>]
|
56
|
+
|
57
|
+
# @!method writter
|
58
|
+
# @api private
|
59
|
+
# @private
|
60
|
+
#
|
61
|
+
# Flag if writter methods (setter) should be added or not
|
62
|
+
#
|
63
|
+
# @return [TrueClass,FalseClass]
|
64
|
+
|
65
|
+
# @!method comparable
|
66
|
+
# @api private
|
67
|
+
# @private
|
68
|
+
#
|
69
|
+
# flag to make the class {Comparable} by the fields
|
70
|
+
#
|
71
|
+
# @return [TrueClass,FalseClass]
|
72
|
+
|
73
|
+
# @!method writter?
|
74
|
+
# @api private
|
75
|
+
# @private
|
76
|
+
#
|
77
|
+
# Flag if writter methods (setter) should be added or not
|
78
|
+
#
|
79
|
+
# @return [TrueClass,FalseClass]
|
80
|
+
|
81
|
+
# @!method comparable?
|
82
|
+
# @api private
|
83
|
+
# @private
|
84
|
+
#
|
85
|
+
# flag to make the class {Comparable} by the fields
|
86
|
+
#
|
87
|
+
# @return [TrueClass,FalseClass]
|
88
|
+
|
89
|
+
# @private
|
90
|
+
# Adds readers and setters
|
91
|
+
#
|
92
|
+
# Readers are always added, while setters depends on the flag {#writter?}
|
93
|
+
#
|
94
|
+
# @return [Array<MethodDefinition>]
|
95
|
+
def add_methods
|
96
|
+
call = writter? ? :attr_accessor : :attr_reader
|
97
|
+
|
98
|
+
add_method(call, *attributes_names, type: :call)
|
99
|
+
end
|
100
|
+
|
101
|
+
# @private
|
102
|
+
# Change the method +==+
|
103
|
+
#
|
104
|
+
# The change happens using {Sinclair::Comparable}
|
105
|
+
# and adding all the fields to be included in the comparisom
|
106
|
+
#
|
107
|
+
# @return [Array<MethodDefinition>]
|
108
|
+
def change_equals
|
109
|
+
return unless comparable?
|
110
|
+
|
111
|
+
add_method(:include, Comparable, type: :call)
|
112
|
+
add_method(:comparable_by, *attributes_names, type: :call)
|
113
|
+
end
|
114
|
+
|
115
|
+
# @private
|
116
|
+
#
|
117
|
+
# Changes the initializer to accept the parameters
|
118
|
+
#
|
119
|
+
# @return [Array<MethodDefinition>]
|
120
|
+
def change_initializer
|
121
|
+
code = attributes_names.map do |attr|
|
122
|
+
"@#{attr} = #{attr}"
|
123
|
+
end.join("\n")
|
124
|
+
|
125
|
+
add_method(:initialize, code, named_parameters: attributes)
|
126
|
+
end
|
127
|
+
|
128
|
+
# @private
|
129
|
+
# Returns the list of attributes
|
130
|
+
#
|
131
|
+
# This is used when defining the readers / setters
|
132
|
+
#
|
133
|
+
# @return [Array<Symbol>]
|
134
|
+
def attributes_names
|
135
|
+
@attributes_names ||= attributes.map do |attr|
|
136
|
+
attr.try(:keys) || attr.to_s
|
137
|
+
end.flatten
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
# @api public
|
5
|
+
# @author Darthjee
|
6
|
+
#
|
7
|
+
# Basic model to be used when defining new classes quickly
|
8
|
+
class Model
|
9
|
+
autoload :Builder, 'sinclair/model/builder'
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Returns a new class that inherits from model
|
13
|
+
#
|
14
|
+
# @overload for(*attributes, writter: true, comparable: true)
|
15
|
+
# @param attributes [Array<Symbol>] attributes to be added in both the
|
16
|
+
# initialization and adding the methos to the model
|
17
|
+
# @param writter [TrueClass,FalseClass] flag informing if the writter/setter
|
18
|
+
# method should be added
|
19
|
+
# @param comparable [TrueClass,FalseClass] flag to make the class {Comparable}
|
20
|
+
# by the fields
|
21
|
+
#
|
22
|
+
# @example A model with readers
|
23
|
+
# class Car < Sinclair::Model.for(:brand, :model, writter: false)
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# car = Car.new(brand: :ford, model: :T)
|
27
|
+
#
|
28
|
+
# car.brand # returns :ford
|
29
|
+
# car.model # returns :T
|
30
|
+
#
|
31
|
+
# @overload for(*attributes, defaults, writter: true, comparable: true)
|
32
|
+
# @param attributes [Array<Symbol>] attributes to be added in both the
|
33
|
+
# initialization and adding the methos to the model
|
34
|
+
# @param defaults [Hash] attributes to be added with a default value in the initializer
|
35
|
+
# @param writter [TrueClass,FalseClass] flag informing if the writter/setter
|
36
|
+
# method should be added
|
37
|
+
# @param comparable [TrueClass,FalseClass] flag to make the class {Comparable}
|
38
|
+
# by the fields
|
39
|
+
#
|
40
|
+
# @example A model with writters
|
41
|
+
# class Job < Sinclair::Model.for({ state: :starting }, writter: true)
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# job = Job.new
|
45
|
+
#
|
46
|
+
# job.state # returns :starting
|
47
|
+
# job.state = :done
|
48
|
+
# job.state # returns :done
|
49
|
+
#
|
50
|
+
# @return [Class<Model>] a new class with the chosen attributes
|
51
|
+
def for(*attributes, **options)
|
52
|
+
Class.new(self) do |klass|
|
53
|
+
Builder.new(klass, *attributes, **options).build
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/sinclair/version.rb
CHANGED
data/lib/sinclair.rb
CHANGED
@@ -96,6 +96,7 @@ class Sinclair
|
|
96
96
|
autoload :MethodBuilder, 'sinclair/method_builder'
|
97
97
|
autoload :MethodDefinition, 'sinclair/method_definition'
|
98
98
|
autoload :MethodDefinitions, 'sinclair/method_definitions'
|
99
|
+
autoload :Model, 'sinclair/model'
|
99
100
|
autoload :Options, 'sinclair/options'
|
100
101
|
|
101
102
|
include OptionsParser
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Model do
|
6
|
+
describe 'readme' do
|
7
|
+
it 'Simple usage' do
|
8
|
+
human1 = Human.new(name: 'John Doe', age: 22)
|
9
|
+
human2 = Human.new(name: 'John Doe', age: 22)
|
10
|
+
|
11
|
+
expect(human1.name).to eq('John Doe')
|
12
|
+
expect(human1.age).to eq(22)
|
13
|
+
expect(human1.gender).to eq(:undefined)
|
14
|
+
expect(human1 == human2).to eq(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'Without comparable' do
|
18
|
+
tv1 = Tv.new(model: 'Sans Sunga Xt')
|
19
|
+
tv2 = Tv.new(model: 'Sans Sunga Xt')
|
20
|
+
|
21
|
+
expect(tv1 == tv2).to eq(false)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Object do
|
4
|
+
describe 'yard' do
|
5
|
+
describe '#is_any?' do
|
6
|
+
context 'when none match' do
|
7
|
+
it do
|
8
|
+
object = [1, 2, 3]
|
9
|
+
|
10
|
+
expect(object.is_any?(Hash, Class)).to eq(false)
|
11
|
+
expect(object.is_any?(Hash, Array)).to eq(true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'yard Sinclair::Model#for' do
|
6
|
+
it 'Creating a Simple model' do
|
7
|
+
car = Car.new(brand: :ford, model: :T)
|
8
|
+
|
9
|
+
expect(car.brand).to eq(:ford)
|
10
|
+
expect(car.model).to eq(:T)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'Creating a model with default values and writter' do
|
14
|
+
job = Job.new
|
15
|
+
|
16
|
+
expect(job.state).to eq(:starting)
|
17
|
+
job.state = :done
|
18
|
+
expect(job.state).to eq(:done)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Object do
|
6
|
+
describe '#is_any?' do
|
7
|
+
subject(:object) { 1 }
|
8
|
+
|
9
|
+
it do
|
10
|
+
expect(object).to respond_to(:is_any?)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when no argument is passed' do
|
14
|
+
it do
|
15
|
+
expect(object).not_to be_is_any
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when passing the correct class as argument' do
|
20
|
+
it do
|
21
|
+
expect(object).to be_is_any(object.class)
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when passing any other class' do
|
25
|
+
it do
|
26
|
+
expect(object).to be_is_any(Symbol, object.class)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when passing the wrong class' do
|
32
|
+
it do
|
33
|
+
expect(object).not_to be_is_any(Symbol)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodDefinition::ParameterHelper do
|
6
|
+
describe '.parameters_from' do
|
7
|
+
context 'when parameters are not named' do
|
8
|
+
context 'when there are no defaults' do
|
9
|
+
it 'returns a list of parameters' do
|
10
|
+
expect(described_class.parameters_from(%i[a b]))
|
11
|
+
.to eq(%w[a b])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when there are defaults' do
|
16
|
+
let(:parameters) do
|
17
|
+
[{ a: 10, b: 'word', c: true, d: false, e: nil, f: :symbol }]
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns a list of parameters' do
|
21
|
+
expect(described_class.parameters_from(parameters))
|
22
|
+
.to eq(['a = 10', 'b = "word"', 'c = true', 'd = false', 'e = nil', 'f = :symbol'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when parameters are named' do
|
28
|
+
context 'when there are no defaults' do
|
29
|
+
it 'returns a list of parameters' do
|
30
|
+
expect(described_class.parameters_from(%i[a b], named: true))
|
31
|
+
.to eq(%w[a: b:])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when there are defaults' do
|
36
|
+
let(:parameters) do
|
37
|
+
[{ a: 10, b: 'word', c: true, d: false, e: nil, f: :symbol }]
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns a list of parameters' do
|
41
|
+
expect(described_class.parameters_from(parameters, named: true))
|
42
|
+
.to eq(['a: 10', 'b: "word"', 'c: true', 'd: false', 'e: nil', 'f: :symbol'])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::MethodDefinition::Stringifier do
|
6
|
+
describe '.value_string' do
|
7
|
+
context 'when value is nil' do
|
8
|
+
it 'returns string representing nil' do
|
9
|
+
expect(described_class.value_string(nil)).to eq('nil')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when value is a symbol' do
|
14
|
+
it 'returns string representing a symbol' do
|
15
|
+
expect(described_class.value_string(:symbol)).to eq(':symbol')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when value is a string' do
|
20
|
+
it 'returns string representing a string' do
|
21
|
+
expect(described_class.value_string('string')).to eq('"string"')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when value is a number' do
|
26
|
+
it 'returns string representing a number' do
|
27
|
+
expect(described_class.value_string(10)).to eq('10')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when value is a float' do
|
32
|
+
it 'returns string representing a float' do
|
33
|
+
expect(described_class.value_string(1.20)).to eq('1.2')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when value is a true' do
|
38
|
+
it 'returns string representing a true' do
|
39
|
+
expect(described_class.value_string(true)).to eq('true')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when value is a false' do
|
44
|
+
it 'returns string representing a false' do
|
45
|
+
expect(described_class.value_string(false)).to eq('false')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when value is a class' do
|
50
|
+
it 'returns string representing a class' do
|
51
|
+
expect(described_class.value_string(Sinclair::Model)).to eq('Sinclair::Model')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when value is a hash' do
|
56
|
+
it 'returns string representing a Hash' do
|
57
|
+
expect(described_class.value_string({ a: 10, 'b' => 'value' }))
|
58
|
+
.to eq('{:a=>10, "b"=>"value"}')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when value is an Array' do
|
63
|
+
it 'returns string representing a Array' do
|
64
|
+
expect(described_class.value_string([:a, 10, 'b', true, nil]))
|
65
|
+
.to eq('[:a, 10, "b", true, nil]')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Model do
|
6
|
+
describe '.with_attributes' do
|
7
|
+
subject(:model) { klass.new(name: name) }
|
8
|
+
|
9
|
+
let(:name) { SecureRandom.hex(10) }
|
10
|
+
let(:attributes) { %i[name] }
|
11
|
+
|
12
|
+
context 'when the call happens with no options' do
|
13
|
+
subject(:klass) { described_class.for(*attributes) }
|
14
|
+
|
15
|
+
it 'Returns a new class' do
|
16
|
+
expect(klass.superclass)
|
17
|
+
.to eq(described_class)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns a class with getter' do
|
21
|
+
expect(klass.instance_method(:name))
|
22
|
+
.to be_a(UnboundMethod)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns a class with setter' do
|
26
|
+
expect(klass.instance_method(:name=))
|
27
|
+
.to be_a(UnboundMethod)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns a new class with a comparable that finds matches' do
|
31
|
+
expect(model).to eq(klass.new(name: name))
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns a new class with a comparable that find misses' do
|
35
|
+
expect(model).not_to eq(klass.new(name: SecureRandom.hex(10)))
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when reader is called' do
|
39
|
+
it do
|
40
|
+
expect(model.name).to eq(name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when setter is called' do
|
45
|
+
let(:name) { SecureRandom.hex(10) }
|
46
|
+
let(:model) { klass.new(name: nil) }
|
47
|
+
|
48
|
+
it do
|
49
|
+
expect { model.name = name }
|
50
|
+
.to change(model, :name)
|
51
|
+
.from(nil)
|
52
|
+
.to(name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when the call happens with comparable false' do
|
58
|
+
subject(:klass) { described_class.for(*attributes, **options) }
|
59
|
+
|
60
|
+
let(:options) { { comparable: false } }
|
61
|
+
|
62
|
+
it 'returns a new class without comparable' do
|
63
|
+
expect(model).not_to eq(klass.new(name: name))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when the call happens with reader options' do
|
68
|
+
subject(:klass) { described_class.for(*attributes, **options) }
|
69
|
+
|
70
|
+
let(:options) { { writter: false } }
|
71
|
+
|
72
|
+
it 'Returns a new class' do
|
73
|
+
expect(klass.superclass)
|
74
|
+
.to eq(described_class)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'returns a class with getter' do
|
78
|
+
expect(klass.instance_method(:name))
|
79
|
+
.to be_a(UnboundMethod)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns a class without setter' do
|
83
|
+
expect { klass.instance_method(:name=) }
|
84
|
+
.to raise_error(NameError)
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when reader is called' do
|
88
|
+
it do
|
89
|
+
expect(model.name).to eq(name)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when the call happens with defaults' do
|
95
|
+
subject(:klass) do
|
96
|
+
described_class.for({ name: 'John Doe' }, **{})
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'Returns a new class' do
|
100
|
+
expect(klass.superclass)
|
101
|
+
.to eq(described_class)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns a class with getter' do
|
105
|
+
expect(klass.instance_method(:name))
|
106
|
+
.to be_a(UnboundMethod)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'returns a class with setter' do
|
110
|
+
expect(klass.instance_method(:name=))
|
111
|
+
.to be_a(UnboundMethod)
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when reader is called' do
|
115
|
+
subject(:model) { klass.new }
|
116
|
+
|
117
|
+
let(:name) { SecureRandom.hex(10) }
|
118
|
+
|
119
|
+
it 'returns the dfault value' do
|
120
|
+
expect(model.name).to eq('John Doe')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'when setter is called' do
|
125
|
+
subject(:model) { klass.new }
|
126
|
+
|
127
|
+
let(:name) { SecureRandom.hex(10) }
|
128
|
+
|
129
|
+
it do
|
130
|
+
expect { model.name = name }
|
131
|
+
.to change(model, :name)
|
132
|
+
.from('John Doe')
|
133
|
+
.to(name)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinclair
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DarthJee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03-
|
11
|
+
date: 2023-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -280,6 +280,7 @@ files:
|
|
280
280
|
- lib/sinclair/config_class.rb
|
281
281
|
- lib/sinclair/config_factory.rb
|
282
282
|
- lib/sinclair/configurable.rb
|
283
|
+
- lib/sinclair/core_ext/object.rb
|
283
284
|
- lib/sinclair/env_settable.rb
|
284
285
|
- lib/sinclair/env_settable/builder.rb
|
285
286
|
- lib/sinclair/equals_checker.rb
|
@@ -311,7 +312,10 @@ files:
|
|
311
312
|
- lib/sinclair/method_definition/parameter_builder.rb
|
312
313
|
- lib/sinclair/method_definition/parameter_helper.rb
|
313
314
|
- lib/sinclair/method_definition/string_definition.rb
|
315
|
+
- lib/sinclair/method_definition/stringifier.rb
|
314
316
|
- lib/sinclair/method_definitions.rb
|
317
|
+
- lib/sinclair/model.rb
|
318
|
+
- lib/sinclair/model/builder.rb
|
315
319
|
- lib/sinclair/options.rb
|
316
320
|
- lib/sinclair/options/builder.rb
|
317
321
|
- lib/sinclair/options/class_methods.rb
|
@@ -325,6 +329,7 @@ files:
|
|
325
329
|
- spec/integration/readme/sinclair/configurable_spec.rb
|
326
330
|
- spec/integration/readme/sinclair/env_settable_spec.rb
|
327
331
|
- spec/integration/readme/sinclair/matchers_spec.rb
|
332
|
+
- spec/integration/readme/sinclair/model_spec.rb
|
328
333
|
- spec/integration/readme/sinclair/options_spec.rb
|
329
334
|
- spec/integration/readme/sinclair/types_of_definition_spec.rb
|
330
335
|
- spec/integration/readme/sinclair_spec.rb
|
@@ -337,6 +342,7 @@ files:
|
|
337
342
|
- spec/integration/yard/sinclair/config_factory_spec.rb
|
338
343
|
- spec/integration/yard/sinclair/config_spec.rb
|
339
344
|
- spec/integration/yard/sinclair/configurable_spec.rb
|
345
|
+
- spec/integration/yard/sinclair/core_ext/object_spec.rb
|
340
346
|
- spec/integration/yard/sinclair/env_settable_spec.rb
|
341
347
|
- spec/integration/yard/sinclair/equals_checker_spec.rb
|
342
348
|
- spec/integration/yard/sinclair/eval_and_add_method_spec.rb
|
@@ -347,6 +353,7 @@ files:
|
|
347
353
|
- spec/integration/yard/sinclair/matchers/add_instance_method_to_spec.rb
|
348
354
|
- spec/integration/yard/sinclair/matchers/change_class_method_spec.rb
|
349
355
|
- spec/integration/yard/sinclair/matchers/change_instance_method_spec.rb
|
356
|
+
- spec/integration/yard/sinclair/model_spec.rb
|
350
357
|
- spec/integration/yard/sinclair/options_parser_spec.rb
|
351
358
|
- spec/integration/yard/sinclair/options_spec.rb
|
352
359
|
- spec/integration/yard/sinclair_spec.rb
|
@@ -357,6 +364,7 @@ files:
|
|
357
364
|
- spec/lib/sinclair/config_factory_spec.rb
|
358
365
|
- spec/lib/sinclair/config_spec.rb
|
359
366
|
- spec/lib/sinclair/configurable_spec.rb
|
367
|
+
- spec/lib/sinclair/core_ext/object_spec.rb
|
360
368
|
- spec/lib/sinclair/env_settable/builder_spec.rb
|
361
369
|
- spec/lib/sinclair/env_settable_spec.rb
|
362
370
|
- spec/lib/sinclair/equals_checker_spec.rb
|
@@ -380,9 +388,12 @@ files:
|
|
380
388
|
- spec/lib/sinclair/method_definition/block_helper_spec.rb
|
381
389
|
- spec/lib/sinclair/method_definition/call_definition_spec.rb
|
382
390
|
- spec/lib/sinclair/method_definition/parameter_builder_spec.rb
|
391
|
+
- spec/lib/sinclair/method_definition/parameter_helper_spec.rb
|
383
392
|
- spec/lib/sinclair/method_definition/string_definition_spec.rb
|
393
|
+
- spec/lib/sinclair/method_definition/stringifier_spec.rb
|
384
394
|
- spec/lib/sinclair/method_definition_spec.rb
|
385
395
|
- spec/lib/sinclair/method_definitions_spec.rb
|
396
|
+
- spec/lib/sinclair/model_spec.rb
|
386
397
|
- spec/lib/sinclair/options/builder_spec.rb
|
387
398
|
- spec/lib/sinclair/options/class_methods_spec.rb
|
388
399
|
- spec/lib/sinclair/options_parser_spec.rb
|
@@ -393,6 +404,7 @@ files:
|
|
393
404
|
- spec/support/models/app_client.rb
|
394
405
|
- spec/support/models/app_config.rb
|
395
406
|
- spec/support/models/builder_options.rb
|
407
|
+
- spec/support/models/car.rb
|
396
408
|
- spec/support/models/client.rb
|
397
409
|
- spec/support/models/connection_options.rb
|
398
410
|
- spec/support/models/default_value.rb
|
@@ -407,7 +419,9 @@ files:
|
|
407
419
|
- spec/support/models/host_config.rb
|
408
420
|
- spec/support/models/http_json_model.rb
|
409
421
|
- spec/support/models/http_person.rb
|
422
|
+
- spec/support/models/human.rb
|
410
423
|
- spec/support/models/initial_valuer.rb
|
424
|
+
- spec/support/models/job.rb
|
411
425
|
- spec/support/models/login_config.rb
|
412
426
|
- spec/support/models/login_configurable.rb
|
413
427
|
- spec/support/models/my_app_client.rb
|
@@ -425,6 +439,7 @@ files:
|
|
425
439
|
- spec/support/models/server.rb
|
426
440
|
- spec/support/models/server_config.rb
|
427
441
|
- spec/support/models/service_client.rb
|
442
|
+
- spec/support/models/tv.rb
|
428
443
|
- spec/support/models/validator_builder.rb
|
429
444
|
- spec/support/sample_model.rb
|
430
445
|
- spec/support/shared_examples/attribute_accessor.rb
|