ripl-multi_line 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.summary = "A ripl plugin for multi-line eval."
12
12
  s.description = "This ripl plugin allows you to evaluate multiple lines of Ruby code."
13
13
  s.required_rubygems_version = ">= 1.3.6"
14
- s.add_dependency 'ripl', '>= 0.2.6'
14
+ s.add_dependency 'ripl', '>= 0.3.0'
15
15
  s.files = Dir.glob(%w[{lib,test}/**/*.rb bin/* [A-Z]*.{txt,rdoc} ext/**/*.{rb,c} **/deps.rip]) + %w{Rakefile .gemspec}
16
16
  s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt"]
17
17
  s.license = 'MIT'
@@ -1,3 +1,6 @@
1
+ == 0.2.2
2
+ * fix for mri regexes
3
+
1
4
  == 0.2.1
2
5
  * rubinius and jruby support
3
6
 
@@ -4,7 +4,7 @@ This {ripl}[http://github.com/cldwalker/ripl] plugin allows you to evaluate mult
4
4
  == Install
5
5
  Install the gem with
6
6
 
7
- sudo gem install ripl-multi_line
7
+ gem install ripl-multi_line
8
8
 
9
9
  == Usage
10
10
 
@@ -18,4 +18,7 @@ You can customize your multi-line prompt with the <tt>:multi_line_prompt</tt> op
18
18
 
19
19
  If you are in multi-line situation, you can press <tt>ctrl+c</tt> and the last line will be removed.
20
20
 
21
+ == Todo
22
+ * Replaceable check if syntax is valid (allows use of this plugin for other languages than Ruby)
23
+
21
24
  J-_-L
@@ -2,10 +2,10 @@ require 'ripl'
2
2
 
3
3
  module Ripl
4
4
  module MultiLine
5
- VERSION = '0.2.1'
5
+ VERSION = '0.2.2'
6
6
  ERROR_REGEXP = /#{
7
7
  [ %q%unexpected $end%,
8
- %q%unterminated string meets end of file%,
8
+ %q%unterminated [a-z]+ meets end of file%,
9
9
  # rubinius
10
10
  %q%expecting '\\n' or ';'%,
11
11
  %q%missing 'end'%,
@@ -31,7 +31,6 @@ module Ripl
31
31
  end
32
32
 
33
33
  def print_eval_error(e)
34
-
35
34
  if e.is_a?(SyntaxError) && e.message =~ ERROR_REGEXP
36
35
  @buffer ||= []
37
36
  @buffer << @input
@@ -68,7 +67,7 @@ module Ripl
68
67
  end
69
68
  end
70
69
 
71
- Ripl::Shell.send :include, Ripl::MultiLine
70
+ Ripl::Shell.include Ripl::MultiLine
72
71
  Ripl.config[:multi_line_prompt] ||= '| '
73
72
 
74
73
  # J-_-L
@@ -0,0 +1,248 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe "Runner" do
4
+ describe ".start" do
5
+ before { reset_ripl }
6
+
7
+ it "loads riplrc" do
8
+ mock_riplrc
9
+ mock_shell
10
+ Ripl.start
11
+ end
12
+
13
+ it "doesn't load riplrc" do
14
+ mock_shell
15
+ dont_allow(Runner).load_rc(anything)
16
+ Ripl.start :riplrc => false
17
+ end
18
+
19
+ it "sets a shell's variables" do
20
+ mock_riplrc
21
+ mock_shell
22
+ Ripl.start(:name=>'shh')
23
+ Ripl.shell.name.should == 'shh'
24
+ end
25
+
26
+ it "passes options to Ripl.config" do
27
+ mock_riplrc
28
+ mock_shell
29
+ Ripl.start(:history=>'~/.mah_history')
30
+ Ripl.config[:history].should == '~/.mah_history'
31
+ end
32
+
33
+ it "overrides config set in riplrc" do
34
+ mock_riplrc { Ripl.config[:name] = 'blah' }
35
+ mock_shell
36
+ Ripl.start(:name=>'dude')
37
+ Ripl.shell.name.should == 'dude'
38
+ end
39
+ end
40
+
41
+ describe ".run" do
42
+ describe "riplrc" do
43
+ before { reset_ripl }
44
+
45
+ it "sets config" do
46
+ mock_riplrc { Ripl.config[:blah] = true }
47
+ mock_shell
48
+ Runner.run([])
49
+ Ripl.config[:blah].should == true
50
+ end
51
+
52
+ it "catches and prints error" do
53
+ mock(Runner).load(anything) { raise SyntaxError }
54
+ mock_shell
55
+ capture_stderr { Runner.run([]) }.should =~ %r{^ripl: Error while loading ~/.riplrc:\nSyntaxError:}
56
+ end
57
+ end
58
+
59
+ describe "with subcommand" do
60
+ def set_dollar_zero(val)
61
+ $progname = $0
62
+ alias $0 $progname
63
+ $0 = val
64
+ end
65
+
66
+ def mock_exec(*args)
67
+ mock(Runner).exec('ripl-rails', *args) do
68
+ set_dollar_zero 'ripl-rails'
69
+ ARGV.replace(args)
70
+ Ripl.start
71
+ end
72
+ end
73
+
74
+ it "gets invoked with arguments" do
75
+ mock_exec 'blah'
76
+ ripl("rails", 'blah')
77
+ end
78
+
79
+ it "has -F global option parsed" do
80
+ mock_exec '-F'
81
+ dont_allow(Runner).load_rc(anything)
82
+ ripl("rails", "-F", :riplrc=>false)
83
+ end
84
+
85
+ it "saves arguments passed to it" do
86
+ mock_exec 'blah', '-F'
87
+ ripl("rails", "blah", "-F", :riplrc=>false)
88
+ Ripl::Runner.argv.should == ['blah', '-F']
89
+ end
90
+
91
+ it "has other global option parsed" do
92
+ mock_exec '-r=blah'
93
+ mock(Runner).require('blah')
94
+ ripl("rails", "-r=blah")
95
+ end
96
+
97
+ it "has automatic --help" do
98
+ mock_exec '--help'
99
+ mock(Runner).exit
100
+ ripl("rails", "--help").chomp.should == "ripl rails [OPTIONS] [ARGS]"
101
+ end
102
+
103
+ it "that is invalid aborts" do
104
+ mock(Runner).abort("`zzz' is not a ripl command.")
105
+ ripl 'zzz', :riplrc => false, :loop => false
106
+ end
107
+ after_all { set_dollar_zero 'ripl' }
108
+ end
109
+
110
+ describe "with -I option" do
111
+ before { @old_load_path = $:.dup }
112
+ after { $:.replace @old_load_path }
113
+
114
+ it "and equal sign adds to $LOAD_PATH" do
115
+ ripl("-I=blah")
116
+ $:[0].should == 'blah'
117
+ end
118
+
119
+ it "and no equal sign adds to $LOAD_PATH" do
120
+ ripl("-Ispec")
121
+ $:[0].should == 'spec'
122
+ end
123
+
124
+ it "and whitespace delimited argument adds to $LOAD_PATH" do
125
+ ripl("-I", "spec")
126
+ $:[0].should == 'spec'
127
+ end
128
+
129
+ it "containing multiple paths adds to $LOAD_PATH" do
130
+ ripl("-I=app:lib")
131
+ $:[0,2].should == ['app', 'lib']
132
+ end
133
+
134
+ it "called more than once adds to $LOAD_PATH" do
135
+ ripl("-Ilib", "-Ispec")
136
+ $:[0,2].should == ['spec', 'lib']
137
+ end
138
+
139
+ it "with invalid argument doesn't add to $LOAD_PATH" do
140
+ previous_size = $:.size
141
+ ripl("-I")
142
+ $:.size.should == previous_size
143
+ end
144
+ end
145
+
146
+ describe "with -r option" do
147
+ it "and equal sign requires path" do
148
+ mock(Runner).require('rip')
149
+ ripl("-r=rip")
150
+ end
151
+
152
+ it "and no equal sign requires path" do
153
+ mock(Runner).require('rip')
154
+ ripl("-rrip")
155
+ end
156
+
157
+ it "and whitespace delimited argument requires path" do
158
+ mock(Runner).require('rip')
159
+ ripl("-r", "rip")
160
+ end
161
+
162
+ it "called more than once requires paths" do
163
+ mock(Runner).require('rip')
164
+ mock(Runner).require('dude')
165
+ ripl("-rrip", "-rdude")
166
+ end
167
+
168
+ it "with invalid argument requires blank" do
169
+ mock(Runner).require('')
170
+ ripl('-r')
171
+ end
172
+ end
173
+
174
+ it "with -f option doesn't load irbrc" do
175
+ reset_ripl
176
+ reset_config
177
+ stub(Kernel).at_exit()
178
+ mock_shell { |shell|
179
+ mock(shell).loop_once { throw :ripl_exit }
180
+ dont_allow(Runner).load_rc(anything)
181
+ }
182
+ ripl("-f", :loop => false)
183
+ Ripl.config[:irbrc] = '~/.irbrc'
184
+ end
185
+
186
+ it "with -F option doesn't load riplrc" do
187
+ reset_ripl
188
+ dont_allow(Runner).load_rc(anything)
189
+ mock_shell { |shell|
190
+ stub(Kernel).at_exit
191
+ mock(shell).before_loop
192
+ mock(shell).loop_once { throw :ripl_exit }
193
+ }
194
+ ripl("-F", :riplrc => false, :loop => false)
195
+ end
196
+
197
+ it "with -d option sets $DEBUG" do
198
+ ripl("-d")
199
+ $DEBUG.should == true
200
+ $DEBUG = nil
201
+ end
202
+
203
+ it "with -v option prints version" do
204
+ mock(Runner).exit
205
+ ripl("-v").chomp.should == Ripl::VERSION
206
+ end
207
+
208
+ it "with -h option prints help" do
209
+ mock(Runner).exit
210
+ actual = ripl("-h")
211
+ actual.should =~ /^Usage: ripl/
212
+ actual.should =~ /Options:\n -f/
213
+ end
214
+
215
+ it "with invalid options prints errors" do
216
+ capture_stderr {
217
+ ripl('--blah', '-z')
218
+ }.chomp.should == "ripl: invalid option `blah'\nripl: invalid option `z'"
219
+ end
220
+
221
+ describe "with plugin" do
222
+ before_all do
223
+ Moo = Module.new do
224
+ def parse_option(option, argv)
225
+ option == '--moo' ? puts("MOOOO") : super
226
+ end
227
+ end
228
+ Runner.extend Moo
229
+ Runner.add_options ['--moo', 'just moos']
230
+ end
231
+
232
+ it "parses plugin option" do
233
+ ripl("--moo").chomp.should == 'MOOOO'
234
+ end
235
+
236
+ it "displays plugin option in --help" do
237
+ mock(Runner).exit
238
+ ripl("--help").should =~ /--moo\s*just moos/
239
+ end
240
+
241
+ it "handles invalid option" do
242
+ capture_stderr {
243
+ ripl('--blah')
244
+ }.chomp.should == "ripl: invalid option `blah'"
245
+ end
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,113 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+ require 'ripl/multi_line' # TODO relative
3
+
4
+ describe "Shell" do
5
+ before { reset_ripl }
6
+
7
+ def shell(options={})
8
+ Ripl.shell(options)
9
+ end
10
+
11
+ describe "#loop" do
12
+ before { mock(shell).before_loop }
13
+ it "exits with exit" do
14
+ mock(shell).get_input { 'exit' }
15
+ dont_allow(shell).eval_input
16
+ shell.loop
17
+ end
18
+
19
+ it "exits with quit" do
20
+ mock(shell).get_input { 'quit' }
21
+ dont_allow(shell).eval_input
22
+ shell.loop
23
+ end
24
+
25
+ it "exits with Control-D" do
26
+ mock(shell).get_input { nil }
27
+ dont_allow(shell).eval_input
28
+ shell.loop
29
+ end
30
+ end
31
+
32
+ it "#loop_once handles Control-C" do
33
+ mock(shell).get_input { raise Interrupt }
34
+ dont_allow(shell).eval_input
35
+ capture_stdout { shell.loop_once }.should == "\n"
36
+ end
37
+
38
+ describe "#prompt" do
39
+ it "should be set to config[:multi_line_prompt]" do
40
+ mock(shell).get_input { '[' }
41
+ shell.loop_once
42
+ shell.prompt.should == Ripl.config[:multi_line_prompt]
43
+ end
44
+ end
45
+
46
+ describe "#before_loop" do
47
+ before_all { Ripl::Commands.send(:define_method, :ping) { 'pong' } }
48
+ before { reset_config }
49
+ it "adds commands to main from Commands" do
50
+ stub(Ripl::Runner).load_rc
51
+ stub(Kernel).at_exit
52
+ Ripl.shell.before_loop
53
+ Ripl.shell.loop_eval("ping").should == 'pong'
54
+ end
55
+
56
+ it "adds commands to fixnum from Commands" do
57
+ stub(Ripl::Runner).load_rc
58
+ Ripl.shell.binding = 1.send(:binding)
59
+ stub(Kernel).at_exit
60
+ Ripl.shell.before_loop
61
+ Ripl.shell.loop_eval("ping").should == 'pong'
62
+ end
63
+ end
64
+
65
+ describe "#eval_input" do
66
+ before { @line = shell.line; shell.eval_input("10 ** 2") }
67
+
68
+ describe "normally" do
69
+ it "sets result" do
70
+ shell.result.should == 100
71
+ end
72
+
73
+ it "sets _" do
74
+ shell.eval_input('_')
75
+ shell.result.should == 100
76
+ end
77
+
78
+ it "increments line" do
79
+ shell.line.should == @line + 1
80
+ end
81
+ end
82
+
83
+ describe "with error" do
84
+ before {
85
+ @line = shell.line
86
+ @stderr = capture_stderr { shell.eval_input('{') }
87
+ }
88
+
89
+ it "prints it" do
90
+ @stderr.should =~ /^(?:SyntaxError: compile error|SyntaxError: \(ripl\):\d+: syntax error)/
91
+ end
92
+
93
+ it "sets @error_raised" do
94
+ shell.instance_variable_get("@error_raised").should == true
95
+ end
96
+
97
+ it "increments line" do
98
+ shell.line.should == @line + 1
99
+ end
100
+ end
101
+ end
102
+
103
+ describe "API#" do
104
+ Shell::API.instance_methods.delete_if {|e| e[/=$/]}.each do |meth|
105
+ it "#{meth} is accessible to plugins" do
106
+ mod = Object.const_set "Ping_#{meth}", Module.new
107
+ mod.send(:define_method, meth) { "pong_#{meth}" }
108
+ Shell.send :include, mod
109
+ shell.send(meth).should == "pong_#{meth}"
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,60 @@
1
+ require 'bacon'
2
+ require 'bacon/bits'
3
+ require 'rr'
4
+ require 'bacon/rr'
5
+ require 'stringio'
6
+ require 'ripl'
7
+ include Ripl
8
+
9
+ module Helpers
10
+ def ripl(*args)
11
+ options = args[-1].is_a?(Hash) ? args.pop : {}
12
+ mock_riplrc unless options[:riplrc] == false
13
+ mock(Ripl.shell).loop unless options[:loop] == false
14
+ capture_stdout { Ripl::Runner.run(args) }
15
+ end
16
+
17
+ def mock_riplrc(&block)
18
+ mock(Runner).load_rc(Ripl.config[:riplrc], &block)
19
+ end
20
+
21
+ def mock_shell(&block)
22
+ mock(Shell).create(anything) {|e|
23
+ shell = Shell.new(e)
24
+ block ? block.call(shell) : mock(shell).loop
25
+ shell
26
+ }
27
+ end
28
+
29
+ def reset_ripl
30
+ Ripl.instance_eval "@config = @shell = @riplrc = nil"
31
+ end
32
+
33
+ def reset_config
34
+ Ripl.config.merge! :history => '~/.irb_history', :completion => {}
35
+ end
36
+
37
+ def capture_stdout(&block)
38
+ original_stdout = $stdout
39
+ $stdout = fake = StringIO.new
40
+ begin
41
+ yield
42
+ ensure
43
+ $stdout = original_stdout
44
+ end
45
+ fake.string
46
+ end
47
+
48
+ def capture_stderr(&block)
49
+ original_stderr = $stderr
50
+ $stderr = fake = StringIO.new
51
+ begin
52
+ yield
53
+ ensure
54
+ $stderr = original_stderr
55
+ end
56
+ fake.string
57
+ end
58
+ end
59
+
60
+ Bacon::Context.send :include, Helpers
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 1
9
- version: 0.2.1
8
+ - 2
9
+ version: 0.2.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jan Lelis
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-12 00:00:00 +01:00
17
+ date: 2011-01-25 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -27,9 +27,9 @@ dependencies:
27
27
  - !ruby/object:Gem::Version
28
28
  segments:
29
29
  - 0
30
- - 2
31
- - 6
32
- version: 0.2.6
30
+ - 3
31
+ - 0
32
+ version: 0.3.0
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
35
  description: This ripl plugin allows you to evaluate multiple lines of Ruby code.
@@ -43,6 +43,9 @@ extra_rdoc_files:
43
43
  - LICENSE.txt
44
44
  files:
45
45
  - lib/ripl/multi_line.rb
46
+ - test/test_helper.rb
47
+ - test/shell_test.rb
48
+ - test/runner_test.rb
46
49
  - LICENSE.txt
47
50
  - README.rdoc
48
51
  - CHANGELOG.rdoc