fathom 0.3.7 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/.autotest +7 -5
  2. data/.document +2 -2
  3. data/Gemfile +9 -10
  4. data/{LICENSE → LICENSE.txt} +1 -1
  5. data/README.md +29 -90
  6. data/Rakefile +34 -32
  7. data/VERSION +1 -1
  8. data/fathom.gemspec +105 -0
  9. data/features/fathom.feature +26 -0
  10. data/features/step_definitions/fathom_steps.rb +23 -0
  11. data/features/support/env.rb +13 -0
  12. data/lib/ext/array.rb +6 -2
  13. data/lib/ext/string.rb +86 -7
  14. data/lib/fathom.rb +51 -88
  15. data/lib/fathom/behaviors/attribute_system.rb +91 -0
  16. data/lib/fathom/behaviors/context_behavior.rb +28 -0
  17. data/lib/fathom/behaviors/plugins.rb +16 -0
  18. data/lib/fathom/contexts/network_population.rb +47 -0
  19. data/lib/fathom/contexts/network_traversal.rb +4 -0
  20. data/lib/fathom/data/adjacency_matrix.rb +27 -0
  21. data/lib/fathom/data/definition.rb +22 -0
  22. data/lib/fathom/data/edge.rb +58 -0
  23. data/lib/fathom/data/network.rb +35 -0
  24. data/lib/fathom/data/outcome.rb +30 -0
  25. data/lib/fathom/data/property.rb +31 -0
  26. data/lib/fathom/data/variable.rb +59 -0
  27. data/lib/fathom/roles/general_graph_tools.rb +87 -0
  28. data/lib/fathom/roles/network_builder.rb +61 -0
  29. data/spec/fathom/behaviors/attribute_system_spec.rb +141 -0
  30. data/spec/fathom/behaviors/context_behavior_spec.rb +15 -0
  31. data/spec/fathom/behaviors/plugins_spec.rb +80 -0
  32. data/spec/fathom/contexts/network_population_spec.rb +55 -0
  33. data/spec/fathom/contexts/network_traversal_spec.rb +11 -0
  34. data/spec/fathom/data/adjacency_matrix_spec.rb +42 -0
  35. data/spec/fathom/data/definition_spec.rb +19 -0
  36. data/spec/fathom/data/edge_spec.rb +77 -0
  37. data/spec/fathom/data/network_spec.rb +72 -0
  38. data/spec/fathom/data/outcome_spec.rb +17 -0
  39. data/spec/fathom/data/property_spec.rb +17 -0
  40. data/spec/fathom/data/variable_spec.rb +101 -0
  41. data/spec/fathom/ext/array_spec.rb +17 -0
  42. data/spec/fathom/ext/string_spec.rb +90 -0
  43. data/spec/fathom/roles/general_graph_tools_spec.rb +95 -0
  44. data/spec/fathom/roles/network_builder_spec.rb +90 -0
  45. data/spec/fathom_spec.rb +28 -49
  46. data/spec/spec_helper.rb +7 -11
  47. data/spec/support/context_behavior.rb +14 -0
  48. data/spec/support/custom_matchers.rb +12 -0
  49. data/spec/support/files.rb +8 -0
  50. data/spec/support/network.yml +42 -0
  51. metadata +133 -174
  52. data/.bundle/config +0 -2
  53. data/.gitignore +0 -6
  54. data/Gemfile.lock +0 -42
  55. data/TODO.md +0 -127
  56. data/autotest/discover.rb +0 -1
  57. data/lib/ext/faster_csv.rb +0 -1
  58. data/lib/ext/open_struct.rb +0 -17
  59. data/lib/fathom/agent.rb +0 -48
  60. data/lib/fathom/agent/agent_cluster.rb +0 -23
  61. data/lib/fathom/agent/properties.rb +0 -48
  62. data/lib/fathom/archive/causal_graph.rb +0 -12
  63. data/lib/fathom/archive/concept.rb +0 -83
  64. data/lib/fathom/archive/conditional_probability_matrix.rb +0 -119
  65. data/lib/fathom/archive/inverter.rb +0 -20
  66. data/lib/fathom/archive/n2.rb +0 -198
  67. data/lib/fathom/archive/n3.rb +0 -119
  68. data/lib/fathom/archive/node.rb +0 -97
  69. data/lib/fathom/archive/noodle.rb +0 -136
  70. data/lib/fathom/archive/scratch.rb +0 -45
  71. data/lib/fathom/distributions.rb +0 -8
  72. data/lib/fathom/distributions/discrete_gaussian.rb +0 -44
  73. data/lib/fathom/distributions/discrete_uniform.rb +0 -25
  74. data/lib/fathom/distributions/gaussian.rb +0 -46
  75. data/lib/fathom/distributions/uniform.rb +0 -35
  76. data/lib/fathom/import.rb +0 -85
  77. data/lib/fathom/import/csv_import.rb +0 -59
  78. data/lib/fathom/import/import_node.rb +0 -17
  79. data/lib/fathom/import/yaml_import.rb +0 -74
  80. data/lib/fathom/knowledge_base.rb +0 -46
  81. data/lib/fathom/knowledge_base/search.rb +0 -19
  82. data/lib/fathom/monte_carlo_set.rb +0 -152
  83. data/lib/fathom/node.rb +0 -139
  84. data/lib/fathom/node/belief_node.rb +0 -121
  85. data/lib/fathom/node/cpm_node.rb +0 -100
  86. data/lib/fathom/node/data_collection.rb +0 -97
  87. data/lib/fathom/node/data_node.rb +0 -22
  88. data/lib/fathom/node/decision.rb +0 -11
  89. data/lib/fathom/node/discrete_node.rb +0 -41
  90. data/lib/fathom/node/fact.rb +0 -24
  91. data/lib/fathom/node/mc_node.rb +0 -70
  92. data/lib/fathom/node/node_extensions/enforced_name.rb +0 -12
  93. data/lib/fathom/node/node_extensions/numeric_methods.rb +0 -68
  94. data/lib/fathom/node/plausible_range.rb +0 -98
  95. data/lib/fathom/simulation.rb +0 -59
  96. data/lib/fathom/simulation/tick_methods.rb +0 -25
  97. data/lib/fathom/simulation/tick_simulation.rb +0 -12
  98. data/lib/fathom/value_description.rb +0 -79
  99. data/lib/options_hash.rb +0 -186
  100. data/spec/ext/array_spec.rb +0 -10
  101. data/spec/ext/faster_csv_spec.rb +0 -10
  102. data/spec/ext/open_struct_spec.rb +0 -20
  103. data/spec/ext/string_spec.rb +0 -7
  104. data/spec/fathom/agent/agent_cluster_spec.rb +0 -17
  105. data/spec/fathom/agent_spec.rb +0 -51
  106. data/spec/fathom/distributions/discrete_gaussian_spec.rb +0 -64
  107. data/spec/fathom/distributions/discrete_uniform_spec.rb +0 -0
  108. data/spec/fathom/distributions/gaussian_spec.rb +0 -64
  109. data/spec/fathom/distributions/uniform_spec.rb +0 -0
  110. data/spec/fathom/import/csv_import_spec.rb +0 -52
  111. data/spec/fathom/import/import_node_spec.rb +0 -10
  112. data/spec/fathom/import/yaml_import_spec.rb +0 -73
  113. data/spec/fathom/import_spec.rb +0 -36
  114. data/spec/fathom/knowledge_base_spec.rb +0 -20
  115. data/spec/fathom/monte_carlo_set_spec.rb +0 -149
  116. data/spec/fathom/node/belief_node_spec.rb +0 -180
  117. data/spec/fathom/node/cpm_node_spec.rb +0 -144
  118. data/spec/fathom/node/data_collection_spec.rb +0 -26
  119. data/spec/fathom/node/data_node_spec.rb +0 -102
  120. data/spec/fathom/node/decision_spec.rb +0 -15
  121. data/spec/fathom/node/discrete_node_spec.rb +0 -56
  122. data/spec/fathom/node/fact_spec.rb +0 -33
  123. data/spec/fathom/node/mc_node_spec.rb +0 -66
  124. data/spec/fathom/node/node_extensions/enforced_name_spec.rb +0 -15
  125. data/spec/fathom/node/node_extensions/numeric_methods_spec.rb +0 -124
  126. data/spec/fathom/node/plausible_range_spec.rb +0 -151
  127. data/spec/fathom/node_spec.rb +0 -172
  128. data/spec/fathom/simulation/tick_simulation_spec.rb +0 -32
  129. data/spec/fathom/simulation_spec.rb +0 -24
  130. data/spec/fathom/value_description_spec.rb +0 -70
  131. data/spec/support/demo.yml +0 -17
  132. data/spec/support/demo_agent.rb +0 -8
  133. data/spec/support/dummy_numeric_node.rb +0 -8
  134. 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
@@ -1,56 +1,35 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- describe "Fathom" do
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
- it "should alias kb for knowledge_base" do
14
- Fathom.kb.should eql(Fathom.knowledge_base)
15
- end
16
- end
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
- For this demo, I picked up a project I had been working on. I added a Monte Carlo analysis that
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
@@ -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 'rspec/autorun'
7
-
8
- include Fathom
4
+ require 'fathom'
9
5
 
10
- # Requires supporting ruby files in spec/support/ and its subdirectories.
11
- Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each {|f| require f}
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 |c|
14
- # c.filter_run :focus => true
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,8 @@
1
+ def network_contents_in_yaml_filename
2
+ File.expand_path('../network.yml', __FILE__)
3
+ end
4
+
5
+ def network_contents_in_yaml
6
+ File.read(network_contents_in_yaml_filename)
7
+ end
8
+
@@ -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