danica 2.4.4 → 2.5.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/lib/danica.rb +3 -0
- data/lib/danica/equation.rb +17 -0
- data/lib/danica/expressable.rb +39 -0
- data/lib/danica/expression.rb +14 -0
- data/lib/danica/{function → expression}/gauss.rb +1 -1
- data/lib/danica/function.rb +14 -62
- data/lib/danica/operator.rb +3 -1
- data/lib/danica/variables_holder.rb +35 -2
- data/lib/danica/variables_holder/alias_builder.rb +20 -0
- data/lib/danica/variables_holder/calculator.rb +45 -0
- data/lib/danica/variables_holder/variables_builder.rb +1 -7
- data/lib/danica/version.rb +1 -1
- data/lib/danica/wrapper/container.rb +2 -1
- data/spec/lib/danica/equation_spec.rb +30 -0
- data/spec/lib/danica/expressable_spec.rb +35 -0
- data/spec/lib/danica/{function → expression}/gauss_spec.rb +1 -1
- data/spec/lib/danica/expression_spec.rb +366 -0
- data/spec/lib/danica/function_spec.rb +38 -258
- data/spec/lib/danica/variables_holder_spec.rb +198 -13
- data/spec/support/models/{functions → expression}/baskara.rb +1 -1
- data/spec/support/models/{functions → expression}/hyperbole.rb +2 -2
- data/spec/support/models/{functions → expression}/spatial.rb +1 -1
- data/spec/support/models/function/hyperbole.rb +16 -0
- data/spec/support/models/variables_holder/dummy.rb +34 -0
- metadata +27 -12
@@ -0,0 +1,366 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples 'a generically generated expression' do
|
4
|
+
it 'returns a expression class' do
|
5
|
+
expect(expression.class.superclass).to eq(described_class)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns a class whose instance responds to the variables' do
|
9
|
+
variables.each do |variable|
|
10
|
+
expect(expression).to respond_to(variable)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'returns a expression that uses the block to process to_tex' do
|
15
|
+
expect(expression.to_tex).to eq('x^{y}')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns a expression that uses the block to process to_gnu' do
|
19
|
+
expect(expression.to_gnu).to eq('x**(y)')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns a expression thtat knows how to calculate' do
|
23
|
+
expect(expression.calculate(x: 2, y: 3)).to eq(8)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe Danica::Expression do
|
28
|
+
let(:variables) { %i(x y) }
|
29
|
+
let(:expression_class) do
|
30
|
+
described_class.build(*variables) do
|
31
|
+
Danica::Operator::Power.new(x, y)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
subject { expression }
|
35
|
+
|
36
|
+
describe '.build' do
|
37
|
+
let(:expression) do
|
38
|
+
expression_class.new
|
39
|
+
end
|
40
|
+
it_behaves_like 'an object with basic operation'
|
41
|
+
it_behaves_like 'an object that respond to basic_methods'
|
42
|
+
it_behaves_like 'a generically generated expression'
|
43
|
+
|
44
|
+
context 'when no block is given' do
|
45
|
+
let(:expression_class) do
|
46
|
+
described_class.build(*variables)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns a expression class' do
|
50
|
+
expect(expression_class.superclass).to eq(described_class)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when creating a class using build' do
|
55
|
+
let(:expression_class) { Danica::Hyperbole }
|
56
|
+
|
57
|
+
it_behaves_like 'an object with basic operation'
|
58
|
+
it_behaves_like 'an object that respond to basic_methods'
|
59
|
+
it 'has the defined variables on class definition' do
|
60
|
+
expect(expression_class.variables_names).to eq([:x])
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'has the defined variables' do
|
64
|
+
expect(expression.variables_hash).to eq(x: Danica::Wrapper::Variable.new(name: :x))
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when calling to_tex' do
|
68
|
+
it 'build expression from block' do
|
69
|
+
expect(expression.to_tex).to eq('x^{2}')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when calling to_gnu' do
|
74
|
+
it 'build expression from block' do
|
75
|
+
expect(expression.to_gnu).to eq('x**(2)')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when using a class that inherits from another class' do
|
81
|
+
let(:expression_class) { Danica::SaddleHyperbole }
|
82
|
+
|
83
|
+
it_behaves_like 'an object with basic operation'
|
84
|
+
it_behaves_like 'an object that respond to basic_methods'
|
85
|
+
|
86
|
+
it 'has the defined variables on class definition' do
|
87
|
+
expect(expression_class.variables_names).to eq([:x, :y])
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'has the defined variables' do
|
91
|
+
expect(expression.variables_hash).to eq(
|
92
|
+
x: Danica::Wrapper::Variable.new(name: :x),
|
93
|
+
y: Danica::Wrapper::Variable.new(name: :y)
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when calling to_tex' do
|
98
|
+
it 'build expression from block' do
|
99
|
+
expect(expression.to_tex).to eq('x^{2} -y^{2}')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when calling to_gnu' do
|
104
|
+
it 'build expression from block' do
|
105
|
+
expect(expression.to_gnu).to eq('x**(2) -y**(2)')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '.create' do
|
112
|
+
let(:expression) do
|
113
|
+
described_class.create(*variables) do
|
114
|
+
Danica::Operator::Power.new(x, y)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
it_behaves_like 'an object with basic operation'
|
118
|
+
it_behaves_like 'an object that respond to basic_methods'
|
119
|
+
it_behaves_like 'a generically generated expression'
|
120
|
+
end
|
121
|
+
|
122
|
+
describe 'spatial' do
|
123
|
+
let(:variables) do
|
124
|
+
{
|
125
|
+
time: :t,
|
126
|
+
acceleration: 'a',
|
127
|
+
initial_space: { name: :S0, latex: 'S_0' },
|
128
|
+
initial_velocity: { name: :V0, latex: 'V_0' }
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
subject { described_class::Spatial.new(variables) }
|
133
|
+
it_behaves_like 'an object with basic operation'
|
134
|
+
it_behaves_like 'an object that respond to basic_methods'
|
135
|
+
|
136
|
+
describe '#to_tex' do
|
137
|
+
context 'when creating the spatial operator for constantly accelerated movement' do
|
138
|
+
let(:expected) { 'S_0 + V_0 \cdot t + \frac{a \cdot t^{2}}{2}' }
|
139
|
+
|
140
|
+
it 'return the latex format CAM' do
|
141
|
+
expect(subject.to_tex).to eq(expected)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#to_gnu' do
|
147
|
+
context 'when creating the spatial operator for constantly accelerated movement' do
|
148
|
+
let(:expected) { 'S0 + V0 * t + (a * t**(2))/(2)' }
|
149
|
+
|
150
|
+
it 'return the latex format CAM' do
|
151
|
+
expect(subject.to_gnu).to eq(expected)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe '#variables_hash' do
|
157
|
+
let(:expected) do
|
158
|
+
{
|
159
|
+
time: Danica::Wrapper::Variable.new(name: :t),
|
160
|
+
acceleration: Danica::Wrapper::Variable.new(name: 'a'),
|
161
|
+
initial_space: Danica::Wrapper::Variable.new( name: :S0, latex: 'S_0' ),
|
162
|
+
initial_velocity: Danica::Wrapper::Variable.new( name: :V0, latex: 'V_0' )
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'when variables are already wrapped with Danica::Wrapper::Variable' do
|
167
|
+
let(:variables) { expected }
|
168
|
+
it 'returns a hash with the variabels' do
|
169
|
+
expect(subject.variables_hash).to eq(expected)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'when variables have been defined with string name' do
|
174
|
+
before do
|
175
|
+
variables.change_keys!(&:to_s)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'returns a hash with the variabels' do
|
179
|
+
expect(subject.variables_hash).to eq(expected)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'when variables are not wrapped yet' do
|
184
|
+
it 'returns a hash with the variabels' do
|
185
|
+
expect(subject.variables_hash).to eq(expected)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'when changing a variable' do
|
190
|
+
before do
|
191
|
+
subject.time = :x
|
192
|
+
expected[:time] = Danica::Wrapper::Variable.new(name: :x)
|
193
|
+
end
|
194
|
+
|
195
|
+
it do
|
196
|
+
expect(subject.variables_hash).to eq(expected)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'when initializing with array' do
|
201
|
+
context 'as hash' do
|
202
|
+
let(:variables) { [ :t, 'a', {name: :S0, latex: 'S_0'}, { name: :V0, latex: 'V_0' } ] }
|
203
|
+
subject { described_class::Spatial.new(variables) }
|
204
|
+
|
205
|
+
it 'returns a hash with the variabels' do
|
206
|
+
expect(subject.variables_hash).to eq(expected)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context 'when initializing with sequence' do
|
212
|
+
context 'as hash' do
|
213
|
+
let(:variables) { [ :t, 'a', {name: :S0, latex: 'S_0'}, { name: :V0, latex: 'V_0' } ] }
|
214
|
+
subject { described_class::Spatial.new(*variables, {}) }
|
215
|
+
|
216
|
+
it 'returns a hash with the variabels' do
|
217
|
+
expect(subject.variables_hash).to eq(expected)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context 'when initializing with variables array' do
|
223
|
+
context 'as hash' do
|
224
|
+
let(:variables) { [ :t, 'a', {name: :S0, latex: 'S_0'}, { name: :V0, latex: 'V_0' } ] }
|
225
|
+
subject { described_class::Spatial.new(variables: variables) }
|
226
|
+
|
227
|
+
it 'returns a hash with the variabels' do
|
228
|
+
expect(subject.variables_hash).to eq(expected)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe '#variables' do
|
235
|
+
context 'when initialized with an array of variables' do
|
236
|
+
subject { described_class::Spatial.new(variables: variables.values) }
|
237
|
+
let(:expected) { variables.values.map { |v| Danica::Wrapper::Variable.new(v.is_a?(Hash) ? v : { name: v }) } }
|
238
|
+
it do
|
239
|
+
expect(subject.variables.compact).to eq(expected)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'when not initializing all variables' do
|
244
|
+
subject { described_class::Spatial.new }
|
245
|
+
let(:time) { Danica::Wrapper::Variable.new(name: :t) }
|
246
|
+
|
247
|
+
context 'when initialized with an empty variable set' do
|
248
|
+
it do
|
249
|
+
expect(subject.variables.compact).not_to be_empty
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
context 'when changing a variable' do
|
254
|
+
before do
|
255
|
+
subject.time = time
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'returns the list of variables merged default and new variables' do
|
259
|
+
expect(subject.variables.compact).to eq([
|
260
|
+
time,
|
261
|
+
Danica::Wrapper::Variable.new(name: :acceleration),
|
262
|
+
Danica::Wrapper::Variable.new(name: :initial_space),
|
263
|
+
Danica::Wrapper::Variable.new(name: :initial_velocity)
|
264
|
+
])
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context 'when initializing with a variable set' do
|
269
|
+
let(:names) { [ :t, :a, :s0, :v0 ] }
|
270
|
+
subject { described_class::Spatial.new *names }
|
271
|
+
|
272
|
+
it 'returns the variables given oin initialization' do
|
273
|
+
expect(subject.variables.map(&:name)).to eq(names)
|
274
|
+
end
|
275
|
+
|
276
|
+
context 'when initializing variables with a hash out of order' do
|
277
|
+
let(:variables) do
|
278
|
+
{
|
279
|
+
initial_velocity: :v0,
|
280
|
+
initial_space: :s0,
|
281
|
+
acceleration: :a,
|
282
|
+
time: :t
|
283
|
+
}
|
284
|
+
end
|
285
|
+
subject { described_class::Spatial.new variables }
|
286
|
+
|
287
|
+
it 'returns the variables given on initialization' do
|
288
|
+
expect(subject.variables.map(&:name)).to eq(names)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
describe '#calculate' do
|
296
|
+
context 'when all variables have value' do
|
297
|
+
let(:time_value) { 2 }
|
298
|
+
let(:time) { time_value }
|
299
|
+
let(:acceleration) { 3 }
|
300
|
+
let(:initial_space) { 1 }
|
301
|
+
let(:initial_velocity) { 1 }
|
302
|
+
subject { described_class::Spatial.new(time, acceleration, initial_space, initial_velocity) }
|
303
|
+
let(:expected) { initial_space + initial_velocity * time_value + acceleration * (time_value ** 2) / 2.0 }
|
304
|
+
|
305
|
+
it 'retuirns the calculated value' do
|
306
|
+
expect(subject.calculate).to eq(expected)
|
307
|
+
end
|
308
|
+
|
309
|
+
context 'when not all variables have value' do
|
310
|
+
let(:time) { :t }
|
311
|
+
|
312
|
+
it do
|
313
|
+
expect { subject.calculate }.to raise_error(Danica::Exception::NotDefined)
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'but calling calculate with a value for the variables' do
|
317
|
+
it 'calculate using the given value' do
|
318
|
+
expect(subject.calculate(time_value)).to eq(expected)
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'does not change the values of then valued variables' do
|
322
|
+
expect do
|
323
|
+
subject.calculate(time_value)
|
324
|
+
end.not_to change(subject.time, :valued?)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context 'when calling with a hash for the values' do
|
329
|
+
it 'calculate using the given value' do
|
330
|
+
expect(subject.calculate(time: time_value)).to eq(expected)
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'does not change the values of then valued variables' do
|
334
|
+
expect do
|
335
|
+
subject.calculate(time: time_value)
|
336
|
+
end.not_to change(subject.time, :valued?)
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
describe 'baskara' do
|
345
|
+
context 'when using the default value for variables' do
|
346
|
+
subject { described_class::Baskara.new }
|
347
|
+
it_behaves_like 'an object that respond to basic_methods'
|
348
|
+
|
349
|
+
describe '#to_tex' do
|
350
|
+
let(:expected) { '\frac{-b \pm \sqrt{b^{2} -4 \cdot a \cdot c}}{2 \cdot a}' }
|
351
|
+
|
352
|
+
it 'return the latex format CAM' do
|
353
|
+
expect(subject.to_tex).to eq(expected)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
describe '#to_gnu' do
|
358
|
+
let(:expected) { '(-b + sqrt(b**(2) -4 * a * c))/(2 * a)' }
|
359
|
+
|
360
|
+
it 'return the gnu format CAM' do
|
361
|
+
expect(subject.to_gnu).to eq(expected)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
@@ -12,11 +12,11 @@ shared_examples 'a generically generated function' do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'returns a function that uses the block to process to_tex' do
|
15
|
-
expect(function.to_tex).to eq('x^{y}')
|
15
|
+
expect(function.to_tex).to eq('f(x, y) = x^{y}')
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'returns a function that uses the block to process to_gnu' do
|
19
|
-
expect(function.to_gnu).to eq('x**(y)')
|
19
|
+
expect(function.to_gnu).to eq('f(x, y) = x**(y)')
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'returns a function thtat knows how to calculate' do
|
@@ -25,6 +25,8 @@ shared_examples 'a generically generated function' do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
describe Danica::Function do
|
28
|
+
subject { function }
|
29
|
+
let(:function) { function_class.new }
|
28
30
|
let(:variables) { %i(x y) }
|
29
31
|
let(:function_class) do
|
30
32
|
described_class.build(*variables) do
|
@@ -34,7 +36,7 @@ describe Danica::Function do
|
|
34
36
|
|
35
37
|
describe '.build' do
|
36
38
|
let(:function) do
|
37
|
-
function_class.new
|
39
|
+
function_class.new(name: :f)
|
38
40
|
end
|
39
41
|
|
40
42
|
it_behaves_like 'a generically generated function'
|
@@ -50,7 +52,7 @@ describe Danica::Function do
|
|
50
52
|
end
|
51
53
|
|
52
54
|
context 'when creating a class using build' do
|
53
|
-
let(:function_class) { Danica::Hyperbole }
|
55
|
+
let(:function_class) { Danica::Function::Hyperbole }
|
54
56
|
|
55
57
|
it 'has the defined variables on class definition' do
|
56
58
|
expect(function_class.variables_names).to eq([:x])
|
@@ -62,19 +64,19 @@ describe Danica::Function do
|
|
62
64
|
|
63
65
|
context 'when calling to_tex' do
|
64
66
|
it 'build function from block' do
|
65
|
-
expect(function.to_tex).to eq('x^{2}')
|
67
|
+
expect(function.to_tex).to eq('f(x) = x^{2}')
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
69
71
|
context 'when calling to_gnu' do
|
70
72
|
it 'build function from block' do
|
71
|
-
expect(function.to_gnu).to eq('x**(2)')
|
73
|
+
expect(function.to_gnu).to eq('f(x) = x**(2)')
|
72
74
|
end
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
76
78
|
context 'when using a class that inherits from another class' do
|
77
|
-
let(:function_class) { Danica::SaddleHyperbole }
|
79
|
+
let(:function_class) { Danica::Function::SaddleHyperbole }
|
78
80
|
|
79
81
|
it 'has the defined variables on class definition' do
|
80
82
|
expect(function_class.variables_names).to eq([:x, :y])
|
@@ -89,13 +91,13 @@ describe Danica::Function do
|
|
89
91
|
|
90
92
|
context 'when calling to_tex' do
|
91
93
|
it 'build function from block' do
|
92
|
-
expect(function.to_tex).to eq('x^{2} -y^{2}')
|
94
|
+
expect(function.to_tex).to eq('f(x, y) = x^{2} -y^{2}')
|
93
95
|
end
|
94
96
|
end
|
95
97
|
|
96
98
|
context 'when calling to_gnu' do
|
97
99
|
it 'build function from block' do
|
98
|
-
expect(function.to_gnu).to eq('x**(2) -y**(2)')
|
100
|
+
expect(function.to_gnu).to eq('f(x, y) = x**(2) -y**(2)')
|
99
101
|
end
|
100
102
|
end
|
101
103
|
end
|
@@ -105,6 +107,8 @@ describe Danica::Function do
|
|
105
107
|
let(:function) do
|
106
108
|
described_class.create(*variables) do
|
107
109
|
Danica::Operator::Power.new(x, y)
|
110
|
+
end.tap do |f|
|
111
|
+
f.name = :f
|
108
112
|
end
|
109
113
|
end
|
110
114
|
it_behaves_like 'a generically generated function'
|
@@ -116,7 +120,7 @@ describe Danica::Function do
|
|
116
120
|
end
|
117
121
|
|
118
122
|
it do
|
119
|
-
expect(function.name).to be_a(Danica::Function::Name)
|
123
|
+
expect(function.name.content).to be_a(Danica::Function::Name)
|
120
124
|
end
|
121
125
|
|
122
126
|
context 'when changing the function variables' do
|
@@ -128,21 +132,21 @@ describe Danica::Function do
|
|
128
132
|
end
|
129
133
|
end
|
130
134
|
|
131
|
-
describe '#
|
135
|
+
describe '#to_tex' do
|
132
136
|
context 'when function has a name' do
|
133
137
|
let(:function) do
|
134
138
|
function_class.new(name: :f)
|
135
139
|
end
|
136
140
|
|
137
141
|
it 'returns the full function description' do
|
138
|
-
expect(function.
|
142
|
+
expect(function.to_tex).to eq('f(x, y) = x^{y}')
|
139
143
|
end
|
140
144
|
|
141
145
|
context 'and one of the variables is changed' do
|
142
146
|
it 'uses the new variable value' do
|
143
147
|
expect do
|
144
148
|
function.y = 2
|
145
|
-
end.to change(function, :
|
149
|
+
end.to change(function, :to_tex).to('f(x, 2) = x^{2}')
|
146
150
|
end
|
147
151
|
end
|
148
152
|
end
|
@@ -153,7 +157,7 @@ describe Danica::Function do
|
|
153
157
|
end
|
154
158
|
|
155
159
|
it 'ignores the constant in the definition' do
|
156
|
-
expect(function.
|
160
|
+
expect(function.to_tex).to eq('f(y) = \pi^{y}')
|
157
161
|
end
|
158
162
|
|
159
163
|
context 'from a hash' do
|
@@ -162,7 +166,7 @@ describe Danica::Function do
|
|
162
166
|
end
|
163
167
|
|
164
168
|
it 'ignores the constant in the definition' do
|
165
|
-
expect(function.
|
169
|
+
expect(function.to_tex).to eq('f(y) = \pi^{y}')
|
166
170
|
end
|
167
171
|
end
|
168
172
|
end
|
@@ -173,7 +177,7 @@ describe Danica::Function do
|
|
173
177
|
end
|
174
178
|
|
175
179
|
it 'sohws the variable as number' do
|
176
|
-
expect(function.
|
180
|
+
expect(function.to_tex).to eq('f(2, y) = 2^{y}')
|
177
181
|
end
|
178
182
|
end
|
179
183
|
|
@@ -183,19 +187,19 @@ describe Danica::Function do
|
|
183
187
|
end
|
184
188
|
|
185
189
|
it 'sohws the variable as number' do
|
186
|
-
expect(function.
|
190
|
+
expect(function.to_tex).to eq('f(2, y) = 2^{y}')
|
187
191
|
end
|
188
192
|
end
|
189
193
|
end
|
190
194
|
|
191
|
-
describe '#
|
195
|
+
describe '#to_gnu' do
|
192
196
|
context 'when function has a name' do
|
193
197
|
let(:function) do
|
194
198
|
function_class.new(name: :f)
|
195
199
|
end
|
196
200
|
|
197
201
|
it 'returns the full function description' do
|
198
|
-
expect(function.
|
202
|
+
expect(function.to_gnu).to eq('f(x, y) = x**(y)')
|
199
203
|
end
|
200
204
|
end
|
201
205
|
|
@@ -205,7 +209,7 @@ describe Danica::Function do
|
|
205
209
|
end
|
206
210
|
|
207
211
|
it 'ignores the constant in the definition' do
|
208
|
-
expect(function.
|
212
|
+
expect(function.to_gnu).to eq('f(y) = pi**(y)')
|
209
213
|
end
|
210
214
|
|
211
215
|
context 'from a hash' do
|
@@ -214,7 +218,7 @@ describe Danica::Function do
|
|
214
218
|
end
|
215
219
|
|
216
220
|
it 'ignores the constant in the definition' do
|
217
|
-
expect(function.
|
221
|
+
expect(function.to_gnu).to eq('f(y) = pi**(y)')
|
218
222
|
end
|
219
223
|
end
|
220
224
|
end
|
@@ -225,7 +229,7 @@ describe Danica::Function do
|
|
225
229
|
end
|
226
230
|
|
227
231
|
it 'sohws the variable as number' do
|
228
|
-
expect(function.
|
232
|
+
expect(function.to_gnu).to eq('f(2, y) = 2**(y)')
|
229
233
|
end
|
230
234
|
end
|
231
235
|
|
@@ -235,251 +239,27 @@ describe Danica::Function do
|
|
235
239
|
end
|
236
240
|
|
237
241
|
it 'sohws the variable as number' do
|
238
|
-
expect(function.
|
242
|
+
expect(function.to_gnu).to eq('f(2, y) = 2**(y)')
|
239
243
|
end
|
240
244
|
end
|
241
|
-
end
|
242
|
-
|
243
|
-
describe 'spatial' do
|
244
|
-
let(:variables) do
|
245
|
-
{
|
246
|
-
time: :t,
|
247
|
-
acceleration: 'a',
|
248
|
-
initial_space: { name: :S0, latex: 'S_0' },
|
249
|
-
initial_velocity: { name: :V0, latex: 'V_0' }
|
250
|
-
}
|
251
|
-
end
|
252
|
-
|
253
|
-
subject { described_class::Spatial.new(variables) }
|
254
|
-
it_behaves_like 'an object that respond to basic_methods'
|
255
245
|
|
256
|
-
describe '#
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
it 'return the latex format CAM' do
|
261
|
-
expect(subject.to_tex).to eq(expected)
|
262
|
-
end
|
246
|
+
describe '#left' do
|
247
|
+
it 'is an alias for name' do
|
248
|
+
expect(subject.left).to eq(subject.name)
|
263
249
|
end
|
264
250
|
end
|
265
251
|
|
266
|
-
describe '#
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
expect(subject.to_gnu).to eq(expected)
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
describe '#variables_hash' do
|
277
|
-
let(:expected) do
|
278
|
-
{
|
279
|
-
time: Danica::Wrapper::Variable.new(name: :t),
|
280
|
-
acceleration: Danica::Wrapper::Variable.new(name: 'a'),
|
281
|
-
initial_space: Danica::Wrapper::Variable.new( name: :S0, latex: 'S_0' ),
|
282
|
-
initial_velocity: Danica::Wrapper::Variable.new( name: :V0, latex: 'V_0' )
|
283
|
-
}
|
284
|
-
end
|
285
|
-
|
286
|
-
context 'when variables are already wrapped with Danica::Wrapper::Variable' do
|
287
|
-
let(:variables) { expected }
|
288
|
-
it 'returns a hash with the variabels' do
|
289
|
-
expect(subject.variables_hash).to eq(expected)
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
context 'when variables have been defined with string name' do
|
294
|
-
before do
|
295
|
-
variables.change_keys!(&:to_s)
|
296
|
-
end
|
297
|
-
|
298
|
-
it 'returns a hash with the variabels' do
|
299
|
-
expect(subject.variables_hash).to eq(expected)
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
context 'when variables are not wrapped yet' do
|
304
|
-
it 'returns a hash with the variabels' do
|
305
|
-
expect(subject.variables_hash).to eq(expected)
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
context 'when changing a variable' do
|
310
|
-
before do
|
311
|
-
subject.time = :x
|
312
|
-
expected[:time] = Danica::Wrapper::Variable.new(name: :x)
|
313
|
-
end
|
314
|
-
|
315
|
-
it do
|
316
|
-
expect(subject.variables_hash).to eq(expected)
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
context 'when initializing with array' do
|
321
|
-
context 'as hash' do
|
322
|
-
let(:variables) { [ :t, 'a', {name: :S0, latex: 'S_0'}, { name: :V0, latex: 'V_0' } ] }
|
323
|
-
subject { described_class::Spatial.new(variables) }
|
324
|
-
|
325
|
-
it 'returns a hash with the variabels' do
|
326
|
-
expect(subject.variables_hash).to eq(expected)
|
327
|
-
end
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
|
-
context 'when initializing with sequence' do
|
332
|
-
context 'as hash' do
|
333
|
-
let(:variables) { [ :t, 'a', {name: :S0, latex: 'S_0'}, { name: :V0, latex: 'V_0' } ] }
|
334
|
-
subject { described_class::Spatial.new(*variables, {}) }
|
335
|
-
|
336
|
-
it 'returns a hash with the variabels' do
|
337
|
-
expect(subject.variables_hash).to eq(expected)
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
context 'when initializing with variables array' do
|
343
|
-
context 'as hash' do
|
344
|
-
let(:variables) { [ :t, 'a', {name: :S0, latex: 'S_0'}, { name: :V0, latex: 'V_0' } ] }
|
345
|
-
subject { described_class::Spatial.new(variables: variables) }
|
346
|
-
|
347
|
-
it 'returns a hash with the variabels' do
|
348
|
-
expect(subject.variables_hash).to eq(expected)
|
349
|
-
end
|
350
|
-
end
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
describe '#variables' do
|
355
|
-
context 'when initialized with an array of variables' do
|
356
|
-
subject { described_class::Spatial.new(variables: variables.values) }
|
357
|
-
let(:expected) { variables.values.map { |v| Danica::Wrapper::Variable.new(v.is_a?(Hash) ? v : { name: v }) } }
|
358
|
-
it do
|
359
|
-
expect(subject.variables.compact).to eq(expected)
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
context 'when not initializing all variables' do
|
364
|
-
subject { described_class::Spatial.new }
|
365
|
-
let(:time) { Danica::Wrapper::Variable.new(name: :t) }
|
366
|
-
|
367
|
-
context 'when initialized with an empty variable set' do
|
368
|
-
it do
|
369
|
-
expect(subject.variables.compact).not_to be_empty
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
context 'when changing a variable' do
|
374
|
-
before do
|
375
|
-
subject.time = time
|
376
|
-
end
|
377
|
-
|
378
|
-
it 'returns the list of variables merged default and new variables' do
|
379
|
-
expect(subject.variables.compact).to eq([
|
380
|
-
time,
|
381
|
-
Danica::Wrapper::Variable.new(name: :acceleration),
|
382
|
-
Danica::Wrapper::Variable.new(name: :initial_space),
|
383
|
-
Danica::Wrapper::Variable.new(name: :initial_velocity)
|
384
|
-
])
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
context 'when initializing with a variable set' do
|
389
|
-
let(:names) { [ :t, :a, :s0, :v0 ] }
|
390
|
-
subject { described_class::Spatial.new *names }
|
391
|
-
|
392
|
-
it 'returns the variables given oin initialization' do
|
393
|
-
expect(subject.variables.map(&:name)).to eq(names)
|
394
|
-
end
|
395
|
-
|
396
|
-
context 'when initializing variables with a hash out of order' do
|
397
|
-
let(:variables) do
|
398
|
-
{
|
399
|
-
initial_velocity: :v0,
|
400
|
-
initial_space: :s0,
|
401
|
-
acceleration: :a,
|
402
|
-
time: :t
|
403
|
-
}
|
404
|
-
end
|
405
|
-
subject { described_class::Spatial.new variables }
|
406
|
-
|
407
|
-
it 'returns the variables given on initialization' do
|
408
|
-
expect(subject.variables.map(&:name)).to eq(names)
|
409
|
-
end
|
410
|
-
end
|
411
|
-
end
|
412
|
-
end
|
413
|
-
end
|
414
|
-
|
415
|
-
describe '#calculate' do
|
416
|
-
context 'when all variables have value' do
|
417
|
-
let(:time_value) { 2 }
|
418
|
-
let(:time) { time_value }
|
419
|
-
let(:acceleration) { 3 }
|
420
|
-
let(:initial_space) { 1 }
|
421
|
-
let(:initial_velocity) { 1 }
|
422
|
-
subject { described_class::Spatial.new(time, acceleration, initial_space, initial_velocity) }
|
423
|
-
let(:expected) { initial_space + initial_velocity * time_value + acceleration * (time_value ** 2) / 2.0 }
|
424
|
-
|
425
|
-
it 'retuirns the calculated value' do
|
426
|
-
expect(subject.calculate).to eq(expected)
|
427
|
-
end
|
428
|
-
|
429
|
-
context 'when not all variables have value' do
|
430
|
-
let(:time) { :t }
|
431
|
-
|
432
|
-
it do
|
433
|
-
expect { subject.calculate }.to raise_error(Danica::Exception::NotDefined)
|
434
|
-
end
|
435
|
-
|
436
|
-
context 'but calling calculate with a value for the variables' do
|
437
|
-
it 'calculate using the given value' do
|
438
|
-
expect(subject.calculate(time_value)).to eq(expected)
|
439
|
-
end
|
440
|
-
|
441
|
-
it 'does not change the values of then valued variables' do
|
442
|
-
expect do
|
443
|
-
subject.calculate(time_value)
|
444
|
-
end.not_to change(subject.time, :valued?)
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
context 'when calling with a hash for the values' do
|
449
|
-
it 'calculate using the given value' do
|
450
|
-
expect(subject.calculate(time: time_value)).to eq(expected)
|
451
|
-
end
|
452
|
-
|
453
|
-
it 'does not change the values of then valued variables' do
|
454
|
-
expect do
|
455
|
-
subject.calculate(time: time_value)
|
456
|
-
end.not_to change(subject.time, :valued?)
|
457
|
-
end
|
458
|
-
end
|
459
|
-
end
|
252
|
+
describe '#left=' do
|
253
|
+
it 'is an alias for the expression' do
|
254
|
+
expect do
|
255
|
+
subject.left = Danica::Operator::Power.new(:x, 2)
|
256
|
+
end.to change { subject.left.content }
|
460
257
|
end
|
461
258
|
end
|
462
|
-
end
|
463
|
-
|
464
|
-
describe 'baskara' do
|
465
|
-
context 'when using the default value for variables' do
|
466
|
-
subject { described_class::Baskara.new }
|
467
|
-
it_behaves_like 'an object that respond to basic_methods'
|
468
|
-
|
469
|
-
describe '#to_tex' do
|
470
|
-
let(:expected) { '\frac{-b \pm \sqrt{b^{2} -4 \cdot a \cdot c}}{2 \cdot a}' }
|
471
|
-
|
472
|
-
it 'return the latex format CAM' do
|
473
|
-
expect(subject.to_tex).to eq(expected)
|
474
|
-
end
|
475
|
-
end
|
476
259
|
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
it 'return the gnu format CAM' do
|
481
|
-
expect(subject.to_gnu).to eq(expected)
|
482
|
-
end
|
260
|
+
describe '#right' do
|
261
|
+
it 'is an alias for the expression' do
|
262
|
+
expect(subject.right).to eq(subject.right)
|
483
263
|
end
|
484
264
|
end
|
485
265
|
end
|