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,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,11 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe NetworkTraversal do
6
+
7
+ # context "when searching a directed graph" do
8
+ # before do
9
+ # @edges =
10
+ # end
11
+ 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