danica 2.4.3 → 2.4.4

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: 88c93cc9b46fa1f9ced587a49535bc0eeec427cc
4
- data.tar.gz: af6ae43ee59d5b15f204203f2a56c6978fec5125
3
+ metadata.gz: 7e650cc12cd4ccaaf7eaebd6f8084ae46211f0cf
4
+ data.tar.gz: 7b9cef3c43db7851160e95f6a2700dfde13f5a28
5
5
  SHA512:
6
- metadata.gz: a547b35c6f1d7c14534ab87ee7d1c6a08222cdcbbb166f435276355a99decfe0bcc458e4aef8e4a011ec79203363fc3fc4f8aa22d80cea260c45c45aedd9ce8f
7
- data.tar.gz: 7c168e661e244debbd6e7c68ca0b3acadebb59cc9f9920ce76f6b632ba7c16e6eb102a70259970887477469bbda3cb23a02ef71a3a605e02ef2c902f0880394e
6
+ metadata.gz: 0acaff19e60a377126d74cfa90441098329f19603b7467e208f672e1ba7a95242beed67125028cd8c1979f5fb9b4443b877aa27ec24bf8e421f6f44970f983b3
7
+ data.tar.gz: 3d5be06b0da8ea1569f17354b711ce328f0577b169af1a8a191f6de883d6cbb2b3aab38fe3c2f03511f0f1aa5f72d819146d3bac3107e32364d9e6030d0ace14
@@ -12,6 +12,7 @@ module Danica
12
12
 
13
13
  default_value :constant?, false
14
14
  default_value :signaled?, false
15
+ default_value :container?, false
15
16
  end
16
17
 
17
18
  def to_f
@@ -43,6 +44,10 @@ module Danica
43
44
  false
44
45
  end
45
46
 
47
+ def content
48
+ self
49
+ end
50
+
46
51
  private
47
52
 
48
53
  def wrap_as_group(value)
@@ -4,6 +4,9 @@ module Danica
4
4
  include VariablesHolder
5
5
  include DSL
6
6
 
7
+ autoload :Gauss, 'danica/function/gauss'
8
+ autoload :Name, 'danica/function/name'
9
+
7
10
  attr_accessor :name
8
11
 
9
12
  default_value :priority, 3
@@ -49,7 +52,7 @@ module Danica
49
52
  end
50
53
 
51
54
  def describe(format)
52
- "#{name}(#{description_variables(format)}) = #{to(format)}"
55
+ "#{name.to(format)} = #{to(format)}"
53
56
  end
54
57
 
55
58
  def describe_tex
@@ -60,7 +63,9 @@ module Danica
60
63
  describe(:gnu)
61
64
  end
62
65
 
63
- autoload :Gauss, 'danica/function/gauss'
66
+ def name
67
+ @name_object ||= Name.new(name: @name, variables: containers)
68
+ end
64
69
 
65
70
  private
66
71
 
@@ -0,0 +1,33 @@
1
+ module Danica
2
+ class Function::Name
3
+ include Common
4
+ attr_reader :name, :containers
5
+
6
+ def initialize(name:, variables:)
7
+ @name = name
8
+ @containers = variables.map do |v|
9
+ v = wrap_value(v)
10
+ v = Wrapper::Container.new(v) unless v.container?
11
+ v
12
+ end
13
+ end
14
+
15
+ def to(format)
16
+ "#{name}(#{description_variables(format)})"
17
+ end
18
+
19
+ def variables
20
+ containers.map(&:content)
21
+ end
22
+
23
+ private
24
+
25
+ def description_variables(format)
26
+ non_constant_variables.map { |v| v.to(format) }.join(', ')
27
+ end
28
+
29
+ def non_constant_variables
30
+ variables.reject(&:constant?)
31
+ end
32
+ end
33
+ end
@@ -1,8 +1,6 @@
1
1
  module Danica
2
2
  class Operator
3
3
  class Chained < Operator
4
- attr_reader :variables
5
-
6
4
  def variables=(vars)
7
5
  @variables = vars.map { |v| wrap_value(v) }
8
6
  end
@@ -13,7 +11,7 @@ module Danica
13
11
 
14
12
  def include?(value)
15
13
  value = wrap_value(value)
16
- variables.include?(value)
14
+ variables.include?(value.content)
17
15
  end
18
16
 
19
17
  def to(format)
@@ -21,6 +19,10 @@ module Danica
21
19
  variables.procedural_join(extractor, &join_proc(symbol(format)))
22
20
  end
23
21
 
22
+ def variables
23
+ @variables.map(&:content)
24
+ end
25
+
24
26
  private
25
27
 
26
28
  def symbol(format)
@@ -20,16 +20,28 @@ module Danica
20
20
 
21
21
  def variables=(vars)
22
22
  vars = vars.as_hash(self.class.variables_names).compact unless vars.is_a? Hash
23
- vars = vars.change_values(skip_inner: false) { |v| wrap_value(v) }
24
- @variables_hash = self.class.variables_hash.merge(vars)
23
+ vars = vars.dup.change_values!(skip_inner: false) { |v| wrap_value(v) }
24
+ vars.each do |k, v|
25
+ public_send("#{k}=", v)
26
+ end
25
27
  end
26
28
 
27
29
  def variables
28
- variables_hash.values
30
+ containers.map(&:content)
31
+ end
32
+
33
+ def containers
34
+ containers_hash.values
35
+ end
36
+
37
+ def containers_hash
38
+ @containers_hash ||= {}.merge(self.class.variables_hash.change_values do |value|
39
+ Wrapper::Container.new(value)
40
+ end)
29
41
  end
30
42
 
31
43
  def variables_hash
32
- @variables_hash ||= {}.merge(self.class.variables_hash)
44
+ containers_hash.change_values(&:content)
33
45
  end
34
46
 
35
47
  def variables_value_hash
@@ -30,13 +30,19 @@ module Danica::VariablesHolder
30
30
 
31
31
  def add_setter(name)
32
32
  instance.send(:define_method, "#{name}=") do |value|
33
- variables_hash[name.to_sym] = wrap_value(value)
33
+ if(containers_hash[name.to_sym].try(:container?))
34
+ containers_hash[name.to_sym].content = wrap_value(value)
35
+ else
36
+ value = wrap_value(value)
37
+ value = Danica::Wrapper::Container.new value unless value.container?
38
+ containers_hash[name.to_sym] = value
39
+ end
34
40
  end
35
41
  end
36
42
 
37
43
  def add_reader(name)
38
44
  instance.send(:define_method, name) do
39
- variables_hash[name.to_sym]
45
+ containers_hash[name.to_sym]
40
46
  end
41
47
  end
42
48
  end
@@ -1,3 +1,3 @@
1
1
  module Danica
2
- VERSION = '2.4.3'
2
+ VERSION = '2.4.4'
3
3
  end
@@ -1,27 +1,38 @@
1
1
  module Danica
2
2
  module Wrapper
3
3
  def wrap_value(value)
4
+ Wrapper.wrap_value(value)
5
+ end
6
+
7
+ def self.wrap_value(value)
4
8
  case value
5
9
  when Numeric
6
- return negative(number(-value)) if value < 0
7
- number(value)
10
+ wrap_numeric(value)
8
11
  when Hash
9
- return constant(value) if value.keys.map(&:to_sym).sort == %i(gnu latex value)
10
- variable(value)
11
- when String, Symbol
12
- variable(name: value)
13
- when NilClass
14
- variable
12
+ wrap_hash(value)
13
+ when String, Symbol, NilClass
14
+ Variable.new(name: value)
15
15
  else
16
16
  value
17
17
  end
18
18
  end
19
19
 
20
+ def self.wrap_numeric(number)
21
+ return Negative.new(Number.new(-number)) if number < 0
22
+ Number.new(number)
23
+ end
24
+
25
+ def self.wrap_hash(hash)
26
+ return Constant.new(hash) if hash.keys.map(&:to_sym).sort == %i(gnu latex value)
27
+ Variable.new(hash)
28
+ end
29
+
20
30
  autoload :Number, 'danica/wrapper/number'
21
31
  autoload :Group, 'danica/wrapper/group'
22
32
  autoload :Negative, 'danica/wrapper/negative'
23
33
  autoload :PlusMinus, 'danica/wrapper/plus_minus'
24
34
  autoload :Constant, 'danica/wrapper/constant'
25
35
  autoload :Variable, 'danica/wrapper/variable'
36
+ autoload :Container, 'danica/wrapper/container'
26
37
  end
27
38
  end
@@ -0,0 +1,23 @@
1
+ module Danica
2
+ class Wrapper::Container
3
+ include Common
4
+ attr_accessor :content
5
+
6
+ delegate :to_f, :contentd?, :to, :to_tex, :to_gnu, :priority, :grouped?,
7
+ :signaled?, :constant?, :valued?, :*, :+, :-, :/, :**, to: :content
8
+
9
+ default_value :container?, true
10
+
11
+ def initialize(content)
12
+ @content = content
13
+ end
14
+
15
+ def ==(other)
16
+ return content == other unless other.is_a?(self.class)
17
+ content == other.content
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Danica::Function::Name do
4
+ let(:x) { Danica::Wrapper::Variable.new(name: :x, latex: '\mu', gnu: 'u')}
5
+ let(:subject) { described_class.new(name: :f, variables: [x]) }
6
+
7
+ describe '#to_tex' do
8
+ it 'returns the name of the function with tex variables' do
9
+ expect(subject.to_tex).to eq('f(\mu)')
10
+ end
11
+
12
+ context 'when initializing variables from scratch' do
13
+ let(:x) { :x }
14
+
15
+ it 'returns the name of the function with tex variables' do
16
+ expect(subject.to_tex).to eq('f(x)')
17
+ end
18
+ end
19
+ end
20
+
21
+ describe '#to_tex' do
22
+ it 'returns the name of the function with tex variables' do
23
+ expect(subject.to_gnu).to eq('f(u)')
24
+ end
25
+
26
+ context 'when initializing variables from scratch' do
27
+ let(:x) { :x }
28
+
29
+ it 'returns the name of the function with tex variables' do
30
+ expect(subject.to_gnu).to eq('f(x)')
31
+ end
32
+ end
33
+ end
34
+ end
@@ -110,6 +110,24 @@ describe Danica::Function do
110
110
  it_behaves_like 'a generically generated function'
111
111
  end
112
112
 
113
+ describe '#name' do
114
+ let(:function) do
115
+ function_class.new(name: :f)
116
+ end
117
+
118
+ it do
119
+ expect(function.name).to be_a(Danica::Function::Name)
120
+ end
121
+
122
+ context 'when changing the function variables' do
123
+ it 'changes the name variables' do
124
+ expect do
125
+ function.x = 2
126
+ end.to change { function.name.variables.map(&:content) }
127
+ end
128
+ end
129
+ end
130
+
113
131
  describe '#describe_tex' do
114
132
  context 'when function has a name' do
115
133
  let(:function) do
@@ -119,6 +137,14 @@ describe Danica::Function do
119
137
  it 'returns the full function description' do
120
138
  expect(function.describe_tex).to eq('f(x, y) = x^{y}')
121
139
  end
140
+
141
+ context 'and one of the variables is changed' do
142
+ it 'uses the new variable value' do
143
+ expect do
144
+ function.y = 2
145
+ end.to change(function, :describe_tex).to('f(x, 2) = x^{2}')
146
+ end
147
+ end
122
148
  end
123
149
 
124
150
  context 'when a variable is set as a constant' do
@@ -328,7 +354,7 @@ describe Danica::Function do
328
354
  describe '#variables' do
329
355
  context 'when initialized with an array of variables' do
330
356
  subject { described_class::Spatial.new(variables: variables.values) }
331
- let(:expected) { variables.values.map { |v| subject.send(:wrap_value, v)} }
357
+ let(:expected) { variables.values.map { |v| Danica::Wrapper::Variable.new(v.is_a?(Hash) ? v : { name: v }) } }
332
358
  it do
333
359
  expect(subject.variables.compact).to eq(expected)
334
360
  end
@@ -20,6 +20,15 @@ shared_examples 'an object that returns the default variables' do
20
20
  end
21
21
  end
22
22
 
23
+ shared_examples 'an variable set that does not change the class variables' do
24
+ it 'does not change the the class variables' do
25
+ expect do
26
+ subject.variables = variables
27
+ end.not_to change { clazz.variables_hash }
28
+ end
29
+ end
30
+
31
+
23
32
  describe Danica::VariablesHolder do
24
33
  class Danica::VariablesHolder::Dummy
25
34
  include Danica::Common
@@ -47,11 +56,32 @@ describe Danica::VariablesHolder do
47
56
  end
48
57
 
49
58
  describe '#variables=' do
50
- before do
51
- subject.variables = variables
59
+ context 'when changing the variables of the object' do
60
+ context 'when all the variables are set with value' do
61
+ let(:variables) { [1, 2, 3] }
62
+ it_behaves_like 'an variable set that does not change the class variables'
63
+ end
64
+
65
+ context 'setting the variables through a hash' do
66
+ let(:variables) { { x: 1, y: 2, z: 3 } }
67
+ it_behaves_like 'an variable set that does not change the class variables'
68
+ end
69
+
70
+ context 'when none of the variables are set with values' do
71
+ let(:variables) { [] }
72
+ it_behaves_like 'an variable set that does not change the class variables'
73
+ end
74
+
75
+ context 'when the variables are set through an empty hash' do
76
+ let(:variables) { {} }
77
+ it_behaves_like 'an variable set that does not change the class variables'
78
+ end
52
79
  end
53
80
 
54
81
  context 'when setting the variables using a list' do
82
+ before do
83
+ subject.variables = variables
84
+ end
55
85
  let(:variables) { [1, 2, 3] }
56
86
 
57
87
  it 'changes the values of the variables' do
@@ -60,12 +90,15 @@ describe Danica::VariablesHolder do
60
90
 
61
91
  context 'but the array is empty' do
62
92
  let(:variables) { [] }
63
-
64
93
  it_behaves_like 'an object that returns the default variables hash'
65
94
  end
66
95
  end
67
96
 
68
97
  context 'when setting the variales using a hash' do
98
+ before do
99
+ subject.variables = variables
100
+ end
101
+
69
102
  let(:variables) { { x: 1, y: 2, z: 3 } }
70
103
 
71
104
  it 'changes the values of the variables' do
@@ -74,7 +107,6 @@ describe Danica::VariablesHolder do
74
107
 
75
108
  context 'but the hash is empty' do
76
109
  let(:variables) { {} }
77
-
78
110
  it_behaves_like 'an object that returns the default variables hash'
79
111
  end
80
112
  end
@@ -147,4 +179,20 @@ describe Danica::VariablesHolder do
147
179
  end
148
180
  end
149
181
  end
182
+
183
+ describe '#containers' do
184
+ it 'is an array of Containers' do
185
+ expect(subject.containers.first).to be_a(Danica::Wrapper::Container)
186
+ end
187
+
188
+ context 'when changing the variable on the object' do
189
+ let(:containers) { subject.containers }
190
+
191
+ it 'changes the variables in the containers' do
192
+ expect do
193
+ subject.x = 2
194
+ end.to change { containers.map(&:content) }
195
+ end
196
+ end
197
+ end
150
198
  end
@@ -7,6 +7,18 @@ describe Danica::Wrapper::Variable do
7
7
  subject { described_class.new(value: 100) }
8
8
  end
9
9
 
10
+ it 'can be initialize from nil value' do
11
+ expect do
12
+ described_class.new(nil)
13
+ end
14
+ end
15
+
16
+ it 'can be initialize from nil name' do
17
+ expect do
18
+ described_class.new(name: nil)
19
+ end
20
+ end
21
+
10
22
  describe '#to_f' do
11
23
  context 'when variable has no value' do
12
24
  it { expect { subject.to_f }.to raise_error(Danica::Exception::NotDefined) }
@@ -17,7 +17,7 @@ shared_examples 'a value wrapper' do |examples|
17
17
  let(:value) { val }
18
18
 
19
19
  it do
20
- expect(subject.wrapped_value).to be_a(expected)
20
+ expect(subject.wrapped_value.content).to be_a(expected)
21
21
  end
22
22
  end
23
23
  end
@@ -41,7 +41,7 @@ describe Danica::Wrapper do
41
41
  let(:value) { { value: 10, latex: :x, gnu: :X } }
42
42
 
43
43
  it do
44
- expect(subject.wrapped_value).to be_a(Danica::Wrapper::Constant)
44
+ expect(subject.wrapped_value.content).to be_a(Danica::Wrapper::Constant)
45
45
  end
46
46
  end
47
47
  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.4.3
4
+ version: 2.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darthjee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-16 00:00:00.000000000 Z
11
+ date: 2017-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -146,6 +146,7 @@ files:
146
146
  - lib/danica/exception.rb
147
147
  - lib/danica/function.rb
148
148
  - lib/danica/function/gauss.rb
149
+ - lib/danica/function/name.rb
149
150
  - lib/danica/operator.rb
150
151
  - lib/danica/operator/addition.rb
151
152
  - lib/danica/operator/chained.rb
@@ -162,6 +163,7 @@ files:
162
163
  - lib/danica/version.rb
163
164
  - lib/danica/wrapper.rb
164
165
  - lib/danica/wrapper/constant.rb
166
+ - lib/danica/wrapper/container.rb
165
167
  - lib/danica/wrapper/group.rb
166
168
  - lib/danica/wrapper/negative.rb
167
169
  - lib/danica/wrapper/number.rb
@@ -175,6 +177,7 @@ files:
175
177
  - spec/lib/danica/common_spec.rb
176
178
  - spec/lib/danica/dsl_spec.rb
177
179
  - spec/lib/danica/function/gauss_spec.rb
180
+ - spec/lib/danica/function/name_spec.rb
178
181
  - spec/lib/danica/function_spec.rb
179
182
  - spec/lib/danica/operator/addition_spec.rb
180
183
  - spec/lib/danica/operator/cos_spec.rb
@@ -237,6 +240,7 @@ test_files:
237
240
  - spec/lib/danica/common_spec.rb
238
241
  - spec/lib/danica/dsl_spec.rb
239
242
  - spec/lib/danica/function/gauss_spec.rb
243
+ - spec/lib/danica/function/name_spec.rb
240
244
  - spec/lib/danica/function_spec.rb
241
245
  - spec/lib/danica/operator/addition_spec.rb
242
246
  - spec/lib/danica/operator/cos_spec.rb