fathom 0.3.7 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +7 -5
- data/.document +2 -2
- data/Gemfile +9 -10
- data/{LICENSE → LICENSE.txt} +1 -1
- data/README.md +29 -90
- data/Rakefile +34 -32
- data/VERSION +1 -1
- data/fathom.gemspec +105 -0
- data/features/fathom.feature +26 -0
- data/features/step_definitions/fathom_steps.rb +23 -0
- data/features/support/env.rb +13 -0
- data/lib/ext/array.rb +6 -2
- data/lib/ext/string.rb +86 -7
- data/lib/fathom.rb +51 -88
- data/lib/fathom/behaviors/attribute_system.rb +91 -0
- data/lib/fathom/behaviors/context_behavior.rb +28 -0
- data/lib/fathom/behaviors/plugins.rb +16 -0
- data/lib/fathom/contexts/network_population.rb +47 -0
- data/lib/fathom/contexts/network_traversal.rb +4 -0
- data/lib/fathom/data/adjacency_matrix.rb +27 -0
- data/lib/fathom/data/definition.rb +22 -0
- data/lib/fathom/data/edge.rb +58 -0
- data/lib/fathom/data/network.rb +35 -0
- data/lib/fathom/data/outcome.rb +30 -0
- data/lib/fathom/data/property.rb +31 -0
- data/lib/fathom/data/variable.rb +59 -0
- data/lib/fathom/roles/general_graph_tools.rb +87 -0
- data/lib/fathom/roles/network_builder.rb +61 -0
- data/spec/fathom/behaviors/attribute_system_spec.rb +141 -0
- data/spec/fathom/behaviors/context_behavior_spec.rb +15 -0
- data/spec/fathom/behaviors/plugins_spec.rb +80 -0
- data/spec/fathom/contexts/network_population_spec.rb +55 -0
- data/spec/fathom/contexts/network_traversal_spec.rb +11 -0
- data/spec/fathom/data/adjacency_matrix_spec.rb +42 -0
- data/spec/fathom/data/definition_spec.rb +19 -0
- data/spec/fathom/data/edge_spec.rb +77 -0
- data/spec/fathom/data/network_spec.rb +72 -0
- data/spec/fathom/data/outcome_spec.rb +17 -0
- data/spec/fathom/data/property_spec.rb +17 -0
- data/spec/fathom/data/variable_spec.rb +101 -0
- data/spec/fathom/ext/array_spec.rb +17 -0
- data/spec/fathom/ext/string_spec.rb +90 -0
- data/spec/fathom/roles/general_graph_tools_spec.rb +95 -0
- data/spec/fathom/roles/network_builder_spec.rb +90 -0
- data/spec/fathom_spec.rb +28 -49
- data/spec/spec_helper.rb +7 -11
- data/spec/support/context_behavior.rb +14 -0
- data/spec/support/custom_matchers.rb +12 -0
- data/spec/support/files.rb +8 -0
- data/spec/support/network.yml +42 -0
- metadata +133 -174
- data/.bundle/config +0 -2
- data/.gitignore +0 -6
- data/Gemfile.lock +0 -42
- data/TODO.md +0 -127
- data/autotest/discover.rb +0 -1
- data/lib/ext/faster_csv.rb +0 -1
- data/lib/ext/open_struct.rb +0 -17
- data/lib/fathom/agent.rb +0 -48
- data/lib/fathom/agent/agent_cluster.rb +0 -23
- data/lib/fathom/agent/properties.rb +0 -48
- data/lib/fathom/archive/causal_graph.rb +0 -12
- data/lib/fathom/archive/concept.rb +0 -83
- data/lib/fathom/archive/conditional_probability_matrix.rb +0 -119
- data/lib/fathom/archive/inverter.rb +0 -20
- data/lib/fathom/archive/n2.rb +0 -198
- data/lib/fathom/archive/n3.rb +0 -119
- data/lib/fathom/archive/node.rb +0 -97
- data/lib/fathom/archive/noodle.rb +0 -136
- data/lib/fathom/archive/scratch.rb +0 -45
- data/lib/fathom/distributions.rb +0 -8
- data/lib/fathom/distributions/discrete_gaussian.rb +0 -44
- data/lib/fathom/distributions/discrete_uniform.rb +0 -25
- data/lib/fathom/distributions/gaussian.rb +0 -46
- data/lib/fathom/distributions/uniform.rb +0 -35
- data/lib/fathom/import.rb +0 -85
- data/lib/fathom/import/csv_import.rb +0 -59
- data/lib/fathom/import/import_node.rb +0 -17
- data/lib/fathom/import/yaml_import.rb +0 -74
- data/lib/fathom/knowledge_base.rb +0 -46
- data/lib/fathom/knowledge_base/search.rb +0 -19
- data/lib/fathom/monte_carlo_set.rb +0 -152
- data/lib/fathom/node.rb +0 -139
- data/lib/fathom/node/belief_node.rb +0 -121
- data/lib/fathom/node/cpm_node.rb +0 -100
- data/lib/fathom/node/data_collection.rb +0 -97
- data/lib/fathom/node/data_node.rb +0 -22
- data/lib/fathom/node/decision.rb +0 -11
- data/lib/fathom/node/discrete_node.rb +0 -41
- data/lib/fathom/node/fact.rb +0 -24
- data/lib/fathom/node/mc_node.rb +0 -70
- data/lib/fathom/node/node_extensions/enforced_name.rb +0 -12
- data/lib/fathom/node/node_extensions/numeric_methods.rb +0 -68
- data/lib/fathom/node/plausible_range.rb +0 -98
- data/lib/fathom/simulation.rb +0 -59
- data/lib/fathom/simulation/tick_methods.rb +0 -25
- data/lib/fathom/simulation/tick_simulation.rb +0 -12
- data/lib/fathom/value_description.rb +0 -79
- data/lib/options_hash.rb +0 -186
- data/spec/ext/array_spec.rb +0 -10
- data/spec/ext/faster_csv_spec.rb +0 -10
- data/spec/ext/open_struct_spec.rb +0 -20
- data/spec/ext/string_spec.rb +0 -7
- data/spec/fathom/agent/agent_cluster_spec.rb +0 -17
- data/spec/fathom/agent_spec.rb +0 -51
- data/spec/fathom/distributions/discrete_gaussian_spec.rb +0 -64
- data/spec/fathom/distributions/discrete_uniform_spec.rb +0 -0
- data/spec/fathom/distributions/gaussian_spec.rb +0 -64
- data/spec/fathom/distributions/uniform_spec.rb +0 -0
- data/spec/fathom/import/csv_import_spec.rb +0 -52
- data/spec/fathom/import/import_node_spec.rb +0 -10
- data/spec/fathom/import/yaml_import_spec.rb +0 -73
- data/spec/fathom/import_spec.rb +0 -36
- data/spec/fathom/knowledge_base_spec.rb +0 -20
- data/spec/fathom/monte_carlo_set_spec.rb +0 -149
- data/spec/fathom/node/belief_node_spec.rb +0 -180
- data/spec/fathom/node/cpm_node_spec.rb +0 -144
- data/spec/fathom/node/data_collection_spec.rb +0 -26
- data/spec/fathom/node/data_node_spec.rb +0 -102
- data/spec/fathom/node/decision_spec.rb +0 -15
- data/spec/fathom/node/discrete_node_spec.rb +0 -56
- data/spec/fathom/node/fact_spec.rb +0 -33
- data/spec/fathom/node/mc_node_spec.rb +0 -66
- data/spec/fathom/node/node_extensions/enforced_name_spec.rb +0 -15
- data/spec/fathom/node/node_extensions/numeric_methods_spec.rb +0 -124
- data/spec/fathom/node/plausible_range_spec.rb +0 -151
- data/spec/fathom/node_spec.rb +0 -172
- data/spec/fathom/simulation/tick_simulation_spec.rb +0 -32
- data/spec/fathom/simulation_spec.rb +0 -24
- data/spec/fathom/value_description_spec.rb +0 -70
- data/spec/support/demo.yml +0 -17
- data/spec/support/demo_agent.rb +0 -8
- data/spec/support/dummy_numeric_node.rb +0 -8
- data/spec/support/fact.yml +0 -11
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe ContextBehavior do
|
6
|
+
it "should be able to set a default_class" do
|
7
|
+
@class = Class.new do
|
8
|
+
extend Plugins
|
9
|
+
plugin ContextBehavior
|
10
|
+
default_class Hash
|
11
|
+
end
|
12
|
+
obj = @class.new
|
13
|
+
obj.object.should eql({})
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
module PluginDemoModule
|
6
|
+
module InstanceMethods
|
7
|
+
def special_instance_method
|
8
|
+
:special_instance_method
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def special_class_method
|
14
|
+
:special_class_method
|
15
|
+
end
|
16
|
+
|
17
|
+
def special_configuration_method
|
18
|
+
@especially_configured = true
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :especially_configured
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.configure(mod)
|
25
|
+
mod.special_configuration_method
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module PlainDemoModule
|
30
|
+
def plain_instance_method
|
31
|
+
:plain_instance_method
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
describe Plugins do
|
37
|
+
|
38
|
+
before do
|
39
|
+
@class = Class.new do
|
40
|
+
extend Plugins
|
41
|
+
plugin PluginDemoModule
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
after(:all) do
|
46
|
+
Object.send(:remove_const, :PluginDemoModule)
|
47
|
+
Object.send(:remove_const, :PlainDemoModule)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have a plugins array" do
|
51
|
+
@class.plugins.should eql([PluginDemoModule])
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be able to add a new plugin" do
|
55
|
+
@class.plugins.should eql([PluginDemoModule])
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should make the ClassMethods available to the class" do
|
59
|
+
@class.special_class_method.should eql(:special_class_method)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should make the InstanceMethods available on an instance" do
|
63
|
+
obj = @class.new
|
64
|
+
obj.special_instance_method.should eql(:special_instance_method)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should include a plain module if it is not a Plugin (has InstanceMethods)" do
|
68
|
+
@class = Class.new do
|
69
|
+
extend Plugins
|
70
|
+
plugin PlainDemoModule
|
71
|
+
end
|
72
|
+
obj = @class.new
|
73
|
+
obj.plain_instance_method.should eql(:plain_instance_method)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should have called the configure method in the plugin" do
|
77
|
+
@class.especially_configured.should be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe NetworkPopulation do
|
6
|
+
|
7
|
+
# ====================
|
8
|
+
# = General Behavior =
|
9
|
+
# ====================
|
10
|
+
context "when acting like a context generally" do
|
11
|
+
before {@class = NetworkPopulation}
|
12
|
+
it_should_behave_like "a context"
|
13
|
+
|
14
|
+
it "should have a default_class of Network" do
|
15
|
+
@context = NetworkPopulation.new
|
16
|
+
@context.object.should be_a(Network)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# ==================
|
21
|
+
# = YAML Importing =
|
22
|
+
# ==================
|
23
|
+
context "when importing records from YAML" do
|
24
|
+
before do
|
25
|
+
@network = Network.new
|
26
|
+
@context = NetworkPopulation.new(@network)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should mixin the NetworkBuilder to the network" do
|
30
|
+
@context.object.should_receive(:extend).with(NetworkBuilder).and_return(true)
|
31
|
+
@context.object.stub(:from_hash) { true }
|
32
|
+
@context.import_records_from_yaml
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should expose from_hash on the network object" do
|
36
|
+
@network.should_not respond_to(:from_hash)
|
37
|
+
@context.import_records_from_yaml
|
38
|
+
@network.should respond_to(:from_hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should be able to take a filename and process that." do
|
42
|
+
yaml_contents = YAML.load(network_contents_in_yaml)
|
43
|
+
YAML.should_receive(:load_file).with(network_contents_in_yaml_filename).and_return(yaml_contents)
|
44
|
+
@context.import_records_from_yaml(:filename => network_contents_in_yaml_filename)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should rely on from_hash to convert the loaded YAML values into a serialized network" do
|
48
|
+
yaml_contents = YAML.load(network_contents_in_yaml)
|
49
|
+
@network.should_receive(:from_hash).with(yaml_contents).and_return(true)
|
50
|
+
@context.import_records_from_yaml(:filename => network_contents_in_yaml_filename)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe AdjacencyMatrix do
|
6
|
+
before do
|
7
|
+
@am = AdjacencyMatrix.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should use an efficient data storage method, a Hash that defaults to 0" do
|
11
|
+
store = @am.send(:instance_variable_get, :@store)
|
12
|
+
store.should be_a(Hash)
|
13
|
+
store[:not_indexed].should eql(0)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should take an arbitrary default for the store" do
|
17
|
+
am = AdjacencyMatrix.new(:arbitrary)
|
18
|
+
store = am.send(:instance_variable_get, :@store)
|
19
|
+
store[:not_indexed].should eql(:arbitrary)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should take a parent and child argument to get or set a value in the store" do
|
23
|
+
lambda{@am[1]}.should raise_error(ArgumentError, /wrong number of arguments/)
|
24
|
+
@am[1,1] = 1
|
25
|
+
@am[1,1].should eql(1)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be an Enumerable" do
|
29
|
+
AdjacencyMatrix.included_modules.should be_include(Enumerable)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should enumerate on the store" do
|
33
|
+
@am[1,1] = 1
|
34
|
+
@am[2,1] = 1
|
35
|
+
@am.map.to_a.should eql([[[1, 1], 1], [[2, 1], 1]])
|
36
|
+
@am.each do |(parent, child), value|
|
37
|
+
child.should eql(1)
|
38
|
+
value.should eql(1)
|
39
|
+
[1,2].should be_include(parent)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe Definition do
|
6
|
+
|
7
|
+
it "should initialize a for accessor" do
|
8
|
+
Definition.should have_an_initialization_accessor_for(:for)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should initialize a given accessor" do
|
12
|
+
Definition.should have_an_initialization_accessor_for(:given)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should initialize a table accessor" do
|
16
|
+
Definition.should have_an_initialization_accessor_for(:table)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe Edge do
|
6
|
+
|
7
|
+
it "should initialize a is_directed accessor" do
|
8
|
+
Edge.should have_an_initialization_accessor_for(:is_directed)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should default the edge to true" do
|
12
|
+
edge = Edge.new
|
13
|
+
edge.is_directed.should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should initialize a parent accessor" do
|
17
|
+
edge = Edge.new(:parent => :value)
|
18
|
+
edge.parent.should ==(Variable.new(:name => :value))
|
19
|
+
edge.parent = :value2
|
20
|
+
edge.parent.should ==(Variable.new(:name => :value2))
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should initialize a child accessor" do
|
24
|
+
edge = Edge.new(:child => :value)
|
25
|
+
edge.child.should ==(Variable.new(:name => :value))
|
26
|
+
edge.child = :value2
|
27
|
+
edge.child.should ==(Variable.new(:name => :value2))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be equal by variables" do
|
31
|
+
v1 = Variable.new(:name => :v1)
|
32
|
+
v2 = Variable.new(:name => :v2)
|
33
|
+
e1 = Edge.new(:parent => v1, :child => v2)
|
34
|
+
e2 = Edge.new(:parent => v1, :child => v2)
|
35
|
+
e1.should ==(e2)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should ensure the parent and child are a variables" do
|
39
|
+
edge = Edge.new :parent => :v1, :child => :v2
|
40
|
+
edge.parent.should ==(Variable.new(:name => :v1))
|
41
|
+
edge.child.should ==(Variable.new(:name => :v2))
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when inferring an Edge" do
|
45
|
+
it "should be able to infer an Edge from an Edge" do
|
46
|
+
edge = Edge.new :parent => :v1, :child => :v2
|
47
|
+
inferred = Edge.infer(edge)
|
48
|
+
inferred.should eql(edge)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should be able to infer an Edge from an Array, [parent, child]" do
|
52
|
+
v1 = Variable.infer(:v1)
|
53
|
+
v2 = Variable.infer(:v2)
|
54
|
+
edge = Edge.infer([v1, v2])
|
55
|
+
edge.should be_a(Edge)
|
56
|
+
edge.parent.should eql(v1)
|
57
|
+
edge.child.should eql(v2)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should be able to take more than one parameter and use that as a parent, child indicator" do
|
61
|
+
v1 = Variable.infer(:v1)
|
62
|
+
v2 = Variable.infer(:v2)
|
63
|
+
edge = Edge.infer(v1, v2)
|
64
|
+
edge.should be_a(Edge)
|
65
|
+
edge.parent.should eql(v1)
|
66
|
+
edge.child.should eql(v2)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should be able to infer an Edge from a Hash" do
|
70
|
+
edge = Edge.infer :parent => :p, :child => :c
|
71
|
+
edge.parent.should be_a(Variable)
|
72
|
+
edge.parent.name.should eql(:p)
|
73
|
+
edge.child.should be_a(Variable)
|
74
|
+
edge.child.name.should eql(:c)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe Network do
|
6
|
+
|
7
|
+
it "should initialize a name accessor" do
|
8
|
+
Network.should have_an_initialization_accessor_for(:name)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should initialize a variables accessor" do
|
12
|
+
Network.should have_an_initialization_accessor_for(:variables)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should default the variables to an array" do
|
16
|
+
Network.new.variables.should eql([])
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should extend Enumerable" do
|
20
|
+
Network.ancestors.should be_include(Enumerable)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should enumerate over the variables" do
|
24
|
+
n = Network.new :variables => [1,2,3]
|
25
|
+
n.map.to_a.should eql([1,2,3])
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should initialize a properties accessor" do
|
29
|
+
Network.should have_an_initialization_accessor_for(:properties)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should default the properties to an Array" do
|
33
|
+
Network.new.properties.should eql([])
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should initialize an edges accessor" do
|
37
|
+
Network.should have_an_initialization_accessor_for(:edges)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should default the edges to an Array" do
|
41
|
+
Network.new.edges.should eql([])
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should initialize a definitions accessor" do
|
45
|
+
Network.should have_an_initialization_accessor_for(:definitions)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should default the definitions to an Array" do
|
49
|
+
Network.new.definitions.should eql([])
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when using the Enumerator" do
|
53
|
+
before do
|
54
|
+
@n = Network.new :variables => [1,2,3]
|
55
|
+
@variables = @n.variables
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should be able to iterate on the variables" do
|
59
|
+
@n.each {|v| @variables.should be_include(v)}
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have each_variable as an alias to each" do
|
63
|
+
@n.each_variable {|v| @variables.should be_include(v)}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should use the variable enumeration for the Enumerable" do
|
67
|
+
@n.map {|v| v }.should eql([1,2,3])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe Outcome do
|
6
|
+
|
7
|
+
it "should initialize a value accessor" do
|
8
|
+
Outcome.should have_an_initialization_accessor_for(:value)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have an infer constructor" do
|
12
|
+
outcome = Outcome.infer(:some_value)
|
13
|
+
outcome.should be_a(Outcome)
|
14
|
+
outcome.value.should eql(:some_value)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe Property do
|
6
|
+
|
7
|
+
it "should initialize a value accessor" do
|
8
|
+
Property.should have_an_initialization_accessor_for(:value)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have an infer constructor" do
|
12
|
+
property = Property.infer(:some_value)
|
13
|
+
property.should be_a(Property)
|
14
|
+
property.value.should eql(:some_value)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe Variable do
|
6
|
+
|
7
|
+
# ==================
|
8
|
+
# = Initialization =
|
9
|
+
# ==================
|
10
|
+
it "should have an attributes getter, built from initialization" do
|
11
|
+
v = Variable.new(some: :value)
|
12
|
+
v.attributes.delete(:id)
|
13
|
+
v.attributes.should eql({:some => :value, :prior_odds => [0.5, 0.5]})
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should initialize a name accessor" do
|
17
|
+
Variable.should have_an_initialization_accessor_for(:name)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have an underscored_name" do
|
21
|
+
v = Variable.new(:name => "a Very special name, don't you think?")
|
22
|
+
v.underscored_name.should eql("a_very_special_name__don_t_you_think_")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should initialize a properties accessor" do
|
26
|
+
Variable.should have_an_initialization_accessor_for(:properties)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should initialize an outcomes accessor" do
|
30
|
+
Variable.should have_an_initialization_accessor_for(:outcomes)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should default the outcomes to [true, false]" do
|
34
|
+
v = Variable.new
|
35
|
+
v.outcomes.should eql([true, false])
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should initialize a prior_odds accessor" do
|
39
|
+
Variable.should have_an_initialization_accessor_for(:prior_odds)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should default the prior odds to the uniform set for the outcomes" do
|
43
|
+
v = Variable.new
|
44
|
+
v.prior_odds.should eql([0.5, 0.5])
|
45
|
+
v = Variable.new :outcomes => [:a, :b, :c]
|
46
|
+
v.prior_odds.should eql([1/3.0, 1/3.0, 1/3.0])
|
47
|
+
end
|
48
|
+
|
49
|
+
# =================
|
50
|
+
# = Equality (==) =
|
51
|
+
# =================
|
52
|
+
it "should be equal by name" do
|
53
|
+
v1 = Variable.new(:name => :name)
|
54
|
+
v2 = Variable.new(:name => :name)
|
55
|
+
v1.should ==(v2)
|
56
|
+
end
|
57
|
+
|
58
|
+
# =========
|
59
|
+
# = Infer =
|
60
|
+
# =========
|
61
|
+
context "when infering" do
|
62
|
+
it "should be able to infer from a variable" do
|
63
|
+
@v1 = Variable.new
|
64
|
+
Variable.infer(@v1).should eql(@v1)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should be able to infer from a hash" do
|
68
|
+
@hash = {:name => :name, :prior_odds => [0.4, 0.6]}
|
69
|
+
@v1 = Variable.new(@hash)
|
70
|
+
Variable.infer(@hash).should ==(@v1)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should be able to infer from a symbol" do
|
74
|
+
@symbol = :name
|
75
|
+
@v1 = Variable.new(:name => @symbol)
|
76
|
+
Variable.infer(@symbol).should ==(@v1)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should be able to infer from a string" do
|
80
|
+
@string = 'name'
|
81
|
+
@v1 = Variable.new(:name => @string)
|
82
|
+
Variable.infer(@string).should ==(@v1)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
# ======
|
88
|
+
# = ID =
|
89
|
+
# ======
|
90
|
+
context "when ensuring a unique id" do
|
91
|
+
before do
|
92
|
+
@v = Variable.new
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should have an id, a UUID" do
|
96
|
+
uuid_re = /^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$/
|
97
|
+
@v.id.should match(uuid_re)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|