strategic 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +10 -8
  4. data/lib/strategic.rb +7 -0
  5. metadata +17 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60db744a19fb4a7e6ac36c0fc5d36a6868a801d296c9331b4e865e087dd93c31
4
- data.tar.gz: a88167c7f3a97fe47be46abef4ccd840597e237bc84812a1da586db501cc7868
3
+ metadata.gz: d76d0987f4534352de4fb52f025547a0ef37cad16a9452f1fd78da71606a3bae
4
+ data.tar.gz: 389a399d74c94352cf2165a8975b0b8d5886c782d08614c8b674ae0bd329c2a3
5
5
  SHA512:
6
- metadata.gz: a0dd52c3176aa17bab03d9de1affdfbd8b90156278277ad3b2ade3a5d4401982a83208b5d04b54c9df39faf66845bd374f0eff9cd71cc6977382382fc7f4138a
7
- data.tar.gz: 966b2e8d07234cf47e0d6da3c622628d777970d99f7c5b6725760b53f7958e013b206aa6eb287d1da2c30a869373648a004db528d40647b89422cf812a4e7a90
6
+ metadata.gz: 5aa4d886c61f6daf162ac9a7dbd19635fb20cb0c9c9cef437998d8496e0e75f4c0381a7abe2c887ba794398ca4522489702cfa644cd18d180bb9cf95813a8725
7
+ data.tar.gz: 2243df9a574cbf09d708f16ef5d6c2bbc2d621e1932c50e68b081402ad19c49ab341dfdd07b5fd5461cbe1ad0ed17cf1898546d62e09b4e254b4ed3d9fbf8d89
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.2.0
4
+
5
+ - `default_strategy` default value will be `'default'`, assuming a `model_namespace/default_strategy.rb` file with `DefaultStrategy` class
6
+ - `new_with_default_strategy` class method (instantiating with `'default'` strategy if not configured or `default_strategy` class method value if configured)
7
+
3
8
  ## 1.1.0
4
9
 
5
10
  - Generate `strategy_name` attribute on `Strategic` class if it does not already exist like in the case of a Rails migration column
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Strategic 1.1.0
1
+ # Strategic 1.2.0
2
2
  ## Painless Strategy Pattern in Ruby and Rails
3
3
  [![Gem Version](https://badge.fury.io/rb/strategic.svg)](http://badge.fury.io/rb/strategic)
4
4
  [![rspec](https://github.com/AndyObtiva/strategic/actions/workflows/ruby.yml/badge.svg)](https://github.com/AndyObtiva/strategic/actions/workflows/ruby.yml)
@@ -28,7 +28,7 @@ code (Open/Closed Principle).
28
28
  externalizing all logic concerning algorithmic variations into separate strategy
29
29
  classes that are easy to find, maintain and extend while honoring the Open/Closed Principle and avoiding conditionals.
30
30
 
31
- In summary, if you make a class called `TaxCalculator` strategic by including the `Strategic` mixin module, now you are able to drop strategies under the `tax_calculator` directory sitting next to the class (e.g. `tax_calculator/us_strategy.rb`, `tax_calculator/canada_strategy.rb`) while gaining extra [API](#api) methods to grab strategy names to present in a user interface (`.strategy_names`), set a strategy (`#strategy=(strategy_name)` or `#strategy_name=(strategy_name)`), and/or instantiate `TaxCalculator` directly with a strategy from the get-go (`.new_with_strategy(strategy_name, *initialize_args)`). Finally, you can simply invoke strategy methods on the main strategic model (e.g. `tax_calculator.tax_for(39.78)`).
31
+ In summary, if you make a class called `TaxCalculator` strategic by including the `Strategic` mixin module, now you are able to drop strategies under the `tax_calculator` directory sitting next to the class (e.g. `tax_calculator/us_strategy.rb`, `tax_calculator/canada_strategy.rb`) while gaining extra [API](#api) methods to grab strategy names to present in a user interface (`.strategy_names`), set a strategy (`#strategy=(strategy_name)` or `#strategy_name=(strategy_name)`), and/or instantiate `TaxCalculator` directly (`.new(*initialize_args)`), with default strategy (`.new_with_default_strategy(*initialize_args)`), or with a strategy from the get-go (`.new_with_strategy(strategy_name, *initialize_args)`). Finally, you can simply invoke strategy methods on the main strategic model (e.g. `tax_calculator.tax_for(39.78)`).
32
32
 
33
33
  ### Example
34
34
 
@@ -98,9 +98,9 @@ tax_calculator = TaxCalculator.create(args) # args include strategy_name
98
98
  tax = tax_calculator.tax_for(39.78)
99
99
  ```
100
100
 
101
- Default strategy for a strategy name that has no strategy class is `nil`
101
+ Default strategy for a strategy name that has no strategy class is `nil` unless `DefaultStrategy` class exists under the model class namespace or `default_strategy` class attribute is set.
102
102
 
103
- You may set a default strategy on a strategic model via class method `default_strategy`
103
+ This is how to set a default strategy on a strategic model via class method `default_strategy`:
104
104
 
105
105
  ```ruby
106
106
  class TaxCalculator
@@ -122,7 +122,7 @@ If no strategy is selected and you try to invoke a method that belongs to strate
122
122
  Add the following to bundler's `Gemfile`.
123
123
 
124
124
  ```ruby
125
- gem 'strategic', '~> 1.1.0'
125
+ gem 'strategic', '~> 1.2.0'
126
126
  ```
127
127
 
128
128
  ### Option 2: Manual
@@ -130,7 +130,7 @@ gem 'strategic', '~> 1.1.0'
130
130
  Or manually install and require library.
131
131
 
132
132
  ```bash
133
- gem install strategic -v1.1.0
133
+ gem install strategic -v1.2.0
134
134
  ```
135
135
 
136
136
  ```ruby
@@ -142,7 +142,7 @@ require 'strategic'
142
142
  Steps:
143
143
  1. Have the original class you'd like to strategize include `Strategic` (e.g. `def TaxCalculator; include Strategic; end`
144
144
  2. Create a directory matching the class underscored file name minus the '.rb' extension (e.g. `tax_calculator/`)
145
- 3. Create a strategy class under that directory (e.g. `tax_calculator/us_strategy.rb`), which:
145
+ 3. Create a strategy class under that directory (e.g. `tax_calculator/us_strategy.rb`) (default is assumed as `tax_calculator/default_strategy.rb` unless customized with `default_strategy` class method):
146
146
  - Lives under the original class namespace
147
147
  - Includes the `Strategic::Strategy` module
148
148
  - Has a class name that ends with `Strategy` suffix (e.g. `NewCustomerStrategy`)
@@ -158,7 +158,8 @@ Steps:
158
158
 
159
159
  These methods can be delcared in a strategic model class body.
160
160
 
161
- - `::default_strategy`: sets default strategy as a strategy name string (e.g. 'us' selects UsStrategy) or alternatively a class/object if you have a mirror hierarchy for the strategy hierarchy
161
+ - `::default_strategy(strategy_name)`: sets default strategy as a strategy name string (e.g. 'us' selects UsStrategy) or alternatively a class/object if you have a mirror hierarchy for the strategy hierarchy
162
+ - `::default_strategy`: returns default strategy (default: `'default'` as in `DefaultStrategy`)
162
163
  - `::strategy_matcher`: custom matcher for all strategies (e.g. `strategy_matcher {|string| string.start_with?('C') && string.end_with?('o')}`)
163
164
 
164
165
  #### Class Methods
@@ -166,6 +167,7 @@ These methods can be delcared in a strategic model class body.
166
167
  - `::strategy_names`: returns list of strategy names (strings) discovered by convention (nested under a namespace matching the superclass name)
167
168
  - `::strategies`: returns list of strategies discovered by convention (nested under a namespace matching the superclass name)
168
169
  - `::new_with_strategy(string_or_class_or_object, *args, &block)`: instantiates a strategy based on a string/class/object and strategy constructor args
170
+ - `::new_with_default_strategy(*args, &block)`: instantiates with default strategy
169
171
  - `::strategy_class_for(string_or_class_or_object)`: selects a strategy class based on a string (e.g. 'us' selects UsStrategy) or alternatively a class/object if you have a mirror hierarchy for the strategy hierarchy
170
172
 
171
173
  #### Instance Methods
data/lib/strategic.rb CHANGED
@@ -30,6 +30,7 @@ module Strategic
30
30
  else
31
31
  klass.include(ExtraRubyMethods)
32
32
  end
33
+ klass.default_strategy 'default'
33
34
  end
34
35
 
35
36
  module ExtraRailsMethods
@@ -111,6 +112,12 @@ module Strategic
111
112
  end
112
113
  end
113
114
 
115
+ def new_with_default_strategy(*args, &block)
116
+ new(*args, &block).tap do |model|
117
+ model.strategy = nil
118
+ end
119
+ end
120
+
114
121
  def new_with_strategy(string_or_class_or_object, *args, &block)
115
122
  new(*args, &block).tap do |model|
116
123
  model.strategy = string_or_class_or_object
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strategic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-14 00:00:00.000000000 Z
11
+ date: 2022-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: 0.8.1
125
+ - !ruby/object:Gem::Dependency
126
+ name: rake-tui
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">"
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">"
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: |
126
140
  if/case conditionals can get really hairy in highly sophisticated business domains.
127
141
  Domain model inheritance can help remedy the problem, but you don't want to dump all
@@ -167,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
181
  - !ruby/object:Gem::Version
168
182
  version: '0'
169
183
  requirements: []
170
- rubygems_version: 3.2.22
184
+ rubygems_version: 3.3.1
171
185
  signing_key:
172
186
  specification_version: 4
173
187
  summary: Painless Strategy Pattern for Ruby and Rails