danica 2.5.0 → 2.5.1

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
  SHA1:
3
- metadata.gz: dbc5e0d585c75c30257524380ed56a556daa08c5
4
- data.tar.gz: 429e5c4ed8845329ebd79f9bfa9353b809e1e763
3
+ metadata.gz: 97379e35fd308207eb9c9fce91da8235e36ac3ea
4
+ data.tar.gz: a254b8b7911c64d5a6a6d99cb86279098f864012
5
5
  SHA512:
6
- metadata.gz: 4fb11c37df1b65c3b960d5d9cf1fecd828e445171e950b16c9f532190e490d37b733923be0d3fc809e54eb1d8cd27fcf9f05b02af60eb4772d13280ffbf825f0
7
- data.tar.gz: e737d1f7f965f29bc7d95a44744385400f12c6b863544a52ea06f851cb137b0a0a33ce90d669c5d2effe79e575d4eeb92a1cff49dbd2fc2ebacd6796542e35b3
6
+ metadata.gz: f4e74d4eb9dcee0763c72342cdf6b2ae08c892284ca7c4d4fc9bea5898f18481a343c0407bc2ccd1b96de8a238ed6d327e5fbd70bf1421b7e296b7238d84c18d
7
+ data.tar.gz: 3dbfa63432ff97ea589d12f5331abf83e051aea1bdef257bb9caf8a17fbec8f982551f8ec519d0805652adb40f698b21becf69cbc1cdef5496369d360a0aef62
data/README.md CHANGED
@@ -7,31 +7,29 @@ A tool for math formulation on docs
7
7
  ## How to use
8
8
  Add the gem to your project or just install the gem
9
9
 
10
- ```
10
+ ```ruby
11
11
  gem 'danica'
12
12
  ```
13
13
 
14
- ```console
14
+ ```bash
15
15
  bundle install danica
16
16
  ```
17
17
 
18
18
  Now you can use in your project
19
19
 
20
20
  ### Quick Use
21
- Use Danica build to build and use your formula using ```Danica.build```
21
+ Use Danica build to build and use your expression using ```Danica.build```
22
22
  ```ruby
23
- formula = Danica.build do
23
+ expression = Danica.build do
24
24
  (number(1) + 2) * power(3,4)
25
25
  end
26
-
27
- formula.to_tex
28
26
  ```
29
27
 
30
28
  create and use functions
31
29
 
32
30
  ```ruby
33
31
  func = Danica.build do
34
- formula(:x, :y) do
32
+ Danica::Function.create(:x, :y) do
35
33
  (number(1) + x) * power(3, y)
36
34
  end
37
35
  end
@@ -39,14 +37,12 @@ end
39
37
  func.to_gnu
40
38
  ```
41
39
 
42
- create gnu or tex output strings to be used on yopur template
40
+ create gnu or tex output strings to be used on your template
43
41
 
44
42
  ### Operators
45
- Operators are much like function, but they do not have a name.
46
-
47
- While a function would be something in the format ```f(x) = x + 1```, an operator would just represent the sum ```x + 1```
43
+ Operators represent a matematical operation such as sum, product, sin, etc..
48
44
 
49
- Operators are to be composed to create a Function ([see below](#functions)) being their difference almost semantic
45
+ Operators are to be composed to create an [expression](#expressions), [equation](#expressions) or [function](#functions) (see below)
50
46
 
51
47
  ```ruby
52
48
  class MyOperator < Danica::Operator
@@ -93,7 +89,7 @@ fx.to_tex
93
89
  ```
94
90
 
95
91
  returns
96
- ```string
92
+ ```tex
97
93
  (x)^{-1}
98
94
  ```
99
95
 
@@ -103,7 +99,7 @@ fx.to_gnu
103
99
  ```
104
100
 
105
101
  returns
106
- ```string
102
+ ```gnuplot
107
103
  (x) ** -1
108
104
  ```
109
105
 
@@ -117,24 +113,99 @@ Danica::Operator::Inverse.new(2).to_f
117
113
  ```
118
114
 
119
115
  both return
120
- ```string
116
+ ```float
121
117
  0.5
122
118
  ```
123
119
 
120
+ ### Expressions
121
+
122
+ Expressions are composition of operators threating their variables input.
123
+
124
+ Example of expression could be ```x ^ y + y / 2``` which is composed of an operator sum of 2 parcels,
125
+ being the first an operator power and the second an operator division, while the variable ```x``` is only used
126
+ as the base of the power operator and the y variable is present on both power and division operator
127
+
128
+ Expressions can be defined on the fly or as a class
129
+
130
+ ```ruby
131
+ clazz = Danica::Expression.build(:a, :b, :c) do
132
+ (
133
+ negative(b) + Danica::Wrapper::PlusMinus.new(
134
+ squared_root(
135
+ power(b, 2) - multiplication(4, a, c)
136
+ )
137
+ )
138
+ ) / (number(2) * a)
139
+ end
140
+ ```
141
+
142
+ ```ruby
143
+ module Danica
144
+ class Expression::Baskara < Expression.build(:a, :b, :c) { numerator / denominator }
145
+
146
+ private
147
+
148
+ def numerator
149
+ negative(b) + Wrapper::PlusMinus.new(squared_root(delta))
150
+ end
151
+
152
+ def denominator
153
+ number(2) * a
154
+ end
155
+
156
+ def delta
157
+ power(b, 2) - multiplication(4, a, c)
158
+ end
159
+ end
160
+ end
161
+ clazz = Danica::Expression::Baskara
162
+ ```
163
+
164
+ Both would create a class whose instance knows how to build baskara formula
165
+
166
+ ```ruby
167
+ clazz.new.to_tex
168
+ ```
169
+
170
+ ```tex
171
+ \frac{-b \pm \sqrt{b^{2} -4 \cdot a \cdot c}}{2 \cdot a}
172
+ ```
173
+
174
+ ### Equations
175
+
176
+ Equations are formed by two expressions with their own variables
177
+
178
+ ```ruby
179
+ Danica::Equation.new.tap do |equation|
180
+ equation.left = Danica.build(:x, :y) do
181
+ x ** 2 + y ** 2
182
+ end
183
+ equation.right = Danica.build(:x, :z) do
184
+ number(1) - z ** 2
185
+ end
186
+ end.to_tex
187
+ ```
188
+
189
+ so we can create the equation
190
+
191
+ ```gnuplot
192
+ x**(2) + y**(2) = 1 -z**(2)
193
+ ```
194
+
124
195
  ### Functions
125
196
 
126
- Functions are composition of operators threating their variables input.
197
+ Functions are equations whose one of the sides is actually the naming of the function and variables declaration
127
198
 
128
199
  Example of function could be ```f(x,y) = x ^ y + y / 2``` which is composed of an operator sum of 2 parcels,
129
200
  being the first an operator power and the second an operator division, while the variable ```x``` is only used
130
201
  as the base of the power operator and the y variable is present on both power and division operator
131
202
 
132
203
  ```ruby
133
- class MyFunction
134
- variables :variables_list
204
+ class MyFunction < Danica::Function
205
+ variables :x, :y ...
135
206
 
136
207
  def function_block
137
- # code of operators composition
208
+ #your code goes here
138
209
  end
139
210
  end
140
211
  ```
@@ -187,8 +258,8 @@ fx.to_tex
187
258
  ```
188
259
 
189
260
  returns
190
- ```string
191
- S_0 + V_0 \cdot t + \frac{a \cdot t^{2}}{2}
261
+ ```tex
262
+ f(t, a, S_0, V_0) = S_0 + V_0 \cdot t + \frac{a \cdot t^{2}}{2}
192
263
  ```
193
264
 
194
265
  ##### to_gnu
@@ -197,36 +268,8 @@ fx.to_gnu
197
268
  ```
198
269
 
199
270
  returns
200
- ```string
201
- S0 + V0 * t + (a * t**(2))/(2)
202
- ```
203
-
204
- ##### describe_tex
205
- Returns the full description of the function
206
-
207
- ```ruby
208
- fx.name = :g
209
- fx.describe_tex
210
- ```
211
-
212
- returns
213
-
214
- ```string
215
- g(t, a, S_0, V_0) = S_0 + V_0 \cdot t + \frac{a \cdot t^{2}}{2}
216
- ```
217
-
218
- ##### describe_gnu
219
- Returns the full description of the function
220
-
221
- ```ruby
222
- fx.name = :g
223
- fx.describe_gnu
224
- ```
225
-
226
- returns
227
-
228
- ```string
229
- g(t, a, S0, V0) = S0 + V0 * t + (a * t**(2))/(2)
271
+ ```gnuplot
272
+ f(t, a, S0, V0) = S0 + V0 * t + (a * t**(2))/(2)
230
273
  ```
231
274
 
232
275
  ##### calculate / to_f
@@ -282,7 +325,7 @@ fx.to_tex
282
325
  ```
283
326
 
284
327
  returns
285
- ```string
328
+ ```tex
286
329
  x^{2} -y^{2}
287
330
  ```
288
331
 
@@ -292,12 +335,12 @@ fx.to_gnu
292
335
  ```
293
336
 
294
337
  returns
295
- ```string
338
+ ```gnuplot
296
339
  x**(2) -y**(2)
297
340
  ```
298
341
 
299
342
  ### DSL and building
300
- A function can be created using the DSL direct from ```Danica```
343
+ An expression can be created using the DSL direct from ```Danica```
301
344
 
302
345
  ```ruby
303
346
  Danica.build do
@@ -305,7 +348,7 @@ Danica.build do
305
348
  end
306
349
  ```
307
350
 
308
- will result into a ```Danica::Operator::Power``` object
351
+ will result into a ```Danica::Operator::Power``` wrapped into an ```Danica::Expression```
309
352
 
310
353
  ```ruby
311
354
  Danica::Operator::Power.new(:x, -1)
@@ -2,8 +2,10 @@ module Danica
2
2
  class Builder
3
3
  include DSL
4
4
 
5
- def build(&block)
6
- instance_eval(&block)
5
+ def build(*vars, &block)
6
+ Expression.create(*vars, &block).tap do |expression|
7
+ return expression.expression_block if expression.expression_block.is_a? Expressable
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -4,7 +4,7 @@ module Danica
4
4
  attr_reader :name, :containers
5
5
 
6
6
  def initialize(name:, variables:)
7
- @name = name
7
+ @name = name || :f
8
8
  @containers = variables.map do |v|
9
9
  v = wrap_value(v)
10
10
  v = Wrapper::Container.new(v) unless v.container?
@@ -1,3 +1,3 @@
1
1
  module Danica
2
- VERSION = '2.5.0'
2
+ VERSION = '2.5.1'
3
3
  end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Danica do
4
+ describe '.build' do
5
+ context 'when building an expression' do
6
+ let(:expression) do
7
+ Danica.build do
8
+ (number(1) + 2) * power(3,4)
9
+ end
10
+ end
11
+
12
+ it do
13
+ expect(expression).to be_a(Danica::Expression)
14
+ end
15
+ end
16
+
17
+ context 'when building a function' do
18
+ let(:function) do
19
+ Danica.build do
20
+ Danica::Function.create(:x, :y) do
21
+ (number(1) + x) * power(3, y)
22
+ end
23
+ end
24
+ end
25
+
26
+ it do
27
+ expect(function).to be_a(Danica::Function)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Danica::Equation do
4
+ subject do
5
+ described_class.new.tap do |equation|
6
+ equation.left = Danica.build(:x, :y) do
7
+ x ** 2 + y ** 2
8
+ end
9
+ equation.right = Danica.build(:x, :z) do
10
+ number(1) - z ** 2
11
+ end
12
+ end
13
+ end
14
+
15
+ describe '#to_gnu' do
16
+ it 'generates the gnu format' do
17
+ expect(subject.to_gnu).to eq('x**(2) + y**(2) = 1 -z**(2)')
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Danica::Expression::Baskara do
4
+ describe '#to_tex' do
5
+ it 'returns bascara tex string' do
6
+ expect(subject.to_tex).to eq('\frac{-b \pm \sqrt{b^{2} -4 \cdot a \cdot c}}{2 \cdot a}')
7
+ end
8
+ end
9
+ end
10
+
11
+ describe Danica::Expression do
12
+ let(:clazz) do
13
+ described_class.build(:a, :b, :c) do
14
+ (
15
+ negative(b) + Danica::Wrapper::PlusMinus.new(
16
+ squared_root(
17
+ power(b, 2) - multiplication(4, a, c)
18
+ )
19
+ )
20
+ ) / (number(2) * a)
21
+ end
22
+ end
23
+ subject { clazz.new }
24
+
25
+ describe 'to_tex' do
26
+ it 'returns bascara tex string' do
27
+ expect(subject.to_tex).to eq('\frac{-b \pm \sqrt{b^{2} -4 \cdot a \cdot c}}{2 \cdot a}')
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe Danica::Function::Spatial do
4
+ subject do
5
+ described_class.new(
6
+ time: :t,
7
+ acceleration: 'a',
8
+ initial_space: { name: :S0, latex: 'S_0', gnu: 'S0' },
9
+ initial_velocity: { name: :V0, latex: 'V_0', gnu: 'V0' }
10
+ )
11
+ end
12
+
13
+ let(:name) { :f }
14
+
15
+ context 'when using it as default' do
16
+ let(:left) { "#{name}(time, acceleration, initial_space, initial_velocity)" }
17
+ let(:right) { 'initial_space + initial_velocity * time + (acceleration * time**(2))/(2)' }
18
+
19
+ subject { described_class.new }
20
+
21
+ it 'knows how to return to gnu format' do
22
+ expect(subject.to_gnu).to eq("#{left} = #{right}")
23
+ end
24
+
25
+ context 'when changing the name' do
26
+ let(:name) { :g }
27
+ subject { described_class.new(name: name) }
28
+
29
+ it 'knows how to return to gnu format' do
30
+ expect(subject.to_gnu).to eq("#{left} = #{right}")
31
+ end
32
+ end
33
+ end
34
+
35
+ context 'when setting the variables' do
36
+ let(:variables) do
37
+ { time: :t, acceleration: :a, initial_space: :s0, initial_velocity: :v0 }
38
+ end
39
+ let(:left) { "#{name}(t, a, s0, v0)" }
40
+ let(:right) { 's0 + v0 * t + (a * t**(2))/(2)' }
41
+
42
+ subject { described_class.new(variables) }
43
+
44
+ it 'knows how to return to gnu format' do
45
+ expect(subject.to_gnu).to eq("#{left} = #{right}")
46
+ end
47
+ end
48
+
49
+ describe '#to_tex' do
50
+ let(:left) { "#{name}(t, a, S_0, V_0)" }
51
+ let(:right) { 'S_0 + V_0 \cdot t + \frac{a \cdot t^{2}}{2}' }
52
+
53
+ it 'builds tex format with its variables' do
54
+ expect(subject.to_tex).to eq("#{left} = #{right}")
55
+ end
56
+ end
57
+
58
+ describe '#to_gnu' do
59
+ let(:left) { "#{name}(t, a, S0, V0)" }
60
+ let(:right) { 'S0 + V0 * t + (a * t**(2))/(2)' }
61
+
62
+ it 'builds gnu format with its variables' do
63
+ expect(subject.to_gnu).to eq("#{left} = #{right}")
64
+ end
65
+ end
66
+ end
67
+
68
+ describe Danica::Function::MyFunction do
69
+ describe '#to_gnu' do
70
+ it 'returns the function' do
71
+ expect(subject.to_gnu).to eq('f(x, y) = x**(2) + y')
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe MyOperator do
4
+ describe '#to_gnu' do
5
+ it 'returns the gnu format' do
6
+ expect(subject.to_gnu).to eq('x**(pi)')
7
+ end
8
+ end
9
+
10
+ describe '#to_tex' do
11
+ it 'returns the tex format' do
12
+ expect(subject.to_tex).to eq('x^{\pi}')
13
+ end
14
+ end
15
+
16
+ describe '#to_f' do
17
+ subject { described_class.new(x: 2) }
18
+
19
+ it 'returns the result of the operation' do
20
+ expect(subject.to_f).to eq(2 ** Math::PI)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe Danica::Operator::Inverse do
26
+ subject { described_class.new(:x) }
27
+
28
+ describe '#to_tex' do
29
+ it 'returns the formated tex string' do
30
+ expect(subject.to_tex).to eq('(x)^{-1}')
31
+ end
32
+ end
33
+
34
+ describe '#to_gnu' do
35
+ it 'returns the formated gnu string' do
36
+ expect(subject.to_gnu).to eq('(x) ** -1')
37
+ end
38
+ end
39
+
40
+ describe '#to_f' do
41
+ it do
42
+ expect { subject.to_f }.to raise_error(Danica::Exception::NotDefined)
43
+ end
44
+
45
+ context 'when value is defined' do
46
+ subject { described_class.new 2 }
47
+
48
+ it 'returns the calculated value' do
49
+ expect(subject.to_f).to eq(0.5)
50
+ end
51
+ end
52
+ end
53
+
54
+ describe '#calculate' do
55
+ it 'returns the calculated value' do
56
+ expect(subject.calculate(2)).to eq(0.5)
57
+ end
58
+ end
59
+ end
@@ -10,7 +10,7 @@ describe Danica do
10
10
  end
11
11
 
12
12
  it 'returns the expected addition' do
13
- expect(result).to eq(Danica::Operator::Addition.new(1,2))
13
+ expect(result.expression_block).to eq(Danica::Operator::Addition.new(1,2))
14
14
  end
15
15
  end
16
16
 
@@ -26,7 +26,7 @@ describe Danica do
26
26
  end
27
27
 
28
28
  it 'returns the expected power' do
29
- expect(result).to eq(expected)
29
+ expect(result.expression_block).to eq(expected)
30
30
  end
31
31
  end
32
32
 
@@ -37,7 +37,7 @@ describe Danica do
37
37
  let(:expected) { Danica::Wrapper::Negative.new(10) }
38
38
 
39
39
  it 'returns the expected negative' do
40
- expect(result).to eq(expected)
40
+ expect(result.expression_block).to eq(expected)
41
41
  end
42
42
  end
43
43
 
@@ -55,6 +55,10 @@ describe Danica do
55
55
  end.new
56
56
  end
57
57
 
58
+ it do
59
+ expect(result).to be_a(Danica::Function)
60
+ end
61
+
58
62
  it 'returns the expected function with variables' do
59
63
  expect(result.variables_hash).to eq(function.variables_hash)
60
64
  end
@@ -76,7 +80,7 @@ describe Danica do
76
80
  end
77
81
 
78
82
  it 'wrap object with negative' do
79
- expect(result).to eq(expected)
83
+ expect(result.expression_block).to eq(expected)
80
84
  end
81
85
 
82
86
  context 'for a number' do
@@ -89,7 +93,7 @@ describe Danica do
89
93
  end
90
94
 
91
95
  it 'wrap object with negative' do
92
- expect(result).to eq(expected)
96
+ expect(result.expression_block).to eq(expected)
93
97
  end
94
98
  end
95
99
  end
@@ -0,0 +1,7 @@
1
+ class MyFunction < Danica::Function
2
+ variables :x, :y
3
+
4
+ def function_block
5
+ x ** 2 + y
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ module Danica
2
+ class Function::Spatial < Function
3
+ variables :time, :acceleration, :initial_space, :initial_velocity
4
+
5
+ private
6
+
7
+ def function_block
8
+ @function_block ||= addition(parcels)
9
+ end
10
+
11
+ def parcels
12
+ [
13
+ initial_space,
14
+ spatial_velocity,
15
+ spatial_acceleration
16
+ ]
17
+ end
18
+
19
+ def spatial_velocity
20
+ multiplication(initial_velocity, time)
21
+ end
22
+
23
+ def spatial_acceleration
24
+ division(multiplication(acceleration, time_squared), 2)
25
+ end
26
+
27
+ def time_squared
28
+ power(time, 2)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ class Danica::Operator::Inverse < Danica::Operator
2
+ variables :value
3
+
4
+ def to_f
5
+ value.to_f ** -1 #Do not worry with nil value as this has been implemented already raising Danica::Exception::NotDefined
6
+ end
7
+
8
+ def to_tex
9
+ "(#{value.to_tex})^{-1}"
10
+ end
11
+
12
+ def to_gnu
13
+ "(#{value.to_gnu}) ** -1"
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ class MyOperator < Danica::Operator
2
+ variables :x
3
+
4
+ def to_f
5
+ (x ** Danica::PI).to_f
6
+ end
7
+
8
+ def to_tex
9
+ "#{x.to_tex}^{\\pi}"
10
+ end
11
+
12
+ def to_gnu
13
+ "#{x.to_tex}**(pi)"
14
+ end
15
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: danica
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darthjee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-19 00:00:00.000000000 Z
11
+ date: 2017-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -179,6 +179,11 @@ files:
179
179
  - spec/integration/negative_spec.rb
180
180
  - spec/integration/plus_minus_spec.rb
181
181
  - spec/integration/power_spec.rb
182
+ - spec/integration/readme/danica_spec.rb
183
+ - spec/integration/readme/equation_spec.rb
184
+ - spec/integration/readme/expression_spec.rb
185
+ - spec/integration/readme/function_spec.rb
186
+ - spec/integration/readme/operator_spec.rb
182
187
  - spec/lib/danica/common_spec.rb
183
188
  - spec/lib/danica/dsl_spec.rb
184
189
  - spec/lib/danica/equation_spec.rb
@@ -210,6 +215,10 @@ files:
210
215
  - spec/support/models/expression/hyperbole.rb
211
216
  - spec/support/models/expression/spatial.rb
212
217
  - spec/support/models/function/hyperbole.rb
218
+ - spec/support/models/function/my_function.rb
219
+ - spec/support/models/function/spatial.rb
220
+ - spec/support/models/operator/inverse.rb
221
+ - spec/support/models/operator/my_operator.rb
213
222
  - spec/support/models/variables_holder/dummy.rb
214
223
  - spec/support/shared_contexts/common.rb
215
224
  - spec/support/shared_examples/base_operations.rb
@@ -247,6 +256,11 @@ test_files:
247
256
  - spec/integration/negative_spec.rb
248
257
  - spec/integration/plus_minus_spec.rb
249
258
  - spec/integration/power_spec.rb
259
+ - spec/integration/readme/danica_spec.rb
260
+ - spec/integration/readme/equation_spec.rb
261
+ - spec/integration/readme/expression_spec.rb
262
+ - spec/integration/readme/function_spec.rb
263
+ - spec/integration/readme/operator_spec.rb
250
264
  - spec/lib/danica/common_spec.rb
251
265
  - spec/lib/danica/dsl_spec.rb
252
266
  - spec/lib/danica/equation_spec.rb
@@ -278,6 +292,10 @@ test_files:
278
292
  - spec/support/models/expression/hyperbole.rb
279
293
  - spec/support/models/expression/spatial.rb
280
294
  - spec/support/models/function/hyperbole.rb
295
+ - spec/support/models/function/my_function.rb
296
+ - spec/support/models/function/spatial.rb
297
+ - spec/support/models/operator/inverse.rb
298
+ - spec/support/models/operator/my_operator.rb
281
299
  - spec/support/models/variables_holder/dummy.rb
282
300
  - spec/support/shared_contexts/common.rb
283
301
  - spec/support/shared_examples/base_operations.rb