rouge-lang 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'rouge'
4
+ require 'term/ansicolor'
5
+
6
+ describe Rouge do
7
+ before do
8
+ Rouge.boot!
9
+ end
10
+
11
+ describe "the rouge.core namespace" do
12
+ before do
13
+ @ns = Rouge[:"rouge.core"]
14
+ end
15
+
16
+ it "should contain the defn macro" do
17
+ lambda {
18
+ @ns[:defn].should be_an_instance_of Rouge::Macro
19
+ }.should_not raise_exception(Rouge::Context::BindingNotFoundError)
20
+ end
21
+ end
22
+
23
+ describe "the user namespace" do
24
+ before do
25
+ @ns = Rouge[:user]
26
+ end
27
+
28
+ it "should refer rouge.builtin, rouge.core and ruby" do
29
+ @ns.refers.should include(Rouge[:"rouge.builtin"])
30
+ @ns.refers.should include(Rouge[:"rouge.core"])
31
+ @ns.refers.should include(Rouge[:"ruby"])
32
+ end
33
+ end
34
+
35
+ describe "the Rouge specs" do
36
+ Dir[relative_to_spec("*.rg")].each do |file|
37
+ it "should pass #{File.basename file}" do
38
+ begin
39
+ r = Rouge::Context.new(Rouge[:user]).readeval(File.read(file))
40
+ rescue => e
41
+ STDOUT.puts Term::ANSIColor.red("#{e.class}: #{e.message}")
42
+ STDOUT.puts Term::ANSIColor.red(e.backtrace.join("\n"))
43
+ r = {:passed => 0, :failed => [["exception"]]}
44
+ end
45
+
46
+ total = r[:passed] + r[:failed].length
47
+
48
+ message =
49
+ "#{total} example#{total == 1 ? "" : "s"}, " +
50
+ "#{r[:failed].length} failure#{r[:failed].length == 1 ? "" : "s"}"
51
+
52
+ if r[:failed].length > 0
53
+ STDOUT.puts Term::ANSIColor.red(message)
54
+ raise RuntimeError,
55
+ "#{r[:failed].length} failed " +
56
+ "case#{r[:failed].length == 1 ? "" : "s"} in #{file}:\n" +
57
+ r[:failed].map {|ex| " - #{ex.join(" -> ")}"}.join("\n")
58
+ else
59
+ STDOUT.puts Term::ANSIColor.green(message)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ # vim: set sw=2 et cc=80:
data/spec/seq_spec.rb ADDED
@@ -0,0 +1,202 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'rouge'
4
+
5
+ describe Rouge::Seq::ASeq do
6
+ let(:seq) do
7
+ Class.new do
8
+ include Rouge::Seq::ASeq
9
+ def to_a; [:q]; end
10
+ end.new
11
+ end
12
+
13
+ describe "#seq" do
14
+ it "should return the original object" do
15
+ seq.seq.should be seq
16
+ end
17
+ end
18
+
19
+ describe "the unimplemented methods" do
20
+ it { expect { seq.first
21
+ }.to raise_exception NotImplementedError }
22
+
23
+ it { expect { seq.next
24
+ }.to raise_exception NotImplementedError }
25
+ end
26
+
27
+ describe "#more" do
28
+ it "should return the value of next" do
29
+ r = double("next result")
30
+ seq.should_receive(:next).and_return(r)
31
+ seq.more.should be r
32
+ end
33
+
34
+ it "should return an empty list if next returns nil" do
35
+ r = double("next result")
36
+ seq.should_receive(:next).and_return(nil)
37
+ seq.more.should eq Rouge::Seq::Empty
38
+ end
39
+ end
40
+
41
+ describe "#cons" do
42
+ let(:head) { double("head") }
43
+
44
+ before { Rouge::Seq::Cons.should_receive(:new).with(head, seq) }
45
+ it { seq.cons(head) }
46
+ end
47
+
48
+ describe "#[]" do
49
+ let(:numbers) { Rouge::Seq::Cons[1, 2, 3] }
50
+
51
+ it { numbers[0].should eq 1 }
52
+ it { numbers[1].should eq 2 }
53
+
54
+ # XXX: unlike Clojure. Thoughts?
55
+ it { numbers[5].should eq nil }
56
+
57
+ it { numbers[-1].should eq 3 }
58
+ it { numbers[-2].should eq 2 }
59
+
60
+ # XXX: or generic seqs/lazyseqs/arrayseqs ...?
61
+ # to preserve Ruby interop probably straight Arrays.
62
+ # We won't be using this form from Rouge itself anyway.
63
+ it { numbers[0..-1].should eq [1, 2, 3] }
64
+ it { numbers[0..-2].should eq [1, 2] }
65
+ it { numbers[0...-2].should eq [1] }
66
+ it { numbers[2...-1].should eq [] }
67
+ it { numbers[2..-1].should eq [3] }
68
+ end
69
+
70
+ describe "#==" do
71
+ it { Rouge::Seq::Array.new([:q], 0).should eq seq }
72
+ it { Rouge::Seq::Array.new([:q, :r], 0).
73
+ should eq Rouge::Seq::Cons[:q, :r] }
74
+ end
75
+
76
+ describe "#each" do
77
+ it { Rouge::Seq::Cons[1].each.should be_an_instance_of Enumerator }
78
+ end
79
+ end
80
+
81
+ describe Rouge::Seq::Cons do
82
+ describe ".new" do
83
+ it { expect { Rouge::Seq::Cons.new(1, Rouge::Seq::Empty)
84
+ }.to_not raise_exception }
85
+
86
+ it { expect { Rouge::Seq::Cons.new(1, nil)
87
+ }.to_not raise_exception }
88
+
89
+ it { expect { Rouge::Seq::Cons.new(1, Rouge::Seq::Cons[:x])
90
+ }.to_not raise_exception }
91
+
92
+ it { expect { Rouge::Seq::Cons.new(1, Rouge::Seq::Array.new([], 0))
93
+ }.to_not raise_exception }
94
+
95
+ it { expect { Rouge::Seq::Cons.new(1, "blah")
96
+ }.to raise_exception(ArgumentError) }
97
+ end
98
+
99
+ describe ".[]" do
100
+ it { Rouge::Seq::Cons[].should eq Rouge::Seq::Empty }
101
+ it { Rouge::Seq::Cons[1].
102
+ should eq Rouge::Seq::Cons.new(1, Rouge::Seq::Empty) }
103
+ it { Rouge::Seq::Cons[1].should eq Rouge::Seq::Cons.new(1, nil) }
104
+ it { Rouge::Seq::Cons[1, 2].
105
+ should eq Rouge::Seq::Cons.new(
106
+ 1, Rouge::Seq::Cons.new(2, Rouge::Seq::Empty)) }
107
+ it { Rouge::Seq::Cons[1, 2, 3].
108
+ should eq Rouge::Seq::Cons.new(1,
109
+ Rouge::Seq::Cons.new(2,
110
+ Rouge::Seq::Cons.new(3, Rouge::Seq::Empty))) }
111
+ end
112
+
113
+ describe "#inspect" do
114
+ it { Rouge::Seq::Cons[].inspect.should eq "()" }
115
+ it { Rouge::Seq::Cons[1].inspect.should eq "(1)" }
116
+ it { Rouge::Seq::Cons[1, 2].inspect.should eq "(1 2)" }
117
+ it { Rouge::Seq::Cons[1, 2, 3].inspect.should eq "(1 2 3)" }
118
+ it { Rouge::Seq::Cons[1, 2, 3].tail.inspect.should eq "(2 3)" }
119
+ end
120
+
121
+ describe "the ASeq implementation" do
122
+ subject { Rouge::Seq::Cons[1, 2, 3] }
123
+
124
+ describe "#first" do
125
+ its(:first) { should eq 1 }
126
+ end
127
+
128
+ describe "#next" do
129
+ its(:next) { should be_an_instance_of Rouge::Seq::Cons }
130
+ its(:next) { should eq Rouge::Seq::Cons[2, 3] }
131
+ it { subject.next.next.next.should eq nil }
132
+ end
133
+ end
134
+ end
135
+
136
+ describe Rouge::Seq::Array do
137
+ describe "#first" do
138
+ it { Rouge::Seq::Array.new([:a, :b, :c], 0).first.should eq :a }
139
+ it { Rouge::Seq::Array.new([:a, :b, :c], 1).first.should eq :b }
140
+ it { Rouge::Seq::Array.new([:a, :b, :c], 2).first.should eq :c }
141
+ end
142
+
143
+ describe "#next" do
144
+ subject { Rouge::Seq::Array.new([:a, :b, :c], 0).next }
145
+
146
+ it { should be_an_instance_of Rouge::Seq::Array }
147
+ it { should eq [:b, :c] }
148
+ end
149
+ end
150
+
151
+ describe Rouge::Seq::Lazy do
152
+ let(:sentinel) { double("sentinel") }
153
+ let(:trigger) { Rouge::Seq::Lazy.new(lambda { sentinel.call }) }
154
+ let(:non_seq) { Rouge::Seq::Lazy.new(lambda { 7 }) }
155
+ let(:error) { Rouge::Seq::Lazy.new(lambda { raise "boom" }) }
156
+
157
+ describe "not evalled until necessary" do
158
+ context "not realised" do
159
+ before { sentinel.should_not_receive(:call) }
160
+ it { trigger }
161
+ end
162
+
163
+ context "realised" do
164
+ before { sentinel.should_receive(:call).and_return [1, 2] }
165
+
166
+ it { trigger.seq.should eq [1, 2] }
167
+ it { trigger.first.should eq 1 }
168
+ it { trigger.next.should eq [2] }
169
+ end
170
+ end
171
+
172
+ describe "not multiply evalled on non-seq" do
173
+ it do
174
+ # Weird, but most similar to Clojure (by experiment).
175
+ expect { non_seq.seq }.to raise_exception
176
+ expect { non_seq.seq.should be Rouge::Seq::Empty
177
+ }.to_not raise_exception
178
+ end
179
+ end
180
+
181
+ describe "multiply evalled on error" do
182
+ it do
183
+ expect { error.seq }.to raise_exception
184
+ expect { error.seq }.to raise_exception
185
+ end
186
+ end
187
+ end
188
+
189
+ describe Rouge::Seq do
190
+ describe ".seq" do
191
+ context Array do
192
+ subject { Rouge::Seq.seq([:a]) }
193
+ it { should be_an_instance_of Rouge::Seq::Array }
194
+ it { should eq Rouge::Seq::Array.new([:a], 0) }
195
+
196
+ let(:arrayseq) { Rouge::Seq::Array.new([:a], 0) }
197
+ it { Rouge::Seq.seq(arrayseq).should be arrayseq }
198
+ end
199
+ end
200
+ end
201
+
202
+ # vim: set sw=2 et cc=80:
@@ -0,0 +1,12 @@
1
+ require 'rspec/autorun'
2
+
3
+ RSpec.configure do |config|
4
+ config.order = 'random'
5
+ config.treat_symbols_as_metadata_keys_with_true_values = true
6
+ end
7
+
8
+ def relative_to_spec name
9
+ File.join(File.dirname(File.absolute_path(__FILE__)), name)
10
+ end
11
+
12
+ # vim: set sw=2 et cc=80:
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'rouge'
4
+
5
+ describe Rouge::Symbol do
6
+ describe "lookup" do
7
+ it { Rouge::Symbol[:true].should be true }
8
+ it { Rouge::Symbol[:false].should be false }
9
+ it { Rouge::Symbol[:nil].should be nil }
10
+ end
11
+
12
+ describe ".[]" do
13
+ it { Rouge::Symbol[:a].should_not be Rouge::Symbol[:a] }
14
+ # but:
15
+ it { Rouge::Symbol[:a].should eq Rouge::Symbol[:a] }
16
+ end
17
+
18
+ describe "#ns, #name" do
19
+ it { Rouge::Symbol[:abc].ns.should be_nil }
20
+ it { Rouge::Symbol[:abc].name.should eq :abc }
21
+ it { Rouge::Symbol[:"abc/def"].ns.should eq :abc }
22
+ it { Rouge::Symbol[:"abc/def"].name.should eq :def }
23
+ it { Rouge::Symbol[:/].ns.should be_nil }
24
+ it { Rouge::Symbol[:/].name.should eq :/ }
25
+ it { Rouge::Symbol[:"rouge.core//"].ns.should eq :"rouge.core" }
26
+ it { Rouge::Symbol[:"rouge.core//"].name.should eq :/ }
27
+ end
28
+
29
+ describe "#to_sym" do
30
+ it { Rouge::Symbol[:boo].to_sym.should eq :boo }
31
+ it { Rouge::Symbol[:"what/nice"].to_sym.should eq :"what/nice" }
32
+ end
33
+ end
34
+
35
+ # vim: set sw=2 et cc=80:
data/spec/var_spec.rb ADDED
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'rouge'
4
+
5
+ describe Rouge::Var do
6
+ describe "the constructor" do
7
+ it "creates an unbound var by default" do
8
+ v = Rouge::Var.new(:mop, :boo)
9
+ v.ns.should eq :mop
10
+ v.name.should eq :boo
11
+ v.deref.should be_an_instance_of Rouge::Var::Unbound
12
+ end
13
+
14
+ it "creates a bound var if requested" do
15
+ v = Rouge::Var.new(:quux, :huh, 99)
16
+ v.ns.should eq :quux
17
+ v.name.should eq :huh
18
+ v.deref.should eq 99
19
+ end
20
+ end
21
+
22
+ describe "equality" do
23
+ it "considers two vars equal if their nses and names are equal" do
24
+ Rouge::Var.new(:a, :a, :v).should == Rouge::Var.new(:a, :a, :v)
25
+ Rouge::Var.new(:a, :a, :w).should == Rouge::Var.new(:a, :a, :w)
26
+ Rouge::Var.new(:b, :a, :v).should_not == Rouge::Var.new(:a, :b, :v)
27
+ Rouge::Var.new(:b, :a, :v).should_not == Rouge::Var.new(:a, :a, :v)
28
+ end
29
+ end
30
+
31
+ describe "the stack" do
32
+ it "should override a var's root" do
33
+ v = Rouge::Var.new(:moop, :hello, :frank)
34
+ v.deref.should eq :frank
35
+
36
+ Rouge::Var.push({:hello => :joe})
37
+ v.deref.should eq :joe
38
+
39
+ Rouge::Var.push({:hello => :mark})
40
+ v.deref.should eq :mark
41
+
42
+ Rouge::Var.pop
43
+ v.deref.should eq :joe
44
+
45
+ Rouge::Var.pop
46
+ v.deref.should eq :frank
47
+ end
48
+ end
49
+ end
50
+
51
+ describe Rouge::Var::Unbound do
52
+ describe "the constructor" do
53
+ it "creates an unbound var's value" do
54
+ v = Rouge::Var.new(:raisin, :boo)
55
+ ub = Rouge::Var::Unbound.new(v)
56
+ ub.var.should be v
57
+ end
58
+ end
59
+ end
60
+
61
+ # vim: set sw=2 et cc=80:
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'rouge'
4
+
5
+ describe [
6
+ Rouge::Macro,
7
+ Rouge::Builtin,
8
+ Rouge::Dequote,
9
+ Rouge::Splice] do
10
+ describe "the constructor" do
11
+ it "should return a new wrapper" do
12
+ described_class.each do |klass|
13
+ klass.new(:abc).should be_an_instance_of klass
14
+ end
15
+ end
16
+
17
+ it "should function with the alternate form" do
18
+ described_class.each do |klass|
19
+ klass[:aoeu].should eq klass.new(:aoeu)
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "equality" do
25
+ it "should be true for two wrappers with the same underlying object" do
26
+ described_class.each do |klass|
27
+ klass.new(:xyz).should eq klass.new(:xyz)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "the inner getter" do
33
+ it "should return the object passed in" do
34
+ described_class.each do |klass|
35
+ klass.new(:boohoo).inner.should eq :boohoo
36
+ l = lambda {}
37
+ klass.new(l).inner.should eq l
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "the Puby pretty-printing" do
43
+ it "should resemble the [] constructor" do
44
+ described_class.each do |klass|
45
+ klass[:hello].inspect.should eq "#{klass.name}[:hello]"
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ # vim: set sw=2 et cc=80:
metadata ADDED
@@ -0,0 +1,216 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rouge-lang
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Arlen Christian Mart Cuss
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: autotest
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: autotest-growl
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: autotest-fsevent
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: ZenTest
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: term-ansicolor
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: Ruby + Clojure = Rouge.
127
+ email:
128
+ - ar@len.me
129
+ executables:
130
+ - rouge
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - .autotest
135
+ - .gitignore
136
+ - .rspec
137
+ - .travis.yml
138
+ - Gemfile
139
+ - LICENSE
140
+ - README.md
141
+ - Rakefile
142
+ - bin/rouge
143
+ - lib/boot.rg
144
+ - lib/rouge.rb
145
+ - lib/rouge/atom.rb
146
+ - lib/rouge/builtins.rb
147
+ - lib/rouge/compiler.rb
148
+ - lib/rouge/context.rb
149
+ - lib/rouge/metadata.rb
150
+ - lib/rouge/namespace.rb
151
+ - lib/rouge/printer.rb
152
+ - lib/rouge/reader.rb
153
+ - lib/rouge/repl.rb
154
+ - lib/rouge/seq.rb
155
+ - lib/rouge/symbol.rb
156
+ - lib/rouge/var.rb
157
+ - lib/rouge/version.rb
158
+ - lib/rouge/wrappers.rb
159
+ - misc/TODO
160
+ - misc/vimrc
161
+ - rouge-lang.gemspec
162
+ - spec/atom_spec.rb
163
+ - spec/builtins_spec.rb
164
+ - spec/compiler_spec.rb
165
+ - spec/context_spec.rb
166
+ - spec/core_spec.rg
167
+ - spec/metadata_spec.rb
168
+ - spec/namespace_spec.rb
169
+ - spec/printer_spec.rb
170
+ - spec/reader_spec.rb
171
+ - spec/rouge_spec.rb
172
+ - spec/seq_spec.rb
173
+ - spec/spec_helper.rb
174
+ - spec/symbol_spec.rb
175
+ - spec/var_spec.rb
176
+ - spec/wrappers_spec.rb
177
+ homepage: http://rouge.io/
178
+ licenses: []
179
+ post_install_message:
180
+ rdoc_options: []
181
+ require_paths:
182
+ - lib
183
+ required_ruby_version: !ruby/object:Gem::Requirement
184
+ none: false
185
+ requirements:
186
+ - - ! '>='
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ required_rubygems_version: !ruby/object:Gem::Requirement
190
+ none: false
191
+ requirements:
192
+ - - ! '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ requirements: []
196
+ rubyforge_project:
197
+ rubygems_version: 1.8.23
198
+ signing_key:
199
+ specification_version: 3
200
+ summary: An implementation of Clojure for Ruby.
201
+ test_files:
202
+ - spec/atom_spec.rb
203
+ - spec/builtins_spec.rb
204
+ - spec/compiler_spec.rb
205
+ - spec/context_spec.rb
206
+ - spec/core_spec.rg
207
+ - spec/metadata_spec.rb
208
+ - spec/namespace_spec.rb
209
+ - spec/printer_spec.rb
210
+ - spec/reader_spec.rb
211
+ - spec/rouge_spec.rb
212
+ - spec/seq_spec.rb
213
+ - spec/spec_helper.rb
214
+ - spec/symbol_spec.rb
215
+ - spec/var_spec.rb
216
+ - spec/wrappers_spec.rb