rouge-lang 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +6 -2
- data/README.md +7 -4
- data/lib/rouge/context.rb +13 -10
- data/lib/rouge/namespace.rb +58 -23
- data/lib/rouge/repl.rb +248 -8
- data/lib/rouge/version.rb +1 -1
- data/spec/repl_spec.rb +75 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1e27ba25fbbb2222935a382e5415a8e294e2fba
|
4
|
+
data.tar.gz: 90af1a227a44d3356f2b3f4f42536f39947b9dcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 531cc48c8807f33ff2968e92d21ad75bbd8ee6d992c701528dc397f49cd54f40f0774384013156993fb939d906b75e94ee6487a97f46a09d463262866dd83591
|
7
|
+
data.tar.gz: bcf7963675049fac6c11ce0e38444c18c53bce272c36506f8e2f8cedc676c7e3c59ee46a75763dda97fc9a0db0da7db0c3fe42d5143918a91f17c9a70b5c8ddc
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Rouge [](http://travis-ci.org/rouge-lang/rouge)
|
2
2
|
|
3
3
|
**Ruby + Clojure = Rouge.**
|
4
4
|
|
@@ -22,7 +22,7 @@ or on `#rouge` on Freenode.
|
|
22
22
|
|
23
23
|
## example
|
24
24
|
|
25
|
-
See [boot.rg](https://github.com/
|
25
|
+
See [boot.rg](https://github.com/rouge-lang/rouge/blob/master/lib/boot.rg),
|
26
26
|
[em-rg](https://github.com/unnali/em-rg),
|
27
27
|
[mechanize-rg](https://github.com/unnali/mechanize-rg), but to demonstrate
|
28
28
|
salient features:
|
@@ -60,7 +60,7 @@ user=>
|
|
60
60
|
|
61
61
|
## TODO
|
62
62
|
|
63
|
-
See [TODO](https://github.com/
|
63
|
+
See [TODO](https://github.com/rouge-lang/rouge/blob/master/misc/TODO), but big ones
|
64
64
|
include:
|
65
65
|
|
66
66
|
* making seqs nicer
|
@@ -82,12 +82,15 @@ include:
|
|
82
82
|
|
83
83
|
Original author: [Arlen Christian Mart Cuss](https://github.com/unnali).
|
84
84
|
|
85
|
+
Committers:
|
86
|
+
|
87
|
+
* [Joel Holdbrooks](https://github.com/noprompt)
|
88
|
+
|
85
89
|
Unreserved thanks to the following people for their contributions.
|
86
90
|
|
87
91
|
* [Russell Whitaker](https://github.com/russellwhitaker)
|
88
92
|
* [Misha Moroshko](https://github.com/moroshko)
|
89
93
|
* [Anthony Grimes](https://github.com/Raynes)
|
90
|
-
* [Joel Holdbrooks](https://github.com/noprompt)
|
91
94
|
|
92
95
|
## copyright and licensing
|
93
96
|
|
data/lib/rouge/context.rb
CHANGED
@@ -5,11 +5,17 @@ require 'rouge/namespace'
|
|
5
5
|
class Rouge::Context
|
6
6
|
class BindingNotFoundError < StandardError; end
|
7
7
|
class BadBindingError < StandardError; end
|
8
|
+
|
8
9
|
class ChangeContextException < Exception
|
9
|
-
def initialize(context); @context = context; end
|
10
10
|
attr_reader :context
|
11
|
+
|
12
|
+
def initialize(context)
|
13
|
+
@context = context
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
17
|
+
attr_reader :ns
|
18
|
+
|
13
19
|
def initialize(parent_or_ns)
|
14
20
|
case parent_or_ns
|
15
21
|
when Rouge::Namespace
|
@@ -18,6 +24,7 @@ class Rouge::Context
|
|
18
24
|
@parent = parent_or_ns
|
19
25
|
@ns = @parent.ns
|
20
26
|
end
|
27
|
+
|
21
28
|
@table = {}
|
22
29
|
end
|
23
30
|
|
@@ -47,8 +54,7 @@ class Rouge::Context
|
|
47
54
|
elsif @parent
|
48
55
|
@parent.set_lexical key, value
|
49
56
|
else
|
50
|
-
raise BindingNotFoundError,
|
51
|
-
"setting #{key} to #{value.inspect}"
|
57
|
+
raise BindingNotFoundError, "setting #{key} to #{value.inspect}"
|
52
58
|
end
|
53
59
|
end
|
54
60
|
|
@@ -56,7 +62,7 @@ class Rouge::Context
|
|
56
62
|
@table.keys + (@parent ? @parent.lexical_keys : [])
|
57
63
|
end
|
58
64
|
|
59
|
-
#
|
65
|
+
# This readeval post-processes the backtrace. Accordingly, it should only
|
60
66
|
# be called by consumers, and never by Rouge internally itself, lest it
|
61
67
|
# catches an exception and processes the backtrace too early.
|
62
68
|
def readeval(input)
|
@@ -129,8 +135,6 @@ class Rouge::Context
|
|
129
135
|
end
|
130
136
|
end
|
131
137
|
|
132
|
-
attr_reader :ns
|
133
|
-
|
134
138
|
private
|
135
139
|
|
136
140
|
def eval_symbol(form)
|
@@ -197,10 +201,9 @@ class Rouge::Context
|
|
197
201
|
default
|
198
202
|
end
|
199
203
|
else
|
200
|
-
raise
|
201
|
-
ArgumentError,
|
204
|
+
raise ArgumentError,
|
202
205
|
"Wrong number of args (#{num_args}) passed to " \
|
203
|
-
"ruby/Symbol #{fun.inspect}"
|
206
|
+
"ruby/Symbol #{fun.inspect}"
|
204
207
|
end
|
205
208
|
when Hash
|
206
209
|
if num_args == 1 || num_args == 2
|
@@ -244,6 +247,6 @@ class Rouge::Context
|
|
244
247
|
raise e
|
245
248
|
end
|
246
249
|
end
|
247
|
-
end
|
250
|
+
end # class Rouge::Context
|
248
251
|
|
249
252
|
# vim: set sw=2 et cc=80:
|
data/lib/rouge/namespace.rb
CHANGED
@@ -5,21 +5,26 @@ require 'rouge/var'
|
|
5
5
|
require 'rouge/atom'
|
6
6
|
|
7
7
|
class Rouge::Namespace
|
8
|
-
@namespaces = {}
|
9
|
-
|
10
8
|
class VarNotFoundError < StandardError; end
|
11
9
|
class RecursiveNamespaceError < StandardError; end
|
12
10
|
|
11
|
+
attr_reader :name, :refers, :table
|
12
|
+
|
13
|
+
@namespaces = {}
|
14
|
+
|
13
15
|
def initialize(name)
|
16
|
+
unless name.is_a? Symbol
|
17
|
+
raise ArgumentError, "bad ns name"
|
18
|
+
end
|
19
|
+
|
14
20
|
@name = name
|
15
|
-
raise ArgumentError, "bad ns name" unless @name.is_a? Symbol
|
16
|
-
@table = {}
|
17
21
|
@refers = []
|
22
|
+
@table = {}
|
18
23
|
end
|
19
24
|
|
20
25
|
def inspect
|
21
|
-
"#<Rouge::
|
22
|
-
"refers
|
26
|
+
"#<Rouge::Namespace: @name=#{@name.inspect}, " \
|
27
|
+
"@refers=[#{@refers.map(&:inspect).join(", ")}]>"
|
23
28
|
end
|
24
29
|
|
25
30
|
def refer(ns)
|
@@ -27,7 +32,10 @@ class Rouge::Namespace
|
|
27
32
|
raise RecursiveNamespaceError, "#@name will not refer #{ns.name}"
|
28
33
|
end
|
29
34
|
|
30
|
-
|
35
|
+
unless @refers.include?(ns)
|
36
|
+
@refers << ns
|
37
|
+
end
|
38
|
+
|
31
39
|
self
|
32
40
|
end
|
33
41
|
|
@@ -64,31 +72,44 @@ class Rouge::Namespace
|
|
64
72
|
self
|
65
73
|
end
|
66
74
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
75
|
+
# Returns a hash of all namespaces.
|
76
|
+
#
|
77
|
+
# @return [Hash]
|
78
|
+
#
|
79
|
+
# @api public
|
80
|
+
def self.all
|
81
|
+
@namespaces
|
73
82
|
end
|
74
83
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
84
|
+
# Returns true if the given namespace ns exists, false otherwise.
|
85
|
+
#
|
86
|
+
# @param [Symbol] ns the namespace to check for
|
87
|
+
#
|
88
|
+
# @return [Boolean]
|
89
|
+
#
|
90
|
+
# @api public
|
91
|
+
def self.exists?(ns)
|
92
|
+
@namespaces.include?(ns)
|
81
93
|
end
|
82
94
|
|
83
|
-
def
|
84
|
-
|
95
|
+
def self.[](ns)
|
96
|
+
if exists?(ns)
|
97
|
+
@namespaces[ns]
|
98
|
+
else
|
99
|
+
self[ns] = new(ns)
|
100
|
+
@namespaces[ns] = new(ns)
|
101
|
+
end
|
85
102
|
end
|
86
103
|
|
87
|
-
def []=(ns, value)
|
104
|
+
def self.[]=(ns, value)
|
88
105
|
@namespaces[ns] = value
|
89
106
|
end
|
90
107
|
|
91
|
-
def
|
108
|
+
def self.get(ns)
|
109
|
+
@namespaces[ns]
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.destroy(ns)
|
92
113
|
@namespaces.delete ns
|
93
114
|
end
|
94
115
|
end
|
@@ -115,16 +136,30 @@ class Rouge::Namespace::Ruby
|
|
115
136
|
def name
|
116
137
|
:ruby
|
117
138
|
end
|
139
|
+
|
140
|
+
# Returns the result of calling Object.constants.
|
141
|
+
#
|
142
|
+
# @return [Array<Symbol>] the list of Ruby constants
|
143
|
+
#
|
144
|
+
# @api public
|
145
|
+
#
|
146
|
+
def table
|
147
|
+
Object.constants
|
148
|
+
end
|
118
149
|
end
|
119
150
|
|
151
|
+
# Create the rouge.builtin namespace.
|
120
152
|
ns = Rouge::Namespace[:"rouge.builtin"]
|
153
|
+
|
121
154
|
Rouge::Builtins.methods(false).reject {|s| s =~ /^_compile_/}.each do |m|
|
122
155
|
ns.set_here m, Rouge::Builtin[Rouge::Builtins.method(m)]
|
123
156
|
end
|
157
|
+
|
124
158
|
Rouge::Builtins::SYMBOLS.each do |name, val|
|
125
159
|
ns.set_here name, val
|
126
160
|
end
|
127
161
|
|
162
|
+
# Create the ruby namespace.
|
128
163
|
Rouge::Namespace[:ruby] = Rouge::Namespace::Ruby.new
|
129
164
|
|
130
165
|
# vim: set sw=2 et cc=80:
|
data/lib/rouge/repl.rb
CHANGED
@@ -17,8 +17,10 @@ module Rouge::REPL
|
|
17
17
|
context = Rouge::Context.new(Rouge[:user])
|
18
18
|
count = 0
|
19
19
|
chaining = false
|
20
|
+
Readline.completion_proc = Completer.new(context.ns)
|
20
21
|
|
21
22
|
while true
|
23
|
+
|
22
24
|
if !chaining
|
23
25
|
prompt = "#{context.ns.name}=> "
|
24
26
|
input = Readline.readline(prompt, true)
|
@@ -40,19 +42,17 @@ module Rouge::REPL
|
|
40
42
|
chaining = true
|
41
43
|
next
|
42
44
|
rescue Rouge::Reader::UnexpectedCharacterError => reader_err
|
43
|
-
repl_error.call
|
45
|
+
repl_error.call(reader_err)
|
44
46
|
rescue Rouge::Reader::NumberFormatError => reader_err
|
45
|
-
repl_error.call
|
47
|
+
repl_error.call(reader_err)
|
46
48
|
end
|
47
49
|
|
48
50
|
chaining = false
|
49
51
|
|
50
52
|
begin
|
51
|
-
form = Rouge::Compiler.compile(
|
52
|
-
|
53
|
-
|
54
|
-
form
|
55
|
-
)
|
53
|
+
form = Rouge::Compiler.compile(context.ns,
|
54
|
+
Set[*context.lexical_keys],
|
55
|
+
form)
|
56
56
|
|
57
57
|
result = context.eval(form)
|
58
58
|
|
@@ -66,13 +66,253 @@ module Rouge::REPL
|
|
66
66
|
context.set_here :"*1", result
|
67
67
|
rescue Rouge::Context::ChangeContextException => cce
|
68
68
|
context = cce.context
|
69
|
+
# Since completion is context sensitive, we need update the proc
|
70
|
+
# whenever it changes.
|
71
|
+
Readline.completion_proc = Completer.new(context.ns)
|
69
72
|
count = 0
|
70
73
|
rescue => e
|
71
|
-
repl_error.call
|
74
|
+
repl_error.call(e)
|
72
75
|
end
|
73
76
|
end
|
74
77
|
end
|
75
78
|
|
79
|
+
module Completer
|
80
|
+
extend self
|
81
|
+
|
82
|
+
# Returns a proc intended to be used with Readline.
|
83
|
+
#
|
84
|
+
# @param [Rouge::Namespace] current_namespace
|
85
|
+
# the current namespace
|
86
|
+
#
|
87
|
+
# @return [Proc] the completion proc to be used with Readline. The
|
88
|
+
# returned proc accepts a string and returns an array.
|
89
|
+
#
|
90
|
+
# @api public
|
91
|
+
def new(current_namespace)
|
92
|
+
return lambda do |query|
|
93
|
+
if query.nil? || query.empty?
|
94
|
+
return []
|
95
|
+
end
|
96
|
+
|
97
|
+
list = namespace_items(current_namespace)
|
98
|
+
list << search(query)
|
99
|
+
|
100
|
+
matches = search_list(list.flatten, query)
|
101
|
+
|
102
|
+
# If there's only one match we check if it's a namespace or a Ruby
|
103
|
+
# constant which contains other constants or singleton methods.
|
104
|
+
if matches.length == 1
|
105
|
+
match = matches[0]
|
106
|
+
if Rouge::Namespace.exists?(match)
|
107
|
+
if current_namespace.table.include?(match)
|
108
|
+
matches << "#{match}/"
|
109
|
+
else
|
110
|
+
Readline.completion_append_character = "/"
|
111
|
+
end
|
112
|
+
else
|
113
|
+
if locate_module(match.to_s)
|
114
|
+
Readline.completion_append_character = ""
|
115
|
+
end
|
116
|
+
end
|
117
|
+
else
|
118
|
+
Readline.completion_append_character = ""
|
119
|
+
end
|
120
|
+
|
121
|
+
matches
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns a list of constants and singleton method names based on the string
|
126
|
+
# query.
|
127
|
+
#
|
128
|
+
# @param [String] query
|
129
|
+
# the search string to use
|
130
|
+
#
|
131
|
+
# @return [Array<Symbol,String>] the search results
|
132
|
+
#
|
133
|
+
# @api public
|
134
|
+
def search(query)
|
135
|
+
namespace, lookup = query.split('/', 2)
|
136
|
+
result =
|
137
|
+
case namespace
|
138
|
+
# The ruby namespace requires special handling.
|
139
|
+
when /^[A-Z]/
|
140
|
+
search_ruby(query)
|
141
|
+
when /^ruby/
|
142
|
+
if lookup && lookup.empty?
|
143
|
+
Rouge[:ruby].table.map {|x| "ruby/#{x}" }
|
144
|
+
else
|
145
|
+
search_ruby(lookup).map {|x| "ruby/#{x}" }
|
146
|
+
end
|
147
|
+
else
|
148
|
+
ns = rg_namespaces[namespace.to_sym]
|
149
|
+
|
150
|
+
if ns
|
151
|
+
ns.table.map { |var, _| "#{namespace}/#{var}" }
|
152
|
+
else
|
153
|
+
# Add the current namepace, rouge.builtin, and ruby tables along with
|
154
|
+
# the names of available namespaces in the completion list.
|
155
|
+
list = []
|
156
|
+
list << Rouge[:"rouge.builtin"].table.keys
|
157
|
+
list << :ruby
|
158
|
+
list << Rouge[:ruby].table
|
159
|
+
list << rg_namespaces.keys
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
search_list(result.flatten, query)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Applies `locate_module` to the string query and returns a list constants
|
167
|
+
# and singleton methods. These results are intended to be filtered in the
|
168
|
+
# `search` method.
|
169
|
+
#
|
170
|
+
# @see Completer.locate_module, Completer.search
|
171
|
+
#
|
172
|
+
# @example
|
173
|
+
# search_ruby("Rouge") #=> ["Rouge/[]", "Rouge/boot!", ...]
|
174
|
+
# search_ruby("Rouge.") #=> ["Rouge/[]", "Rouge/boot!", ...]
|
175
|
+
#
|
176
|
+
# @param [String] query
|
177
|
+
# the search string to use
|
178
|
+
#
|
179
|
+
# @return [Array<Symbol,String>] the search result
|
180
|
+
#
|
181
|
+
# @api public
|
182
|
+
def search_ruby(query)
|
183
|
+
namespace = query.split('/', 2).first
|
184
|
+
|
185
|
+
mod = locate_module(namespace)
|
186
|
+
|
187
|
+
if mod == Object
|
188
|
+
mod.constants
|
189
|
+
else
|
190
|
+
ns = mod.name.gsub('::','.')
|
191
|
+
result = []
|
192
|
+
mod.singleton_methods.each { |sm| result << "#{ns}/#{sm}" }
|
193
|
+
mod.constants.each { |c| result << "#{ns}.#{c}" }
|
194
|
+
result.flatten
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Recursively searches for a Ruby module (includes classes) given by the
|
199
|
+
# string query. The string should contain a Rouge style namespace name for
|
200
|
+
# the module.
|
201
|
+
#
|
202
|
+
# Optionally, a root module can be supplied as the context for the query.
|
203
|
+
# By default this is Object. If no module is found, the method returns nil
|
204
|
+
# or the root.
|
205
|
+
#
|
206
|
+
# Be aware this method *only* returns modules and classes.
|
207
|
+
#
|
208
|
+
# @example
|
209
|
+
# locate_module("Bil.Bo") #=> Bil::Bo
|
210
|
+
# locate_module("Ji.Tsu", Nin) #=> Nin::Ji::Tsu
|
211
|
+
#
|
212
|
+
# @param [String] query
|
213
|
+
# the module (or class) to find
|
214
|
+
#
|
215
|
+
# @param [Module] root
|
216
|
+
# the optional search context
|
217
|
+
#
|
218
|
+
# @return [Class,Module,nil] the search result
|
219
|
+
#
|
220
|
+
# @api public
|
221
|
+
def locate_module(query, root = Object)
|
222
|
+
head, tail = query.split('.', 2)
|
223
|
+
|
224
|
+
return root unless rg_ruby_module?(head)
|
225
|
+
|
226
|
+
lookup = head.to_sym
|
227
|
+
|
228
|
+
if root.is_a?(Module) && root.constants.include?(lookup)
|
229
|
+
result = root.const_get(lookup)
|
230
|
+
|
231
|
+
return root unless result.is_a?(Module)
|
232
|
+
|
233
|
+
# `query` may have ended with '.'.
|
234
|
+
if tail.nil? || tail.empty?
|
235
|
+
result
|
236
|
+
else
|
237
|
+
locate_module(tail, result)
|
238
|
+
end
|
239
|
+
else
|
240
|
+
root
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Rouge namespaces. Note we do not include the rouge.builtin and ruby
|
245
|
+
# namespaces since we would like built in vars, such as def or let, and top
|
246
|
+
# level Ruby constants to be easily accessible with command line
|
247
|
+
# completion.
|
248
|
+
#
|
249
|
+
# @return [Hash] the filtered namespaces
|
250
|
+
#
|
251
|
+
# @api public
|
252
|
+
def rg_namespaces
|
253
|
+
Rouge::Namespace.all.reject do |key, _|
|
254
|
+
[:"rouge.builtin", :ruby].include?(key)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# Returns true if the provided namespace is included in `rg_namespaces`.
|
259
|
+
#
|
260
|
+
# @see Rouge::REPL::Completer.rg_namespaces
|
261
|
+
#
|
262
|
+
# @param [Rouge::Namespace] x
|
263
|
+
# the namespace to test
|
264
|
+
#
|
265
|
+
# @return [Boolean]
|
266
|
+
#
|
267
|
+
# @api public
|
268
|
+
def rg_namespace?(x)
|
269
|
+
x.is_a?(Rouge::Namespace) && rg_namespaces.keys.include?(x.name)
|
270
|
+
end
|
271
|
+
|
272
|
+
private
|
273
|
+
|
274
|
+
# Returns a list of table keys and refer keys based on the given namespace.
|
275
|
+
#
|
276
|
+
# @param [Rouge::Namespace] ns
|
277
|
+
# the namespace to use
|
278
|
+
#
|
279
|
+
# @return [Array<Symbol>]
|
280
|
+
#
|
281
|
+
# @api public
|
282
|
+
def namespace_items(ns)
|
283
|
+
list = ns.table.keys
|
284
|
+
refers = ns.refers.select { |ns| rg_namespace?(ns) }
|
285
|
+
list << refers.map { |ns| ns.table.keys }
|
286
|
+
end
|
287
|
+
|
288
|
+
# Returns true if the string query matches a Rouge style Ruby module or
|
289
|
+
# constant name.
|
290
|
+
#
|
291
|
+
# @param [String] query
|
292
|
+
# the query string to match.
|
293
|
+
#
|
294
|
+
# @return [Boolean]
|
295
|
+
#
|
296
|
+
# @api private
|
297
|
+
def rg_ruby_module?(x)
|
298
|
+
!!/^(?:[A-Z][A-Za-z_]*\.?)+$/.match(x)
|
299
|
+
end
|
300
|
+
|
301
|
+
# Filters a list of items based on a string query.
|
302
|
+
#
|
303
|
+
# @param [Array] list
|
304
|
+
# the list to filter.
|
305
|
+
#
|
306
|
+
# @param [String] query
|
307
|
+
# the search string to use.
|
308
|
+
#
|
309
|
+
# @return [Array]
|
310
|
+
#
|
311
|
+
# @api private
|
312
|
+
def search_list(list, query)
|
313
|
+
list.grep(/^#{Regexp.escape(query)}/)
|
314
|
+
end
|
315
|
+
end
|
76
316
|
end
|
77
317
|
|
78
318
|
# vim: set sw=2 et cc=80:
|
data/lib/rouge/version.rb
CHANGED
data/spec/repl_spec.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'rouge'
|
4
|
+
|
5
|
+
describe Rouge::REPL do
|
6
|
+
describe "comp" do
|
7
|
+
let(:user) { Rouge[:user].clear }
|
8
|
+
let(:food) { Rouge[:food].clear }
|
9
|
+
let(:comp) { Rouge::REPL::Completer }
|
10
|
+
let(:fake_class_a) { Class.new }
|
11
|
+
let(:fake_class_b) { Class.new }
|
12
|
+
|
13
|
+
before {
|
14
|
+
stub_const("Corn", fake_class_a)
|
15
|
+
stub_const("Corn::Bread", fake_class_b)
|
16
|
+
fake_class_a.define_singleton_method(:pop) {}
|
17
|
+
fake_class_b.define_singleton_method(:toast) {}
|
18
|
+
user.set_here(:pop, "corn")
|
19
|
+
food.set_here(:scrambled, "eggs")
|
20
|
+
user.refer(food)
|
21
|
+
}
|
22
|
+
|
23
|
+
context "#new" do
|
24
|
+
let(:comp) { Rouge::REPL::Completer.new(user) }
|
25
|
+
it { comp.call("u").should include(:user) }
|
26
|
+
it { comp.call("p").should include(:pop) }
|
27
|
+
it { comp.call("s").should include(:scrambled) }
|
28
|
+
it { comp.call("Rouge").should include("Rouge.VERSION") }
|
29
|
+
it { comp.call("ruby/").should include("ruby/RUBY_VERSION") }
|
30
|
+
it { comp.call("ruby/Rouge.").should include("ruby/Rouge.VERSION") }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "#search" do
|
34
|
+
it { comp.search("u").should include(:user) }
|
35
|
+
it { comp.search("r").should include(:ruby) }
|
36
|
+
it { comp.search("d").should include(:def) }
|
37
|
+
it { comp.search("user/").should include("user/pop") }
|
38
|
+
it { comp.search("C").should include(:Corn) }
|
39
|
+
it { comp.search("C").should_not include(:Bread) }
|
40
|
+
it { comp.search("Corn.").should include("Corn.Bread") }
|
41
|
+
it { comp.search("Corn/").should include("Corn/pop") }
|
42
|
+
it { comp.search("Corn.").should_not include("Corn/pop") }
|
43
|
+
it { comp.search("Corn/").should_not include("Corn.Bread") }
|
44
|
+
it { comp.search("ruby/C").should include("ruby/Corn") }
|
45
|
+
it { comp.search("ruby/Corn.").should include("ruby/Corn.Bread") }
|
46
|
+
it { comp.search("ruby/Corn/").should include("ruby/Corn/pop") }
|
47
|
+
it { comp.search("ruby/Corn.Bread/").should include("ruby/Corn.Bread/toast") }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "#search_ruby" do
|
51
|
+
it { comp.search_ruby("B").should include(:Corn) }
|
52
|
+
it { comp.search_ruby("Corn").should include("Corn.Bread") }
|
53
|
+
it { comp.search_ruby("Corn").should include("Corn/pop") }
|
54
|
+
it { comp.search_ruby("Corn.Bread").should include("Corn.Bread/toast") }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "#rg_namespaces" do
|
58
|
+
it { comp.send(:rg_namespaces).should be_an_instance_of(Hash) }
|
59
|
+
it { comp.send(:rg_namespaces).should include(:user) }
|
60
|
+
end
|
61
|
+
|
62
|
+
context "#locate_module" do
|
63
|
+
it { comp.locate_module("R").should eq(Object) }
|
64
|
+
it { comp.locate_module("Rouge").should eq(Rouge) }
|
65
|
+
it { comp.locate_module("Rouge.").should eq(Rouge) }
|
66
|
+
it { comp.locate_module("V", Rouge).should eq(Rouge) }
|
67
|
+
it { comp.locate_module("Rouge..").should eq(Rouge) }
|
68
|
+
it { comp.locate_module("Symbol", Rouge).should eq(Rouge::Symbol) }
|
69
|
+
it { comp.locate_module("Rouge.Symbol").should eq(Rouge::Symbol) }
|
70
|
+
it { comp.locate_module("Rouge.symbol").should eq(Rouge) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# vim: set sw=2 et cc=80:
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rouge-lang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arlen Christian Mart Cuss
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- spec/namespace_spec.rb
|
154
154
|
- spec/printer_spec.rb
|
155
155
|
- spec/reader_spec.rb
|
156
|
+
- spec/repl_spec.rb
|
156
157
|
- spec/rouge_spec.rb
|
157
158
|
- spec/seq_spec.rb
|
158
159
|
- spec/spec_helper.rb
|
@@ -192,6 +193,7 @@ test_files:
|
|
192
193
|
- spec/namespace_spec.rb
|
193
194
|
- spec/printer_spec.rb
|
194
195
|
- spec/reader_spec.rb
|
196
|
+
- spec/repl_spec.rb
|
195
197
|
- spec/rouge_spec.rb
|
196
198
|
- spec/seq_spec.rb
|
197
199
|
- spec/spec_helper.rb
|