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,17 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Array do
|
4
|
+
|
5
|
+
it "should be able to invert an array" do
|
6
|
+
[:a, :b, :c].invert.should eql({:a => 0, :b => 1, :c => 2})
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be able to invert an array with an optional block" do
|
10
|
+
keys = [4,5,6]
|
11
|
+
array = [:a, :b, :c]
|
12
|
+
inverted = array.invert do |x, i|
|
13
|
+
keys[i]
|
14
|
+
end
|
15
|
+
inverted.should eql({:a => 4, :b => 5, :c => 6})
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
it "should be able to constantize a string" do
|
5
|
+
"Object".constantize.should eql(Object)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be able to camelize a lower-case and underscored word" do
|
9
|
+
"this_is_it".camelize.should eql("ThisIsIt")
|
10
|
+
"this_is_it".camelize(false).should eql("thisIsIt")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to underscore a camel-cased word" do
|
14
|
+
"ThisIsIt".underscore.should eql("this_is_it")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be able to dasherize an underscored word" do
|
18
|
+
"this_is_it".dasherize.should eql("this-is-it")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be able to demodulize a module-looking word" do
|
22
|
+
"This::Is::It".demodulize.should eql("It")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be able to create a foreign key from a name" do
|
26
|
+
"ThisIsIt".foreign_key.should eql("this_is_it_id")
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when ordinalize-ing numbers" do
|
30
|
+
it "should turn 1 to 1st" do
|
31
|
+
"1".ordinalize.should eql("1st")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should turn 2 to 2nd" do
|
35
|
+
"2".ordinalize.should eql("2nd")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should turn 3 to 3rd" do
|
39
|
+
"3".ordinalize.should eql("3rd")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should turn 4 and so on to nth" do
|
43
|
+
(4..20).each do |i|
|
44
|
+
i.to_s.ordinalize.should eql("#{i}th")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be able to wrap a string, defaulting to 80 characters" do
|
50
|
+
source = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
51
|
+
expected =<<END
|
52
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
|
53
|
+
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
|
54
|
+
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
55
|
+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
|
56
|
+
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
|
57
|
+
culpa qui officia deserunt mollit anim id est laborum.
|
58
|
+
END
|
59
|
+
source.wrap.should eql(expected)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should be able to take an arbitrary wrap length" do
|
63
|
+
source = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
64
|
+
expected =<<END
|
65
|
+
Lorem ipsum dolor sit
|
66
|
+
amet, consectetur
|
67
|
+
adipisicing elit, sed do
|
68
|
+
eiusmod tempor
|
69
|
+
incididunt ut labore et
|
70
|
+
dolore magna aliqua. Ut
|
71
|
+
enim ad minim veniam,
|
72
|
+
quis nostrud
|
73
|
+
exercitation ullamco
|
74
|
+
laboris nisi ut aliquip
|
75
|
+
ex ea commodo consequat.
|
76
|
+
Duis aute irure dolor in
|
77
|
+
reprehenderit in
|
78
|
+
voluptate velit esse
|
79
|
+
cillum dolore eu fugiat
|
80
|
+
nulla pariatur.
|
81
|
+
Excepteur sint occaecat
|
82
|
+
cupidatat non proident,
|
83
|
+
sunt in culpa qui
|
84
|
+
officia deserunt mollit
|
85
|
+
anim id est laborum.
|
86
|
+
END
|
87
|
+
source.wrap(24).should eql(expected)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe NetworkBuilder do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@network = Network.new
|
9
|
+
@network.extend GeneralGraphTools
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when using the adjacency matrix" do
|
13
|
+
it "should offer an adjacency matrix to the network" do
|
14
|
+
@network.adjacency_matrix.should be_an(AdjacencyMatrix)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should default unknown values to 0" do
|
18
|
+
@network.adjacency_matrix[:parent, :child].should eql(0)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should record edges in the adjacency matrix with add_edge" do
|
22
|
+
v1 = Variable.new()
|
23
|
+
v2 = Variable.new()
|
24
|
+
@network.add_edge(v1, v2)
|
25
|
+
@network.variables.should eql([v1, v2])
|
26
|
+
@network.at(v1, v2).should eql(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should remove edges, but not the variables" do
|
30
|
+
v1 = Variable.new()
|
31
|
+
v2 = Variable.new()
|
32
|
+
@network.add_edge(v1, v2)
|
33
|
+
@network.remove_edge(v1, v2)
|
34
|
+
@network.variables.should eql([v1, v2])
|
35
|
+
@network.at(v1, v2).should eql(0)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should work for non-variables" do
|
39
|
+
@network.add_edge(:one, :two)
|
40
|
+
@network.at(:one, :two).should eql(1)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have [] as an alias for 'at'" do
|
44
|
+
@network.add_edge :one, :two
|
45
|
+
@network.at(:one, :two).should eql(1)
|
46
|
+
@network[:one, :two].should eql(1)
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when iterating on the graph" do
|
50
|
+
before do
|
51
|
+
@network.add_edge :one, :two
|
52
|
+
@network.add_edge :one, :three
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should be able to lookup the out-degree of a variable" do
|
56
|
+
@network.degree(:one).should eql(2)
|
57
|
+
@network.degree(:two).should eql(0)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should have an iterator on each_vertex" do
|
61
|
+
found = []
|
62
|
+
@network.each_vertex {|v| found << v }
|
63
|
+
found.should eql([:one, :two, :three])
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have an iterator on each_edge" do
|
67
|
+
found = []
|
68
|
+
@network.each_edge {|p, c| found << [p,c] }
|
69
|
+
found.should eql([[:one, :two], [:one, :three]])
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return whether the graph is connected" do
|
73
|
+
# 1 -> 2 and 1 -> 3
|
74
|
+
@network.should be_connected
|
75
|
+
|
76
|
+
@network = Network.new
|
77
|
+
@network.extend GeneralGraphTools
|
78
|
+
@network.add_edge(:one, :two)
|
79
|
+
@network.add_edge(:three, :four)
|
80
|
+
|
81
|
+
# 1 -> 2
|
82
|
+
# 3 -> 4
|
83
|
+
@network.should_not be_connected
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should have an edge lookup tool" do
|
91
|
+
v1, v2 = Variable.infer(:v1), Variable.infer(:v2)
|
92
|
+
@network.add_edge(v1, v2)
|
93
|
+
@network.edge?(v1, v2).should be_true
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
include Fathom
|
4
|
+
|
5
|
+
describe NetworkBuilder do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@network = Network.new
|
9
|
+
@network.extend NetworkBuilder
|
10
|
+
end
|
11
|
+
|
12
|
+
# =============
|
13
|
+
# = from_hash =
|
14
|
+
# =============
|
15
|
+
context "when building a network from a hash" do
|
16
|
+
# ===========================
|
17
|
+
# = Top-level Functionality =
|
18
|
+
# ===========================
|
19
|
+
it "should have a from_hash method" do
|
20
|
+
@network.should respond_to(:from_hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should merge the attributes with the new hash" do
|
24
|
+
@network.from_hash name: :special
|
25
|
+
@network.attributes.should eql(name: :special)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should provide the name directly" do
|
29
|
+
@network.from_hash name: :special
|
30
|
+
@network.name.should eql(:special)
|
31
|
+
end
|
32
|
+
|
33
|
+
# ==========================
|
34
|
+
# = Variable Serialization =
|
35
|
+
# ==========================
|
36
|
+
it "should convert the variables to serialized Variables" do
|
37
|
+
@network.from_hash variables: [{name: :arrived}, {name: :happy}]
|
38
|
+
@network.variables.all? {|p| p.is_a?(Variable)}.should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should convert the variables to an array" do
|
42
|
+
@network.from_hash variables: Variable.new(name: :temperature_at_noon)
|
43
|
+
@network.variables.should be_a(Array)
|
44
|
+
end
|
45
|
+
|
46
|
+
# ==========================
|
47
|
+
# = Property Serialization =
|
48
|
+
# ==========================
|
49
|
+
it "should convert the properties to serialized Properties" do
|
50
|
+
@network.from_hash properties: [1, 2, 3]
|
51
|
+
@network.properties.all? {|p| p.is_a?(Property)}.should be_true
|
52
|
+
@network.properties.map {|p| p.value }.should eql([1,2,3])
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should convert the properties to an array" do
|
56
|
+
@network.from_hash properties: 1
|
57
|
+
@network.properties.should be_a(Array)
|
58
|
+
end
|
59
|
+
|
60
|
+
# ======================
|
61
|
+
# = Edge Serialization =
|
62
|
+
# ======================
|
63
|
+
it "should convert the edges to serialized Edges" do
|
64
|
+
@network.from_hash edges: {parent: 1, child: 2}
|
65
|
+
@network.edges.all? {|p| p.is_a?(Edge)}.should be_true
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should convert the edges to an array" do
|
69
|
+
@network.from_hash edges: Edge.new
|
70
|
+
@network.edges.should be_a(Array)
|
71
|
+
end
|
72
|
+
|
73
|
+
# ============================
|
74
|
+
# = Definition Serialization =
|
75
|
+
# ============================
|
76
|
+
it "should convert the definitions to serialized Definitions" do
|
77
|
+
@network.from_hash definitions: {for: :target, given: [:p1, :p2], table: [[0.1, 0.9], [0.3, 0.7]]}
|
78
|
+
@network.definitions.all? {|p| p.is_a?(Definition)}.should be_true
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should convert the definitions to an array" do
|
82
|
+
@network.from_hash definitions: Definition.new
|
83
|
+
@network.definitions.should be_a(Array)
|
84
|
+
end
|
85
|
+
|
86
|
+
# TODO: Come back to this and deal with the recursive nature of this process: basically, initialization and from_hash share a lot of behavior, and there's a case to be made to merge these.
|
87
|
+
|
88
|
+
end # when building a network from a hash
|
89
|
+
|
90
|
+
end
|
data/spec/fathom_spec.rb
CHANGED
@@ -1,56 +1,35 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
describe
|
4
|
-
it "should have required gsl, but not included it (avoiding Rational conflicts)" do
|
5
|
-
Fathom.included_modules.should_not be_include(GSL)
|
6
|
-
lambda{GSL}.should_not raise_error
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should have a knowledge base" do
|
10
|
-
Fathom.knowledge_base.should be_a(KnowledgeBase)
|
11
|
-
end
|
3
|
+
describe Fathom do
|
12
4
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
=begin
|
20
|
-
OK, so I'm thinking about how this works....
|
21
|
-
A knowledge base is something I work from. I could create a default knowledge base. I won't be able to save it to anywhere permenant, but possibly I want to just be able to start working for a while, have things link up, then decide if I've created anything of value...
|
22
|
-
|
23
|
-
Or, I could always use an explicit knowledge base.
|
24
|
-
|
25
|
-
Frankly, the way I thought I would use it would be:
|
26
|
-
|
27
|
-
home_budget = Fathom::KnowledgeBase.find_or_create(:home_budget)
|
28
|
-
home_budget.new(:plausible_range, :hard_min => 0, :min => 500, :max => 750, :name => "Referral Income", :type => :revenue)
|
29
|
-
revenue = home_budget.find(...)
|
30
|
-
mc_revenue = home_budget.new(:mc_node, :values => revenue, :type => :revenue, :name => "Combined Income", :description => "A collection of income from our investments, job, and miscellaneous projects.") do |s|
|
31
|
-
:combined_income => s.values.inject(0.0) do |sum, e|
|
32
|
-
sum += e
|
5
|
+
context "when configuring Fathom" do
|
6
|
+
|
7
|
+
after do
|
8
|
+
Fathom.reset_config!
|
33
9
|
end
|
10
|
+
|
11
|
+
it "should have a config" do
|
12
|
+
Fathom.config.should be_a(::Fathom::Config)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be configured automatically to use a Hash for storage" do
|
16
|
+
Fathom.config.storage.should eql(Hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to set the storage" do
|
20
|
+
Fathom.config.storage = :another_storage_option
|
21
|
+
Fathom.config.storage.should eql(:another_storage_option)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should use the String extensions" do
|
25
|
+
"test".should respond_to(:underscore)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should depend on UUID" do
|
29
|
+
defined?(UUID).should be_true
|
30
|
+
end
|
31
|
+
|
34
32
|
end
|
35
|
-
home_budget.new(:svm_node, :values => mc_revenue.process, :type => :revenue)
|
36
|
-
|
37
|
-
mc_daily_expenses = home_budget.new(:mc_node,
|
38
|
-
:values => {:expenses => home_budget.find(...), :dates => Fathom::KnowledgeBase.find(:dates)},
|
39
|
-
:type => :expenses,
|
40
|
-
:name => "Combined Expenses",
|
41
|
-
:description => "All of the household expenses on a monthly basis"
|
42
|
-
) do |s|
|
43
|
-
cycle ||= (1..365).cycle
|
44
|
-
day = s.values.dates.day_in_year(cycle.next)
|
45
|
-
...
|
46
|
-
end
|
47
|
-
|
48
|
-
create a mini belief network about whether the budget is appropriate here...
|
49
|
-
|
50
33
|
|
51
34
|
|
52
|
-
|
53
|
-
could always be re-run, in case the inputs change. I don't yet have an automated way to keep up with the
|
54
|
-
changes to the inputs on that, but I do on the belief nodes.
|
55
|
-
|
56
|
-
=end
|
35
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,12 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
-
|
4
|
-
require 'fathom'
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
3
|
require 'rspec'
|
6
|
-
require '
|
7
|
-
|
8
|
-
include Fathom
|
4
|
+
require 'fathom'
|
9
5
|
|
10
|
-
# Requires supporting
|
11
|
-
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
12
9
|
|
13
|
-
RSpec.configure do |
|
14
|
-
|
15
|
-
c.filter_run_excluding :slow => true
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.filter_run_excluding :slow => true
|
16
12
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
shared_examples_for "a context" do
|
2
|
+
|
3
|
+
it "should take an object and expose that object through a reader" do
|
4
|
+
obj = double('some data object')
|
5
|
+
context = @class.new(obj)
|
6
|
+
context.object.should eql(obj)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should raise an error if no target is provided at initialization" do
|
10
|
+
@class.send(:instance_variable_set, :@default_class, nil)
|
11
|
+
lambda{@class.new}.should raise_error(ArgumentError, /You must provide a target object to build this context./)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Tests that a value can be set with a parameters hash, and that an accessor is set on that field.
|
2
|
+
# Meaning: MyClass.new(:some_accessor => :some_value).some_accessor # => :some_value
|
3
|
+
# and obj = MyClass.new(:key => :value); obj.key = :new_value; obj.key # => :new_value
|
4
|
+
RSpec::Matchers.define :have_an_initialization_accessor_for do |attr|
|
5
|
+
match do |klass|
|
6
|
+
obj = klass.new(attr => :value)
|
7
|
+
obj.send(attr).should eql(:value)
|
8
|
+
obj.send("#{attr}=", :value2)
|
9
|
+
obj.send(attr).should eql(:value2)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
name: I spy
|
2
|
+
variables:
|
3
|
+
-
|
4
|
+
name: bigger-than-a-breadbox
|
5
|
+
properties:
|
6
|
+
- Generic content that fits inside the variable or node
|
7
|
+
- Yet more content, properties are typically an array
|
8
|
+
- For the simplest of variables, we can just do an inline hash, like below.
|
9
|
+
- name: this-side-of-the-room
|
10
|
+
- name: bigger-than-an-apple
|
11
|
+
- name: useful-on-a-deserted-island
|
12
|
+
- name: something-i-would-use
|
13
|
+
- name: alarm-clock
|
14
|
+
- name: laptop
|
15
|
+
- name: hair-dryer
|
16
|
+
- name: pocket-knife
|
17
|
+
|
18
|
+
edges:
|
19
|
+
-
|
20
|
+
parent: bigger-than-a-breadbox
|
21
|
+
child: bigger-than-an-apple
|
22
|
+
|
23
|
+
-
|
24
|
+
parent: bigger-than-a-breadbox
|
25
|
+
child: this-side-of-the-room
|
26
|
+
-
|
27
|
+
parent: bigger-than-a-breadbox
|
28
|
+
child: bigger-than-an-apple
|
29
|
+
|
30
|
+
definitions:
|
31
|
+
-
|
32
|
+
for: y
|
33
|
+
given:
|
34
|
+
- e1
|
35
|
+
- e2
|
36
|
+
table:
|
37
|
+
-
|
38
|
+
- 0.9
|
39
|
+
- 0.1
|
40
|
+
-
|
41
|
+
- 0.1
|
42
|
+
- 0.9
|