From fe44329fce99028fec0f99711ca5cf76760dd67d Mon Sep 17 00:00:00 2001 From: Luis Lavena Date: Sat, 25 Apr 2009 21:18:49 -0300 Subject: [PATCH] Added README, examples and tests, courtesy of Daniel Berger. --- README | 58 ++++++++ examples/example_readline.rb | 8 ++ examples/example_readline_with_completion.rb | 18 +++ test/test_rbreadline.rb | 13 ++ test/test_readline.rb | 133 +++++++++++++++++++ 5 files changed, 230 insertions(+) create mode 100644 README create mode 100644 examples/example_readline.rb create mode 100644 examples/example_readline_with_completion.rb create mode 100644 test/test_rbreadline.rb create mode 100644 test/test_readline.rb diff --git a/README b/README new file mode 100644 index 0000000..0f759fa --- /dev/null +++ b/README @@ -0,0 +1,58 @@ += Description + +The readline library provides a pure Ruby implementation of the GNU +readline C library, as well as the Readline extension that ships as part +of the standard library. + += Synopsis + require 'readline' + + loop do + line = Readline::readline('> ') + Readline::HISTORY.push(line) + puts "You typed: #{line}" + break if line == 'quit' + end + += Motivation + +First, building the GNU readline library on MS Windows with Visual C++ is +nigh impossible. However, certain libraries depend on readline. By providing +a pure Ruby version we eliminate the entire compiler compatibility issue. + +Second, even on distributions of Windows built with MinGW (that include +the readline library for Windows), the behavior was sometimes erratic and +would break. + +Third, even on certain Unix distributions the GNU readline library is not +guaranteed to be installed. Providing a pure Ruby readline eliminates the +need to install a C library first. It's also one less link in the dependency +chain, meaning we don't need to worry about possible changes in the underlying +C library affecting our interface. + +Fourth, by making the interface pure Ruby, we increase the likelihood of +receiving patches, feature requests, documentation updates, etc from the +community at large, since not everyone knows C. + +Lastly, the Readline interface that ships as part of the standard library is +weak, and only provides a very limited subset of the actual GNU readline +library. By providing a pure Ruby implementation we allow 3rd party library +authors to write their own interface as they see fit. + += Tutorial + +For an excellent tutorial on how to use Readline in practice, please see +Joseph Pecoraro's examples at http://bogojoker.com/readline/. There is also +documentation by Michael Fellinger at http://p.ramaze.net/18421.md. + += Alternatives + +See Rawline for a library that began life in pure Ruby and provides an +interface that's probably more comfortable to Ruby programmer. It has certain +features that Readline does not. In addition, it provides a Readline +compatibility mode. + += Authors + +* Park Heesob (C translation, code donated as part of bounty) +* Daniel Berger (Documentation and testing) diff --git a/examples/example_readline.rb b/examples/example_readline.rb new file mode 100644 index 0000000..cf910b3 --- /dev/null +++ b/examples/example_readline.rb @@ -0,0 +1,8 @@ +require 'readline' + +loop do + line = Readline::readline('> ') + Readline::HISTORY.push(line) + puts "You typed: #{line}" + break if line == 'quit' +end diff --git a/examples/example_readline_with_completion.rb b/examples/example_readline_with_completion.rb new file mode 100644 index 0000000..0f645c8 --- /dev/null +++ b/examples/example_readline_with_completion.rb @@ -0,0 +1,18 @@ +require 'readline' + +list = [ + 'search', 'download', 'open', + 'help', 'history', 'quit', + 'url', 'next', 'clear', + 'prev', 'past', +].sort + +comp = proc{ |s| list.grep( /^#{Regexp.escape(s)}/) } + +Readline.completion_append_character = " " +Readline.completion_proc = comp + +while line = Readline.readline('> ', true) + p line + break if line == 'quit' +end diff --git a/test/test_rbreadline.rb b/test/test_rbreadline.rb new file mode 100644 index 0000000..849bf37 --- /dev/null +++ b/test/test_rbreadline.rb @@ -0,0 +1,13 @@ +require 'rubygems' +gem 'test-unit' + +require 'test/unit' +require 'rbreadline' + +class TC_Pr_RbReadline < Test::Unit::TestCase + def test_versions + assert_equal('5.2', RbReadline::RL_LIBRARY_VERSION) + assert_equal(0x0502, RbReadline::RL_READLINE_VERSION) + assert_equal('0.1.0', RbReadline::RB_READLINE_VERSION) + end +end diff --git a/test/test_readline.rb b/test/test_readline.rb new file mode 100644 index 0000000..7114f78 --- /dev/null +++ b/test/test_readline.rb @@ -0,0 +1,133 @@ +require 'rubygems' +gem 'test-unit' + +require 'test/unit' +require 'readline' + +class TC_Pr_Readline < Test::Unit::TestCase + def setup + @proc = proc{ |s| ['alpha', 'beta'].grep( /^#{Regexp.escape(s)}/) } + end + + def test_version + assert_equal('5.2', Readline::VERSION) + end + + def test_readline_basic + assert_respond_to(Readline, :readline) + end + + def test_readline_expected_errors + assert_raise(ArgumentError){ Readline.readline } + end + + def test_input_basic + assert_respond_to(Readline, :input=) + end + + def test_input + assert_nothing_raised{ Readline.input = $stdin } + end + + def test_output_basic + assert_respond_to(Readline, :output=) + end + + def test_output + assert_nothing_raised{ Readline.output = $stdout } + end + + def test_completion_proc_get_basic + assert_respond_to(Readline, :completion_proc) + end + + def test_completion_proc_set_basic + assert_respond_to(Readline, :completion_proc=) + end + + def test_completion_proc + assert_nothing_raised{ Readline.completion_proc = @proc } + end + + def test_completion_case_fold_get_basic + assert_respond_to(Readline, :completion_case_fold) + end + + def test_completion_case_fold + assert_equal(false, Readline.completion_case_fold) # default + end + + def test_completion_case_fold_set_basic + assert_respond_to(Readline, :completion_case_fold=) + end + + def test_completion_case_fold + assert_nothing_raised{ Readline.completion_case_fold = false } + end + + def test_completion_proc_expected_errors + assert_raise(ArgumentError){ Readline.completion_proc = 1 } + assert_raise(ArgumentError){ Readline.completion_proc = 'a' } + end + + def test_vi_editing_mode_basic + assert_respond_to(Readline, :vi_editing_mode) + end + + def test_emacs_editing_mode_basic + assert_respond_to(Readline, :emacs_editing_mode) + end + + def test_completion_append_character_get_basic + assert_respond_to(Readline, :completion_append_character) + end + + def test_completion_append_character_get + assert_equal(' ', Readline.completion_append_character) # default + end + + def test_completion_append_character_set_basic + assert_respond_to(Readline, :completion_append_character=) + end + + def test_completion_append_character_set + assert_nothing_raised{ Readline.completion_append_character } + end + + def test_basic_word_break_characters_get_basic + assert_respond_to(Readline, :basic_word_break_characters) + end + + def test_basic_word_break_characters_get + assert_equal(" \t\n\"\\'`@$><=|&{(", Readline.basic_word_break_characters) + end + + def test_basic_word_break_characters_set_basic + assert_respond_to(Readline, :basic_word_break_characters=) + end + + def test_basic_word_break_characters_set + assert_nothing_raised{ Readline.basic_word_break_characters = " \t\n\"\\'`@$><=|&{(" } + end + + def test_basic_quote_characters_get_basic + assert_respond_to(Readline, :basic_quote_characters) + end + + def test_basic_quote_characters_get + assert_nothing_raised{ Readline.basic_quote_characters } + assert_equal("\"'", Readline.basic_quote_characters) + end + + def test_basic_quote_characters_set_basic + assert_respond_to(Readline, :basic_quote_characters=) + end + + def test_basic_quote_characters_set + assert_nothing_raised{ Readline.basic_quote_characters = "\"'" } + end + + def teardown + @proc = nil + end +end