ripl-multi_line 0.2.1 → 0.2.2

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.
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