sinclair 1.12.1 → 1.14.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/.rubocop.yml +0 -1
- data/README.md +42 -3
- data/config/check_specs.yml +1 -0
- data/config/yardstick.yml +3 -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 +107 -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 +4 -4
- data/spec/lib/sinclair/method_definition/stringifier_spec.rb +69 -0
- data/spec/lib/sinclair/model_spec.rb +65 -0
- data/spec/support/models/car.rb +5 -0
- data/spec/support/models/human.rb +5 -0
- data/spec/support/models/job.rb +5 -0
- data/spec/support/models/tv.rb +4 -0
- data/spec/support/shared_examples/model.rb +121 -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: 6ee09cd280144bc873d89c0272856bf716e0a20c2ca5d3f7fe8bf11ac972c859
|
4
|
+
data.tar.gz: c5107aa15ffab29f4dd14b45efd0387913c60064ad62a58c4ec85adb09d91c9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38994db2d8a69ef1b9f3827a84bcb53a0bd18e2073a4840b004a89ac00a0fe0f5d9a8a69ce231b9d6c5f2cfc51b3a96c5ee898c848ce7ba802eac1d8556a058b
|
7
|
+
data.tar.gz: 4812c5a5793de217eb0cdd895c8cc94ac698af119c60fded29ea6929bddf0240b9dbcdba237dba7c1f060a3c3b8a3a173d2c7fef0509f6181d738ca0c7f0ef34
|
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.14.0](https://github.com/darthjee/sinclair/tree/1.14.0)
|
17
17
|
|
18
|
-
[Next release](https://github.com/darthjee/sinclair/compare/1.
|
18
|
+
[Next release](https://github.com/darthjee/sinclair/compare/1.14.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.14.0](https://www.rubydoc.info/gems/sinclair/1.14.0)
|
23
23
|
|
24
24
|
Installation
|
25
25
|
---------------
|
@@ -616,6 +616,45 @@ 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
|
631
|
+
initialize_with :name, :age, { gender: :undefined }, **{}
|
632
|
+
end
|
633
|
+
|
634
|
+
human1 = Human.new(name: 'John Doe', age: 22)
|
635
|
+
human2 = Human.new(name: 'John Doe', age: 22)
|
636
|
+
|
637
|
+
human1.name # returns 'John Doe'
|
638
|
+
human1.age # returns 22
|
639
|
+
human1.gender # returns :undefined
|
640
|
+
human1 == human2 # returns true
|
641
|
+
```
|
642
|
+
</details>
|
643
|
+
|
644
|
+
<details>
|
645
|
+
<summary>Example with options</summary>
|
646
|
+
|
647
|
+
```ruby
|
648
|
+
class Tv < Sinclair::Model.for(:model, writter: false, comparable: false)
|
649
|
+
end
|
650
|
+
|
651
|
+
tv1 = Tv.new(model: 'Sans Sunga Xt')
|
652
|
+
tv2 = Tv.new(model: 'Sans Sunga Xt')
|
653
|
+
|
654
|
+
tv1 == tv2 # returns false
|
655
|
+
```
|
656
|
+
</details>
|
657
|
+
|
619
658
|
RSspec matcher
|
620
659
|
---------------
|
621
660
|
|
data/config/check_specs.yml
CHANGED
data/config/yardstick.yml
CHANGED
@@ -29,6 +29,8 @@ 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
|
33
|
+
- Sinclair::Model.initialize_with
|
32
34
|
ReturnTag:
|
33
35
|
enabled: true
|
34
36
|
exclude:
|
@@ -63,6 +65,7 @@ rules:
|
|
63
65
|
- Sinclair::MethodDefinition::ParameterBuilder#initialize
|
64
66
|
- Sinclair::MethodDefinition::ParameterHelper#initialize
|
65
67
|
- Sinclair::MethodDefinition::StringDefinition#initialize
|
68
|
+
- Sinclair::Model::Builder#initialize
|
66
69
|
- Sinclair::Options#initialize
|
67
70
|
- Sinclair::Options::Builder#initialize
|
68
71
|
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.to_json}"
|
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,107 @@
|
|
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
|
+
# @deprecated Use {.initialize_with} instead
|
15
|
+
#
|
16
|
+
# @overload for(*attributes, writter: true, comparable: true)
|
17
|
+
# @param attributes [Array<Symbol>] attributes to be added in both the
|
18
|
+
# initialization and adding the methos to the model
|
19
|
+
# @param writter [TrueClass,FalseClass] flag informing if the writter/setter
|
20
|
+
# method should be added
|
21
|
+
# @param comparable [TrueClass,FalseClass] flag to make the class {Comparable}
|
22
|
+
# by the fields
|
23
|
+
#
|
24
|
+
# @example A model with readers
|
25
|
+
# class Car < Sinclair::Model.for(:brand, :model, writter: false)
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# car = Car.new(brand: :ford, model: :T)
|
29
|
+
#
|
30
|
+
# car.brand # returns :ford
|
31
|
+
# car.model # returns :T
|
32
|
+
#
|
33
|
+
# @overload for(*attributes, defaults, writter: true, comparable: true)
|
34
|
+
# @param attributes [Array<Symbol>] attributes to be added in both the
|
35
|
+
# initialization and adding the methos to the model
|
36
|
+
# @param defaults [Hash] attributes to be added with a default value in the initializer
|
37
|
+
# @param writter [TrueClass,FalseClass] flag informing if the writter/setter
|
38
|
+
# method should be added
|
39
|
+
# @param comparable [TrueClass,FalseClass] flag to make the class {Comparable}
|
40
|
+
# by the fields
|
41
|
+
#
|
42
|
+
# @example A model with writters
|
43
|
+
# class Job < Sinclair::Model.for({ state: :starting }, writter: true)
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# job = Job.new
|
47
|
+
#
|
48
|
+
# job.state # returns :starting
|
49
|
+
# job.state = :done
|
50
|
+
# job.state # returns :done
|
51
|
+
#
|
52
|
+
# @return [Class<Model>] a new class with the chosen attributes
|
53
|
+
def for(*attributes, **options)
|
54
|
+
Class.new(self) do |klass|
|
55
|
+
Builder.new(klass, *attributes, **options).build
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Adds methods needed for the model
|
60
|
+
#
|
61
|
+
# The readers/writters, +==+ and initializer are added
|
62
|
+
#
|
63
|
+
# @overload initialize_with(*attributes, writter: true, comparable: true)
|
64
|
+
# @param attributes [Array<Symbol>] attributes to be added in both the
|
65
|
+
# initialization and adding the methos to the model
|
66
|
+
# @param writter [TrueClass,FalseClass] flag informing if the writter/setter
|
67
|
+
# method should be added
|
68
|
+
# @param comparable [TrueClass,FalseClass] flag to make the class {Comparable}
|
69
|
+
# by the fields
|
70
|
+
#
|
71
|
+
# @example A model with readers
|
72
|
+
# class Car < Sinclair::Model
|
73
|
+
# initialize_with(:brand, :model, writter: false)
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# car = Car.new(brand: :ford, model: :T)
|
77
|
+
#
|
78
|
+
# car.brand # returns :ford
|
79
|
+
# car.model # returns :T
|
80
|
+
#
|
81
|
+
# @overload initialize_with(*attributes, defaults, writter: true, comparable: true)
|
82
|
+
# @param attributes [Array<Symbol>] attributes to be added in both the
|
83
|
+
# initialization and adding the methos to the model
|
84
|
+
# @param defaults [Hash] attributes to be added with a default value in the initializer
|
85
|
+
# @param writter [TrueClass,FalseClass] flag informing if the writter/setter
|
86
|
+
# method should be added
|
87
|
+
# @param comparable [TrueClass,FalseClass] flag to make the class {Comparable}
|
88
|
+
# by the fields
|
89
|
+
#
|
90
|
+
# @example A model with writters
|
91
|
+
# class Job < Sinclair::Model
|
92
|
+
# initialize_with({ state: :starting }, writter: true)
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# job = Job.new
|
96
|
+
#
|
97
|
+
# job.state # returns :starting
|
98
|
+
# job.state = :done
|
99
|
+
# job.state # returns :done
|
100
|
+
#
|
101
|
+
# @return [Array<MethodDefinition>]
|
102
|
+
def initialize_with(*attributes, **options)
|
103
|
+
Builder.new(self, *attributes, **options).build
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
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
|
@@ -14,12 +14,12 @@ describe Sinclair::MethodDefinition::ParameterHelper do
|
|
14
14
|
|
15
15
|
context 'when there are defaults' do
|
16
16
|
let(:parameters) do
|
17
|
-
[{ a: 10, b: 'word', c: true, d: false }]
|
17
|
+
[{ a: 10, b: 'word', c: true, d: false, e: nil, f: :symbol }]
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'returns a list of parameters' do
|
21
21
|
expect(described_class.parameters_from(parameters))
|
22
|
-
.to eq(['a = 10', 'b = "word"', 'c = true', 'd = false'])
|
22
|
+
.to eq(['a = 10', 'b = "word"', 'c = true', 'd = false', 'e = nil', 'f = :symbol'])
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -34,12 +34,12 @@ describe Sinclair::MethodDefinition::ParameterHelper do
|
|
34
34
|
|
35
35
|
context 'when there are defaults' do
|
36
36
|
let(:parameters) do
|
37
|
-
[{ a: 10, b: 'word', c: true, d: false }]
|
37
|
+
[{ a: 10, b: 'word', c: true, d: false, e: nil, f: :symbol }]
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'returns a list of parameters' do
|
41
41
|
expect(described_class.parameters_from(parameters, named: true))
|
42
|
-
.to eq(['a: 10', 'b: "word"', 'c: true', 'd: false'])
|
42
|
+
.to eq(['a: 10', 'b: "word"', 'c: true', 'd: false', 'e: nil', 'f: :symbol'])
|
43
43
|
end
|
44
44
|
end
|
45
45
|
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,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Model do
|
6
|
+
subject(:model) { klass.new(name: name) }
|
7
|
+
|
8
|
+
let(:name) { SecureRandom.hex(10) }
|
9
|
+
let(:attributes) { %i[name] }
|
10
|
+
let(:options) { {} }
|
11
|
+
|
12
|
+
describe '.for' do
|
13
|
+
subject(:klass) { described_class.for(*attributes, **options) }
|
14
|
+
|
15
|
+
it_behaves_like 'sinclair model building'
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.initialize_with' do
|
19
|
+
subject(:klass) { Class.new(described_class) }
|
20
|
+
|
21
|
+
context 'when no options are given' do
|
22
|
+
it do
|
23
|
+
expect { klass.initialize_with(*attributes, **options) }
|
24
|
+
.to add_method(:name).to(klass)
|
25
|
+
end
|
26
|
+
|
27
|
+
it do
|
28
|
+
expect { klass.initialize_with(*attributes, **options) }
|
29
|
+
.to add_method(:name=).to(klass)
|
30
|
+
end
|
31
|
+
|
32
|
+
it do
|
33
|
+
expect { klass.initialize_with(*attributes, **options) }
|
34
|
+
.to change_method(:==).on(klass)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when writter and comparable are not enabled' do
|
39
|
+
let(:options) { { writter: false, comparable: false } }
|
40
|
+
|
41
|
+
it do
|
42
|
+
expect { klass.initialize_with(*attributes, **options) }
|
43
|
+
.to add_method(:name).to(klass)
|
44
|
+
end
|
45
|
+
|
46
|
+
it do
|
47
|
+
expect { klass.initialize_with(*attributes, **options) }
|
48
|
+
.not_to add_method(:name=).to(klass)
|
49
|
+
end
|
50
|
+
|
51
|
+
it do
|
52
|
+
expect { klass.initialize_with(*attributes, **options) }
|
53
|
+
.not_to change_method(:==).on(klass)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when the build is done' do
|
58
|
+
before do
|
59
|
+
klass.initialize_with(*attributes, **options)
|
60
|
+
end
|
61
|
+
|
62
|
+
it_behaves_like 'sinclair model building'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_examples 'sinclair model building' do
|
4
|
+
context 'when the call happens with no options' do
|
5
|
+
it 'Returns a new class' do
|
6
|
+
expect(klass.superclass)
|
7
|
+
.to eq(described_class)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns a class with getter' do
|
11
|
+
expect(klass.instance_method(:name))
|
12
|
+
.to be_a(UnboundMethod)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns a class with setter' do
|
16
|
+
expect(klass.instance_method(:name=))
|
17
|
+
.to be_a(UnboundMethod)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns a new class with a comparable that finds matches' do
|
21
|
+
expect(model).to eq(klass.new(name: name))
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns a new class with a comparable that find misses' do
|
25
|
+
expect(model).not_to eq(klass.new(name: SecureRandom.hex(10)))
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when reader is called' do
|
29
|
+
it do
|
30
|
+
expect(model.name).to eq(name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when setter is called' do
|
35
|
+
let(:name) { SecureRandom.hex(10) }
|
36
|
+
let(:model) { klass.new(name: nil) }
|
37
|
+
|
38
|
+
it do
|
39
|
+
expect { model.name = name }
|
40
|
+
.to change(model, :name)
|
41
|
+
.from(nil)
|
42
|
+
.to(name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when the call happens with comparable false' do
|
48
|
+
let(:options) { { comparable: false } }
|
49
|
+
|
50
|
+
it 'returns a new class without comparable' do
|
51
|
+
expect(model).not_to eq(klass.new(name: name))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when the call happens with reader options' do
|
56
|
+
let(:options) { { writter: false } }
|
57
|
+
|
58
|
+
it 'Returns a new class' do
|
59
|
+
expect(klass.superclass)
|
60
|
+
.to eq(described_class)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'returns a class with getter' do
|
64
|
+
expect(klass.instance_method(:name))
|
65
|
+
.to be_a(UnboundMethod)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'returns a class without setter' do
|
69
|
+
expect { klass.instance_method(:name=) }
|
70
|
+
.to raise_error(NameError)
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when reader is called' do
|
74
|
+
it do
|
75
|
+
expect(model.name).to eq(name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when the call happens with defaults' do
|
81
|
+
let(:attributes) { [{ name: 'John Doe' }] }
|
82
|
+
|
83
|
+
it 'Returns a new class' do
|
84
|
+
expect(klass.superclass)
|
85
|
+
.to eq(described_class)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'returns a class with getter' do
|
89
|
+
expect(klass.instance_method(:name))
|
90
|
+
.to be_a(UnboundMethod)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns a class with setter' do
|
94
|
+
expect(klass.instance_method(:name=))
|
95
|
+
.to be_a(UnboundMethod)
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'when reader is called' do
|
99
|
+
subject(:model) { klass.new }
|
100
|
+
|
101
|
+
let(:name) { SecureRandom.hex(10) }
|
102
|
+
|
103
|
+
it 'returns the dfault value' do
|
104
|
+
expect(model.name).to eq('John Doe')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when setter is called' do
|
109
|
+
subject(:model) { klass.new }
|
110
|
+
|
111
|
+
let(:name) { SecureRandom.hex(10) }
|
112
|
+
|
113
|
+
it do
|
114
|
+
expect { model.name = name }
|
115
|
+
.to change(model, :name)
|
116
|
+
.from('John Doe')
|
117
|
+
.to(name)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
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.14.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-16 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
|
@@ -382,8 +390,10 @@ files:
|
|
382
390
|
- spec/lib/sinclair/method_definition/parameter_builder_spec.rb
|
383
391
|
- spec/lib/sinclair/method_definition/parameter_helper_spec.rb
|
384
392
|
- spec/lib/sinclair/method_definition/string_definition_spec.rb
|
393
|
+
- spec/lib/sinclair/method_definition/stringifier_spec.rb
|
385
394
|
- spec/lib/sinclair/method_definition_spec.rb
|
386
395
|
- spec/lib/sinclair/method_definitions_spec.rb
|
396
|
+
- spec/lib/sinclair/model_spec.rb
|
387
397
|
- spec/lib/sinclair/options/builder_spec.rb
|
388
398
|
- spec/lib/sinclair/options/class_methods_spec.rb
|
389
399
|
- spec/lib/sinclair/options_parser_spec.rb
|
@@ -394,6 +404,7 @@ files:
|
|
394
404
|
- spec/support/models/app_client.rb
|
395
405
|
- spec/support/models/app_config.rb
|
396
406
|
- spec/support/models/builder_options.rb
|
407
|
+
- spec/support/models/car.rb
|
397
408
|
- spec/support/models/client.rb
|
398
409
|
- spec/support/models/connection_options.rb
|
399
410
|
- spec/support/models/default_value.rb
|
@@ -408,7 +419,9 @@ files:
|
|
408
419
|
- spec/support/models/host_config.rb
|
409
420
|
- spec/support/models/http_json_model.rb
|
410
421
|
- spec/support/models/http_person.rb
|
422
|
+
- spec/support/models/human.rb
|
411
423
|
- spec/support/models/initial_valuer.rb
|
424
|
+
- spec/support/models/job.rb
|
412
425
|
- spec/support/models/login_config.rb
|
413
426
|
- spec/support/models/login_configurable.rb
|
414
427
|
- spec/support/models/my_app_client.rb
|
@@ -426,6 +439,7 @@ files:
|
|
426
439
|
- spec/support/models/server.rb
|
427
440
|
- spec/support/models/server_config.rb
|
428
441
|
- spec/support/models/service_client.rb
|
442
|
+
- spec/support/models/tv.rb
|
429
443
|
- spec/support/models/validator_builder.rb
|
430
444
|
- spec/support/sample_model.rb
|
431
445
|
- spec/support/shared_examples/attribute_accessor.rb
|
@@ -434,6 +448,7 @@ files:
|
|
434
448
|
- spec/support/shared_examples/config_factory.rb
|
435
449
|
- spec/support/shared_examples/env_settable.rb
|
436
450
|
- spec/support/shared_examples/instance_method_definition.rb
|
451
|
+
- spec/support/shared_examples/model.rb
|
437
452
|
- spec/support/shared_examples/sinclair.rb
|
438
453
|
homepage: https://github.com/darthjee/sinclair
|
439
454
|
licenses: []
|