sinclair 1.13.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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: []