summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--array.c12
-rw-r--r--eval.c19
-rw-r--r--ext/pty/expect_sample.rb15
-rw-r--r--hash.c24
-rw-r--r--lib/cgi.rb16
-rw-r--r--lib/drb/drb.rb1
-rw-r--r--lib/test/unit/autorunner.rb4
-rw-r--r--lib/test/unit/ui/tk/testrunner.rb225
9 files changed, 278 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index a6877fe511..0572ef6b23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -35,6 +35,18 @@ Wed Nov 5 22:55:16 2003 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tk.rb : add TkMenu#set_focus support Tcl/Tk's
tk_menuSetFocus
+Wed Nov 5 17:33:45 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_load): allow interrupt during loaded program
+ evaluation. [ruby-dev:21834]
+
+ * hash.c (rb_hash_fetch): always warn if default argument and a
+ block are supplied at the same time. [ruby-dev:21842]
+
+ * hash.c (env_fetch): ditto.
+
+ * array.c (rb_ary_fetch): ditto.
+
Wed Nov 5 19:08:47 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/optparse.rb (OptionParser::Switch::PlacedArgument::parse):
diff --git a/array.c b/array.c
index ac2bb7d265..ba030bf468 100644
--- a/array.c
+++ b/array.c
@@ -595,21 +595,21 @@ rb_ary_fetch(argc, argv, ary)
VALUE ary;
{
VALUE pos, ifnone;
+ long block_given;
long idx;
rb_scan_args(argc, argv, "11", &pos, &ifnone);
+ block_given = rb_block_given_p();
+ if (block_given && argc == 2) {
+ rb_warn("block supersedes default value argument");
+ }
idx = NUM2LONG(pos);
if (idx < 0) {
idx += RARRAY(ary)->len;
}
if (idx < 0 || RARRAY(ary)->len <= idx) {
- if (rb_block_given_p()) {
- if (argc > 1) {
- rb_raise(rb_eArgError, "wrong number of arguments");
- }
- return rb_yield(pos);
- }
+ if (block_given) return rb_yield(pos);
if (argc == 1) {
rb_raise(rb_eIndexError, "index %ld out of array", idx);
}
diff --git a/eval.c b/eval.c
index f8543a41f9..48b133ed76 100644
--- a/eval.c
+++ b/eval.c
@@ -5836,11 +5836,11 @@ rb_load(fname, wrap)
ruby_in_eval--;
node = ruby_eval_tree;
rb_thread_critical = critical;
+ ALLOW_INTS;
if (ruby_nerrs == 0) {
eval_node(self, node);
}
}
- ALLOW_INTS;
ruby_frame->last_func = last_func;
ruby_current_node = last_node;
ruby_sourcefile = 0;
@@ -9812,22 +9812,6 @@ rb_thread_trap_eval(cmd, sig)
VALUE cmd;
int sig;
{
-#if 0
- rb_thread_critical = 0;
- if (!rb_thread_dead(curr_thread)) {
- rb_thread_ready(curr_thread);
- rb_trap_eval(cmd, sig);
- return;
- }
- rb_thread_ready(main_thread);
- if (THREAD_SAVE_CONTEXT(curr_thread)) {
- return;
- }
- th_cmd = cmd;
- th_sig = sig;
- curr_thread = main_thread;
- rb_thread_restore_context(curr_thread, RESTORE_TRAP);
-#else
rb_thread_critical = 0;
if (!rb_thread_dead(curr_thread)) {
if (THREAD_SAVE_CONTEXT(curr_thread)) {
@@ -9838,7 +9822,6 @@ rb_thread_trap_eval(cmd, sig)
th_sig = sig;
curr_thread = main_thread;
rb_thread_restore_context(curr_thread, RESTORE_TRAP);
-#endif
}
static VALUE
diff --git a/ext/pty/expect_sample.rb b/ext/pty/expect_sample.rb
index 1311476c5d..bf8a2352fe 100644
--- a/ext/pty/expect_sample.rb
+++ b/ext/pty/expect_sample.rb
@@ -4,17 +4,16 @@
# by A. Ito
#
# This program reports the latest version of ruby interpreter
-# by connecting to ftp server at netlab.co.jp.
+# by connecting to ftp server at ruby-lang.org.
#
require 'pty'
require 'expect'
fnames = []
-PTY.spawn("ftp ftp.netlab.co.jp") do
- |r_f,w_f,pid|
+PTY.spawn("ftp ftp.ruby-lang.org") do |r_f,w_f,pid|
w_f.sync = true
- $expect_verbose = true
+ $expect_verbose = false
r_f.expect(/^Name.*: /) do
w_f.print "ftp\n"
@@ -31,14 +30,14 @@ PTY.spawn("ftp ftp.netlab.co.jp") do
r_f.expect('word:') do
w_f.print username+"@\n"
end
- r_f.expect("ftp> ") do
- w_f.print "cd pub/lang/ruby\n"
+ r_f.expect("> ") do
+ w_f.print "cd pub/ruby\n"
end
- r_f.expect("ftp> ") do
+ r_f.expect("> ") do
w_f.print "dir\n"
end
- r_f.expect("ftp> ") do |output|
+ r_f.expect("> ") do |output|
for x in output[0].split("\n")
if x =~ /(ruby.*\.tar\.gz)/ then
fnames.push $1
diff --git a/hash.c b/hash.c
index 2743ad0e24..75c07797d3 100644
--- a/hash.c
+++ b/hash.c
@@ -300,16 +300,16 @@ rb_hash_fetch(argc, argv, hash)
{
VALUE key, if_none;
VALUE val;
+ long block_given;
rb_scan_args(argc, argv, "11", &key, &if_none);
+ block_given = rb_block_given_p();
+ if (block_given && argc == 2) {
+ rb_warn("block supersedes default value argument");
+ }
if (!st_lookup(RHASH(hash)->tbl, key, &val)) {
- if (rb_block_given_p()) {
- if (argc > 1) {
- rb_raise(rb_eArgError, "wrong number of arguments");
- }
- return rb_yield(key);
- }
+ if (block_given) return rb_yield(key);
if (argc == 1) {
rb_raise(rb_eIndexError, "key not found");
}
@@ -1086,9 +1086,14 @@ env_fetch(argc, argv)
VALUE *argv;
{
VALUE key, if_none;
+ long block_given;
char *nam, *env;
rb_scan_args(argc, argv, "11", &key, &if_none);
+ block_given = rb_block_given_p();
+ if (block_given && argc == 2) {
+ rb_warn("block supersedes default value argument");
+ }
StringValue(key);
nam = RSTRING(key)->ptr;
if (strlen(nam) != RSTRING(key)->len) {
@@ -1096,12 +1101,7 @@ env_fetch(argc, argv)
}
env = getenv(nam);
if (!env) {
- if (rb_block_given_p()) {
- if (argc > 1) {
- rb_raise(rb_eArgError, "wrong number of arguments");
- }
- return rb_yield(key);
- }
+ if (block_given) return rb_yield(key);
if (argc == 1) {
rb_raise(rb_eIndexError, "key not found");
}
diff --git a/lib/cgi.rb b/lib/cgi.rb
index 43a5aa89f0..fc94772948 100644
--- a/lib/cgi.rb
+++ b/lib/cgi.rb
@@ -984,7 +984,7 @@ class CGI
raise EOFError, "bad content body"
end
- until -1 == content_length
+ loop do
head = nil
if 10240 < content_length
require "tempfile"
@@ -1020,14 +1020,13 @@ class CGI
else
stdinput.read(content_length) or ''
end
- buf += c
+ buf.concat(c)
content_length -= c.size
-
end
buf = buf.sub(/\A((?:.|\n)*?)(?:#{EOL})?#{boundary}(#{EOL}|--)/n) do
body.print $1
- if "--" == $2 or EOL == $2
+ if "--" == $2
content_length = -1
end
""
@@ -1072,7 +1071,8 @@ class CGI
else
params[name] = [body]
end
-
+ break if buf.size == 0
+ break if content_length === -1
end
params
@@ -1115,6 +1115,7 @@ class CGI
@multipart = true
@params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
else
+ @multipart = false
@params = CGI::parse(
case env_table['REQUEST_METHOD']
when "GET", "HEAD"
@@ -1133,10 +1134,13 @@ class CGI
end
@cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
-
end
private :initialize_query
+ def multipart?
+ @multipart
+ end
+
class Value < String # :nodoc:
def initialize(str, params)
@params = params
diff --git a/lib/drb/drb.rb b/lib/drb/drb.rb
index fda18401dd..5eb7345e1b 100644
--- a/lib/drb/drb.rb
+++ b/lib/drb/drb.rb
@@ -1295,6 +1295,7 @@ module DRb
end
def run
+ raise if Thread.critical
Thread.start do
begin
while true
diff --git a/lib/test/unit/autorunner.rb b/lib/test/unit/autorunner.rb
index 803dc27d8b..3f17fadcf5 100644
--- a/lib/test/unit/autorunner.rb
+++ b/lib/test/unit/autorunner.rb
@@ -29,6 +29,10 @@ module Test
require 'test/unit/ui/fox/testrunner'
Test::Unit::UI::Fox::TestRunner.run(r.suite)
end,
+ :tk => proc do |r|
+ require 'test/unit/ui/tk/testrunner'
+ Test::Unit::UI::Tk::TestRunner.run(r.suite)
+ end,
}
OUTPUT_LEVELS = {
diff --git a/lib/test/unit/ui/tk/testrunner.rb b/lib/test/unit/ui/tk/testrunner.rb
new file mode 100644
index 0000000000..adf5a10222
--- /dev/null
+++ b/lib/test/unit/ui/tk/testrunner.rb
@@ -0,0 +1,225 @@
+# :nodoc:
+#
+# Original Author:: Nathaniel Talbott.
+# Author:: Kazuhiro NISHIYAMA.
+# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
+# Copyright:: Copyright (c) 2003 Kazuhiro NISHIYAMA. All rights reserved.
+# License:: Ruby license.
+
+require 'tk'
+require 'test/unit/ui/testrunnermediator'
+require 'test/unit/ui/testrunnerutilities'
+
+module Test
+ module Unit
+ module UI
+ module Tk # :nodoc:
+
+ # Runs a Test::Unit::TestSuite in a Tk UI. Obviously,
+ # this one requires you to have Tk
+ # and the Ruby Tk extension installed.
+ class TestRunner
+ extend TestRunnerUtilities
+
+ # Creates a new TestRunner and runs the suite.
+ def self.run(suite)
+ new(suite).start
+
+ end
+
+ # Creates a new TestRunner for running the passed
+ # suite.
+ def initialize(suite)
+ if (suite.respond_to?(:suite))
+ @suite = suite.suite
+ else
+ @suite = suite
+ end
+
+ @red = false
+ @fault_detail_list = []
+ @run_suite_thread = nil
+ end
+
+ # Begins the test run.
+ def start
+ setup_ui
+ setup_mediator
+ attach_to_mediator
+ start_ui
+ end
+
+ private
+ def setup_mediator # :nodoc:
+ @mediator = TestRunnerMediator.new(@suite)
+ suite_name = @suite.to_s
+ if ( @suite.kind_of?(Module) )
+ suite_name = @suite.name
+ end
+ @suite_name_entry.value = suite_name
+ end
+
+ def attach_to_mediator # :nodoc:
+ @run_button.command(method(:run_suite))
+ @fault_list.bind('ButtonPress-1', proc{|y|
+ fault = @fault_detail_list[@fault_list.nearest(y)]
+ if fault
+ show_fault(fault)
+ end
+ }, '%y')
+ @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
+ @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
+ @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
+ @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
+ @mediator.add_listener(TestCase::STARTED, &method(:test_started))
+ @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
+ end
+
+ def start_ui # :nodoc:
+ run_suite
+ begin
+ ::Tk.mainloop
+ rescue Exception
+ if @run_suite_thread and @run_suite_thread.alive?
+ @run_suite_thread.raise $!
+ retry
+ else
+ raise
+ end
+ end
+ end
+
+ def stop # :nodoc:
+ ::Tk.exit
+ end
+
+ def reset_ui(count) # :nodoc:
+ @test_total_count = count.to_f
+ @test_progress_bar.configure('background'=>'green')
+ @test_progress_bar.place('relwidth'=>0/count)
+ @red = false
+
+ @test_count_label.value = 0
+ @assertion_count_label.value = 0
+ @failure_count_label.value = 0
+ @error_count_label.value = 0
+
+ @fault_list.delete(0, 'end')
+ @fault_detail_list = []
+ clear_fault
+ end
+
+ def add_fault(fault) # :nodoc:
+ if ( ! @red )
+ @test_progress_bar.configure('background'=>'red')
+ @red = true
+ end
+ @fault_detail_list.push fault
+ @fault_list.insert('end', fault.short_display)
+ end
+
+ def show_fault(fault) # :nodoc:
+ raw_show_fault(fault.long_display)
+ end
+
+ def raw_show_fault(string) # :nodoc:
+ @detail_text.value = string
+ end
+
+ def clear_fault # :nodoc:
+ raw_show_fault("")
+ end
+
+ def result_changed(result) # :nodoc:
+ @test_count_label.value = result.run_count
+ @test_progress_bar.place('relwidth'=>result.run_count/@test_total_count)
+ @assertion_count_label.value = result.assertion_count
+ @failure_count_label.value = result.failure_count
+ @error_count_label.value = result.error_count
+ end
+
+ def started(result) # :nodoc:
+ output_status("Started...")
+ end
+
+ def test_started(test_name)
+ output_status("Running #{test_name}...")
+ end
+
+ def finished(elapsed_time)
+ output_status("Finished in #{elapsed_time} seconds")
+ end
+
+ def output_status(string) # :nodoc:
+ @status_entry.value = string
+ end
+
+ def setup_ui # :nodoc:
+ @status_entry = TkVariable.new
+ l = TkLabel.new(nil, 'textvariable'=>@status_entry, 'relief'=>'sunken')
+ l.pack('side'=>'bottom', 'fill'=>'x')
+
+ suite_frame = TkFrame.new.pack('fill'=>'x')
+
+ @run_button = TkButton.new(suite_frame, 'text'=>'Run')
+ @run_button.pack('side'=>'right')
+
+ TkLabel.new(suite_frame, 'text'=>'Suite:').pack('side'=>'left')
+ @suite_name_entry = TkVariable.new
+ l = TkLabel.new(suite_frame, 'textvariable'=>@suite_name_entry, 'relief'=>'sunken')
+ l.pack('side'=>'left', 'fill'=>'x', 'expand'=>true)
+
+ f = TkFrame.new(nil, 'relief'=>'sunken', 'borderwidth'=>3, 'height'=>20).pack('fill'=>'x', 'padx'=>1)
+ @test_progress_bar = TkFrame.new(f, 'background'=>'green').place('anchor'=>'nw', 'relwidth'=>0.0, 'relheight'=>1.0)
+
+ info_frame = TkFrame.new.pack('fill'=>'x', 'expand'=>true)
+ @test_count_label = create_count_label(info_frame, 'Tests:')
+ @assertion_count_label = create_count_label(info_frame, 'Assertions:')
+ @failure_count_label = create_count_label(info_frame, 'Failures:')
+ @error_count_label = create_count_label(info_frame, 'Errors:')
+
+ fault_list_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true)
+
+ fault_scrollbar = TkScrollbar.new(fault_list_frame)
+ fault_scrollbar.pack('side'=>'right', 'fill'=>'y')
+ @fault_list = TkListbox.new(fault_list_frame)
+ @fault_list.pack('fill'=>'both', 'expand'=>true)
+ @fault_list.yscrollbar(fault_scrollbar)
+
+ detail_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true)
+ detail_scrollbar_y = TkScrollbar.new(detail_frame)
+ detail_scrollbar_y.pack('side'=>'right', 'fill'=>'y')
+ detail_scrollbar_x = TkScrollbar.new(detail_frame)
+ detail_scrollbar_x.pack('side'=>'bottom', 'fill'=>'x')
+ @detail_text = TkText.new(detail_frame, 'height'=>10, 'wrap'=>'none') {
+ bindtags(bindtags - [TkText])
+ }
+ @detail_text.pack('fill'=>'both', 'expand'=>true)
+ @detail_text.yscrollbar(detail_scrollbar_y)
+ @detail_text.xscrollbar(detail_scrollbar_x)
+ end
+
+ def create_count_label(parent, label) # :nodoc:
+ TkLabel.new(parent, 'text'=>label).pack('side'=>'left', 'expand'=>true)
+ v = TkVariable.new(0)
+ TkLabel.new(parent, 'textvariable'=>v).pack('side'=>'left', 'expand'=>true)
+ v
+ end
+
+ def run_suite # :nodoc:
+ run_proc = proc {
+ @run_suite_thread = Thread.start {
+ @mediator.run_suite
+ }
+ }
+ TkAfter.new(1000, 1, run_proc).start
+ end
+ end
+ end
+ end
+ end
+end
+
+if __FILE__ == $0
+ Test::Unit::UI::Tk::TestRunner.start_command_line_test
+end