sinclair 1.13.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46b430c9db3658979d128e45ecbbb03aab30bb993d8651ecc8cc3bd9fe1b18e3
4
- data.tar.gz: fa78aa3bde540b7f90675566086e65d884cea51b2874b6cd5166ffc50018ab73
3
+ metadata.gz: 6ee09cd280144bc873d89c0272856bf716e0a20c2ca5d3f7fe8bf11ac972c859
4
+ data.tar.gz: c5107aa15ffab29f4dd14b45efd0387913c60064ad62a58c4ec85adb09d91c9c
5
5
  SHA512:
6
- metadata.gz: 9a290bcea44d39854bd7b8bd99b28c18d0a6c827b31f140fb339b82d49a9add6e505f738b4925b27c25ddedd695d06963a4221c55ff9b869157aaec5753a5747
7
- data.tar.gz: dfdc3723b6a6d31611eceb727007680aafc3f56d9cda1e16922768df7e9ce14238d0c982ff7e4232a914015c8d22850b869ab08601b8121727ce0673c43ca10b
6
+ metadata.gz: 38994db2d8a69ef1b9f3827a84bcb53a0bd18e2073a4840b004a89ac00a0fe0f5d9a8a69ce231b9d6c5f2cfc51b3a96c5ee898c848ce7ba802eac1d8556a058b
7
+ data.tar.gz: 4812c5a5793de217eb0cdd895c8cc94ac698af119c60fded29ea6929bddf0240b9dbcdba237dba7c1f060a3c3b8a3a173d2c7fef0509f6181d738ca0c7f0ef34
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.13.0](https://github.com/darthjee/sinclair/tree/1.13.0)
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.13.0...master)
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.13.0](https://www.rubydoc.info/gems/sinclair/1.13.0)
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
  ---------------
@@ -627,7 +627,8 @@ When creating a model class, options can be passed
627
627
  <summary>Example of simple usage</summary>
628
628
 
629
629
  ```ruby
630
- class Human < Sinclair::Model.for(:name, :age, { gender: :undefined }, **{})
630
+ class Human < Sinclair::Model
631
+ initialize_with :name, :age, { gender: :undefined }, **{}
631
632
  end
632
633
 
633
634
  human1 = Human.new(name: 'John Doe', age: 22)
data/config/yardstick.yml CHANGED
@@ -30,6 +30,7 @@ rules:
30
30
  - Sinclair::Matchers#change_method
31
31
  - Sinclair::Matchers#change_class_method
32
32
  - Sinclair::Model.for
33
+ - Sinclair::Model.initialize_with
33
34
  ReturnTag:
34
35
  enabled: true
35
36
  exclude:
@@ -11,6 +11,8 @@ class Sinclair
11
11
  class << self
12
12
  # Returns a new class that inherits from model
13
13
  #
14
+ # @deprecated Use {.initialize_with} instead
15
+ #
14
16
  # @overload for(*attributes, writter: true, comparable: true)
15
17
  # @param attributes [Array<Symbol>] attributes to be added in both the
16
18
  # initialization and adding the methos to the model
@@ -53,6 +55,53 @@ class Sinclair
53
55
  Builder.new(klass, *attributes, **options).build
54
56
  end
55
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
56
105
  end
57
106
  end
58
107
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.13.0'
4
+ VERSION = '1.14.0'
5
5
  end
@@ -3,136 +3,63 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Sinclair::Model do
6
- describe '.with_attributes' do
7
- subject(:model) { klass.new(name: name) }
6
+ subject(:model) { klass.new(name: name) }
8
7
 
9
- let(:name) { SecureRandom.hex(10) }
10
- let(:attributes) { %i[name] }
8
+ let(:name) { SecureRandom.hex(10) }
9
+ let(:attributes) { %i[name] }
10
+ let(:options) { {} }
11
11
 
12
- context 'when the call happens with no options' do
13
- subject(:klass) { described_class.for(*attributes) }
12
+ describe '.for' do
13
+ subject(:klass) { described_class.for(*attributes, **options) }
14
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
15
+ it_behaves_like 'sinclair model building'
16
+ end
29
17
 
30
- it 'returns a new class with a comparable that finds matches' do
31
- expect(model).to eq(klass.new(name: name))
32
- end
18
+ describe '.initialize_with' do
19
+ subject(:klass) { Class.new(described_class) }
33
20
 
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)))
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)
36
25
  end
37
26
 
38
- context 'when reader is called' do
39
- it do
40
- expect(model.name).to eq(name)
41
- end
27
+ it do
28
+ expect { klass.initialize_with(*attributes, **options) }
29
+ .to add_method(:name=).to(klass)
42
30
  end
43
31
 
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
32
+ it do
33
+ expect { klass.initialize_with(*attributes, **options) }
34
+ .to change_method(:==).on(klass)
54
35
  end
55
36
  end
56
37
 
57
- context 'when the call happens with comparable false' do
58
- subject(:klass) { described_class.for(*attributes, **options) }
38
+ context 'when writter and comparable are not enabled' do
39
+ let(:options) { { writter: false, comparable: false } }
59
40
 
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))
41
+ it do
42
+ expect { klass.initialize_with(*attributes, **options) }
43
+ .to add_method(:name).to(klass)
64
44
  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
45
 
72
- it 'Returns a new class' do
73
- expect(klass.superclass)
74
- .to eq(described_class)
46
+ it do
47
+ expect { klass.initialize_with(*attributes, **options) }
48
+ .not_to add_method(:name=).to(klass)
75
49
  end
76
50
 
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
51
+ it do
52
+ expect { klass.initialize_with(*attributes, **options) }
53
+ .not_to change_method(:==).on(klass)
91
54
  end
92
55
  end
93
56
 
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)
57
+ context 'when the build is done' do
58
+ before do
59
+ klass.initialize_with(*attributes, **options)
112
60
  end
113
61
 
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
62
+ it_behaves_like 'sinclair model building'
136
63
  end
137
64
  end
138
65
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: false
2
2
 
3
- class Car < Sinclair::Model.for(:brand, :model, writter: false)
3
+ class Car < Sinclair::Model
4
+ initialize_with(:brand, :model, writter: false)
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Human < Sinclair::Model.for(:name, :age, { gender: :undefined }, **{})
3
+ class Human < Sinclair::Model
4
+ initialize_with :name, :age, { gender: :undefined }, **{}
4
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: false
2
2
 
3
- class Job < Sinclair::Model.for({ state: :starting }, writter: true)
3
+ class Job < Sinclair::Model
4
+ initialize_with({ state: :starting }, writter: true)
4
5
  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.13.0
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-15 00:00:00.000000000 Z
11
+ date: 2023-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -448,6 +448,7 @@ files:
448
448
  - spec/support/shared_examples/config_factory.rb
449
449
  - spec/support/shared_examples/env_settable.rb
450
450
  - spec/support/shared_examples/instance_method_definition.rb
451
+ - spec/support/shared_examples/model.rb
451
452
  - spec/support/shared_examples/sinclair.rb
452
453
  homepage: https://github.com/darthjee/sinclair
453
454
  licenses: []