aniero-treehouse 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +43 -0
  3. data/README.txt +102 -0
  4. data/Rakefile +25 -0
  5. data/examples/simple_assignment.rb +54 -0
  6. data/lib/treehouse.rb +52 -0
  7. data/lib/treehouse/metaid.rb +16 -0
  8. data/lib/treehouse/node.rb +79 -0
  9. data/lib/treehouse/node_creator.rb +28 -0
  10. data/lib/treehouse/node_definition.rb +106 -0
  11. data/lib/treehouse/visitor.rb +49 -0
  12. data/lib/treehouse/visitor_definition.rb +49 -0
  13. data/spec/fixtures/assignments.txt +7 -0
  14. data/spec/fixtures/ey00-s00348.xen +14 -0
  15. data/spec/grammars/assignments.rb +38 -0
  16. data/spec/grammars/assignments.treetop +42 -0
  17. data/spec/grammars/dot_xen.rb +122 -0
  18. data/spec/grammars/dot_xen.treetop +100 -0
  19. data/spec/grammars/magic.rb +63 -0
  20. data/spec/integration/assignments_spec.rb +45 -0
  21. data/spec/integration/dot_xen_spec.rb +86 -0
  22. data/spec/integration/magic_spec.rb +40 -0
  23. data/spec/node_creator_spec.rb +47 -0
  24. data/spec/node_definition_spec.rb +60 -0
  25. data/spec/node_spec.rb +131 -0
  26. data/spec/spec_helper.rb +34 -0
  27. data/spec/treehouse_spec.rb +17 -0
  28. data/spec/visitor_definition_spec.rb +44 -0
  29. data/spec/visitor_spec.rb +48 -0
  30. data/tasks/ann.rake +81 -0
  31. data/tasks/bones.rake +21 -0
  32. data/tasks/gem.rake +126 -0
  33. data/tasks/git.rake +41 -0
  34. data/tasks/manifest.rake +49 -0
  35. data/tasks/notes.rake +28 -0
  36. data/tasks/post_load.rake +39 -0
  37. data/tasks/rdoc.rake +51 -0
  38. data/tasks/rubyforge.rake +57 -0
  39. data/tasks/setup.rb +268 -0
  40. data/tasks/spec.rake +55 -0
  41. data/tasks/svn.rake +48 -0
  42. data/tasks/test.rake +38 -0
  43. data/treehouse.gemspec +38 -0
  44. metadata +124 -0
@@ -0,0 +1,45 @@
1
+ require File.join(File.dirname(__FILE__), %w[.. spec_helper])
2
+
3
+ require Treehouse.path(%w(spec grammars assignments))
4
+
5
+ describe AssignmentsLanguage::Grammar do
6
+
7
+ it "has nodes defined" do
8
+ consts = AssignmentsLanguage::Grammar.constants
9
+ consts.should include("Assignments")
10
+ consts.should include("Assignment")
11
+ consts.should include("BlankLine")
12
+ end
13
+
14
+ end
15
+
16
+ describe AssignmentsLanguage::Parser, ".parse" do
17
+
18
+ before(:each) do
19
+ @input = File.read(Treehouse.path(%w(spec fixtures assignments.txt)))
20
+ end
21
+
22
+ it "parses a file and returns a Treehouse AST" do
23
+ AssignmentsLanguage::Parser.parse(@input).should be_a_kind_of(Treehouse::Node)
24
+ end
25
+
26
+ end
27
+
28
+ describe AssignmentsLanguage do
29
+ it "has a string visitor defined" do
30
+ AssignmentsLanguage.const_get("StringVisitor").ancestors.should include(Treehouse::Visitor)
31
+ end
32
+ end
33
+
34
+ describe AssignmentsLanguage::StringVisitor do
35
+ before(:each) do
36
+ @input = File.read(Treehouse.path(%w(spec fixtures assignments.txt)))
37
+ @ast = AssignmentsLanguage::Parser.parse(@input)
38
+ end
39
+
40
+ describe "#visit" do
41
+ it "traverses the AST and collects the values" do
42
+ AssignmentsLanguage::StringVisitor.visit(@ast).should == "foo = bar\nbaz = blech\nno = way\n"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,86 @@
1
+ require File.join(File.dirname(__FILE__), %w[.. spec_helper])
2
+
3
+ require Treehouse.path(%w(spec grammars dot_xen))
4
+
5
+ describe DotXen::Parser, ".parse" do
6
+ before(:each) do
7
+ data = File.read(Treehouse.path(%w(spec fixtures ey00-s00348.xen)))
8
+ @ast = DotXen::Parser.parse(data)
9
+ end
10
+ it "returns an AST" do
11
+ @ast.should_not be_nil
12
+ end
13
+
14
+ describe "with a parsed AST" do
15
+ it "has a comment" do
16
+ @ast.should have(1).comments
17
+ end
18
+
19
+ it "has 3 disks" do
20
+ @ast.should have(3).disks
21
+ end
22
+
23
+ it "has vars" do
24
+ @ast.should have_at_least(5).vars
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ describe DotXen::HashVisitor do
32
+ before(:all) do
33
+ data = File.read(Treehouse.path(%w(spec fixtures ey00-s00348.xen)))
34
+ @ast = DotXen::Parser.parse(data)
35
+ end
36
+
37
+ describe ".visit" do
38
+ it "returns a hash representation of the AST" do
39
+ DotXen::HashVisitor.visit(@ast).should == {
40
+ :comments => [" -*- mode: python; -*-"],
41
+ :disks => [
42
+ "phy:/dev/ey00-data4/root-s00348,sda1,w",
43
+ "phy:/dev/ey00-data4/swap-s00348,sda2,w",
44
+ "phy:/dev/ey00-data4/gfs-00218,sdb1,w!"
45
+ ],
46
+ :vars => {
47
+ "name" => "ey00-s00348",
48
+ "kernel" => "/boot/vmlinuz-2.6.18-xenU",
49
+ "memory" => 712,
50
+ "cpu_cap" => 100,
51
+ "vcpus" => 1,
52
+ "root" => "/dev/sda1 ro",
53
+ "maxmem" => 4096,
54
+ "vif" => ["bridge=xenbr0"]
55
+ }
56
+ }
57
+ end
58
+ end
59
+ end
60
+
61
+ describe DotXen::StringVisitor do
62
+ before(:all) do
63
+ data = File.read(Treehouse.path(%w(spec fixtures ey00-s00348.xen)))
64
+ @ast = DotXen::Parser.parse(data)
65
+ end
66
+ describe ".visit" do
67
+ it "returns a string representation of the AST" do
68
+ DotXen::StringVisitor.visit(@ast).should == <<-EOS
69
+ # -*- mode: python; -*-
70
+ kernel = '/boot/vmlinuz-2.6.18-xenU'
71
+ memory = 712
72
+ maxmem = 4096
73
+ name = 'ey00-s00348'
74
+ vif = [ 'bridge=xenbr0' ]
75
+ root = "/dev/sda1 ro"
76
+ vcpus = 1
77
+ cpu_cap = 100
78
+ disk = [
79
+ "phy:/dev/ey00-data4/root-s00348,sda1,w",
80
+ "phy:/dev/ey00-data4/swap-s00348,sda2,w",
81
+ "phy:/dev/ey00-data4/gfs-00218,sdb1,w!"
82
+ ]
83
+ EOS
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,40 @@
1
+ require File.join(File.dirname(__FILE__), %w[.. spec_helper])
2
+
3
+ require Treehouse.path(%w(spec grammars magic))
4
+
5
+ describe MagicAssignments::Parser do
6
+ describe ".parse" do
7
+ before(:each) do
8
+ @input = File.read(Treehouse.path(%w(spec fixtures assignments.txt)))
9
+ @result = MagicAssignments::Parser.parse(@input)
10
+ end
11
+
12
+ it "returns an AST" do
13
+ @result.should be_an_instance_of(MagicAssignments::AST::Assignments)
14
+ end
15
+
16
+ it "has the right number of nodes" do
17
+ @result.should have(7).assignments
18
+ end
19
+
20
+ it "has an assignment with correct values" do
21
+ @result.assignments.first.should be_an_instance_of(MagicAssignments::AST::Assignment)
22
+ @result.assignments.first.lhs.value.should == "foo"
23
+ @result.assignments.first.rhs.value.should == "bar"
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ describe MagicAssignments::HashVisitor do
30
+ describe ".visit" do
31
+ it "returns a hash representation of the assignments" do
32
+ ast = MagicAssignments::Parser.parse(File.read(Treehouse.path(%w(spec fixtures assignments.txt))))
33
+ MagicAssignments::HashVisitor.visit(ast).should == {
34
+ "foo" => "bar",
35
+ "baz" => "blech",
36
+ "no" => "way"
37
+ }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,47 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ describe Treehouse::NodeCreator do
4
+
5
+ before(:all) do
6
+ SomeNode = Class.new(Treehouse::Node)
7
+ end
8
+ after(:all) do
9
+ Object.send(:remove_const, "SomeNode")
10
+ end
11
+
12
+ describe "#initialize" do
13
+
14
+ it "takes a class as an argument" do
15
+ nc = Treehouse::NodeCreator.new(SomeNode)
16
+ end
17
+ end
18
+
19
+ describe "#new" do
20
+ before(:each) do
21
+ @nc = Treehouse::NodeCreator.new(SomeNode)
22
+ end
23
+
24
+ it "takes parameters as if it were a treetop syntax node" do
25
+ @nc.new("what", 0..3)
26
+ end
27
+
28
+ it "returns a treetop syntax node" do
29
+ node = @nc.new("what", 0..3)
30
+ node.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
31
+ end
32
+
33
+ it "defines a build method on the syntax node" do
34
+ node = @nc.new("what", 0..3)
35
+ node.methods.should include("build")
36
+ end
37
+
38
+ it "creates an instance of the defined class when build is called on the resulting syntax node" do
39
+ node = @nc.new("what", 0..3)
40
+ mock_node = mock("node")
41
+ SomeNode.should_receive(:new).with(node).and_return(mock_node)
42
+ node.build.should == mock_node
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,60 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ describe Treehouse::NodeDefinition do
4
+ module TestNodes
5
+ include Treehouse::NodeDefinition
6
+ end
7
+
8
+ it "adds a node method when included" do
9
+ TestNodes.methods.should include("node")
10
+ end
11
+
12
+ it "adds a create_node method when included" do
13
+ TestNodes.methods.should include("create_node")
14
+ end
15
+
16
+ describe ".node" do
17
+ before(:each) do
18
+ TestNodes.class_eval { node :foo, :bar, :baz }
19
+ end
20
+ after(:each) do
21
+ TestNodes.send(:remove_const, "Foo")
22
+ end
23
+
24
+ it "defines a class" do
25
+ TestNodes.constants.should include("Foo")
26
+ TestNodes::Foo.ancestors.should include(Treehouse::Node)
27
+ end
28
+
29
+ it "defines a class with an attribute for each of the provided arguments" do
30
+ TestNodes::Foo.instance_methods.should include("bar")
31
+ TestNodes::Foo.instance_methods.should include("baz")
32
+ end
33
+
34
+ end
35
+
36
+ describe ".create_node" do
37
+ before(:all) do
38
+ TestNodes.class_eval { node :foo_node }
39
+ end
40
+ after(:all) do
41
+ TestNodes.send(:remove_const, "FooNode")
42
+ end
43
+
44
+ it "takes a node name as an argument" do
45
+ TestNodes.create_node(:foo_node)
46
+ end
47
+
48
+ it "returns an instance of NodeCreator" do
49
+ TestNodes.create_node(:foo_node).should be_an_instance_of(Treehouse::NodeCreator)
50
+ end
51
+
52
+ it "instantiates the node creator with the class corresponding to the node name" do
53
+ obj = Object.new
54
+ Treehouse::NodeCreator.should_receive(:new).with(TestNodes::FooNode).and_return(obj)
55
+ TestNodes.create_node(:foo_node).should == obj
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,131 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ describe Treehouse::Node do
4
+
5
+ describe ".create" do
6
+ it "returns a class that inherits from Treehouse::Node" do
7
+ klass = Treehouse::Node.create
8
+ klass.should be_an_instance_of(Class)
9
+ klass.ancestors.should include(Treehouse::Node)
10
+ end
11
+
12
+ describe "with attribute names" do
13
+ before(:each) do
14
+ @node = Treehouse::Node.create(:foo, :bar)
15
+ end
16
+
17
+ it "creates a class with the given attributes" do
18
+ n = @node.new(:foo => 1, :bar => 2)
19
+ n.foo.should == 1
20
+ n.bar.should == 2
21
+ end
22
+
23
+ it "creates attributes with a default of raising an exception if not initialized" do
24
+ n = @node.new(:foo => 1) # no :bar
25
+ n.foo.should == 1
26
+ lambda { n.bar }.should raise_error(RuntimeError, "no value given for bar")
27
+ end
28
+
29
+ end
30
+
31
+ describe "with an attribute hash" do
32
+ before(:each) do
33
+ @node = Treehouse::Node.create(:lhs => :left_value, :rhs => :right_value)
34
+ end
35
+
36
+ it "creates a class with attributes matching the hash keys" do
37
+ @node.attributes.sort.should == ["lhs", "rhs"]
38
+ end
39
+
40
+ it "creates attributes with a default of raising an exception if not set" do
41
+ n = @node.new
42
+ lambda { n.lhs }.should raise_error(RuntimeError, "no value given for lhs")
43
+ end
44
+
45
+ it "returns a class with an attribute mapping" do
46
+ @node.attribute_mapping.should == {"lhs" => :left_value, "rhs" => :right_value}
47
+ end
48
+
49
+ end
50
+
51
+ describe "with a mix of named attributes and hash attributes" do
52
+ before(:each) do
53
+ @node = Treehouse::Node.create(:one, :two, :three => :value)
54
+ end
55
+
56
+ it "creates a class with attributes matching the named attributes and hash keys" do
57
+ @node.attributes.should == %w(one two three)
58
+ end
59
+
60
+ it "updates the attribute mapping" do
61
+ @node.attribute_mapping.should == {"three" => :value}
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ describe ".new" do
69
+ before(:each) do
70
+ @node = Treehouse::Node.create(:child, :value => :data)
71
+ end
72
+
73
+ describe "with empty args" do
74
+ it "initializes a node without touching the attributes" do
75
+ n = @node.new
76
+ lambda { n.child }.should raise_error(RuntimeError)
77
+ end
78
+ end
79
+
80
+ describe "with a hash" do
81
+ it "initializes each of the attributes to the given value" do
82
+ n = @node.new(:child => 1, :value => 2)
83
+ n.child.should == 1
84
+ n.value.should == 2
85
+ end
86
+ end
87
+
88
+ describe "with an instance of Treetop::Runtime::SyntaxNode" do
89
+ before(:each) do
90
+ @child = mock_syntax_node :build => "child value"
91
+ @top = mock_syntax_node :child => @child, :data => "data"
92
+ end
93
+
94
+ it "sets the named values by calling build on the named child node" do
95
+ @top.should_receive(:child).and_return(@child)
96
+ @child.should_receive(:build).and_return("child value")
97
+ n = @node.new(@top)
98
+ n.child.should == "child value"
99
+ end
100
+
101
+ it "calls the specified method directly for hash values" do
102
+ @top.should_receive(:data).and_return do
103
+ puts "called from #{caller.detect {|c| c !~ /rspec/}}"
104
+ "foo"
105
+ end
106
+ n = @node.new(@top)
107
+ n.value.should == "foo"
108
+ end
109
+
110
+ it "calls build on each element of a referenced node value if that value is an array" do
111
+ @top.should_receive(:child).and_return([@child, @child])
112
+ @child.should_receive(:build).exactly(2).times.and_return("one", "two")
113
+ n = @node.new(@top)
114
+ n.child.should == %w(one two)
115
+ end
116
+
117
+ it "only calls build on elements of an array if they respond to that method" do
118
+ @top.should_receive(:child).and_return([@child, "blah"])
119
+ @node.new(@top).child.should == ["child value", "blah"]
120
+ end
121
+
122
+ it "yields the syntax node instance if a mapped attribute is a lambda" do
123
+ @node = Treehouse::Node.create(:value => lambda { |x| @x = x })
124
+ @node.new(@top)
125
+ @x.should == @top
126
+ end
127
+
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib treehouse]))
2
+
3
+ Spec::Runner.configure do |config|
4
+ # == Mock Framework
5
+ #
6
+ # RSpec uses it's own mocking framework by default. If you prefer to
7
+ # use mocha, flexmock or RR, uncomment the appropriate line:
8
+ #
9
+ # config.mock_with :mocha
10
+ # config.mock_with :flexmock
11
+ # config.mock_with :rr
12
+
13
+ # borrowed from rspec_on_rails' mock_model
14
+ def mock_syntax_node(stubs={})
15
+ m = mock "mock syntax node", stubs
16
+ m.send(:__mock_proxy).instance_eval do
17
+ def @target.is_a?(other)
18
+ Treetop::Runtime::SyntaxNode.ancestors.include?(other)
19
+ end
20
+ def @target.kind_of?(other)
21
+ Treetop::Runtime::SyntaxNode.ancestors.include?(other)
22
+ end
23
+ def @target.instance_of?(other)
24
+ other == Treetop::Runtime::SyntaxNode
25
+ end
26
+ def @target.class
27
+ Treetop::Runtime::SyntaxNode
28
+ end
29
+ end
30
+ yield m if block_given?
31
+ m
32
+ end
33
+
34
+ end