El4r-1.0.0 - EmacsLisp for Ruby

Hi,

El4r enables you to write Emacs programs in Ruby as well as in
EmacsLisp.
I call the Ruby language to manipulate Emacs `EmacsRuby’.

El4r and Test::Unit enables you to test EmacsLisp/EmacsRuby programs
automatically.

El4r is available at
http://www.rubyist.net/~rubikitch/computer/el4r/index.en.html

== What’s new

=== [2005/12/01] 1.0.0 released

  • Installer.
  • Packaging policy.
  • Fixed fatal error bug.
  • Fixed defun-GC problem.
  • Renamed: el4r-runtest.rb → el4r-runtest
  • New command: el4r
  • New EmacsRuby functions.
    • define_minor_mode
    • define_derived_mode
    • eval_after_load

=== [2005/10/11] 0.9.3 released

  • el4r-runtest.rb: Raise when the test-script file is not found.
  • Now output builtin functions (p, print, puts …) are usable in
    EmacsRuby.
  • Fixed an error-handling bug.
  • More stable.

=== [2005/10/05] 0.9.2 released

  • ~/.el4rrc.rb contains all the el4r setting.
  • Automatic configuration.
  • Now el4r can be installed in arbitrary directory.
  • A block is accepted in El4r::ELMethodsMixin#newbuf .
  • New class: ElApp
  • Works with Windows(WINE).
  • Introduced el4r_load search path.
  • New EmacsRuby library in el4r/ directory.

== Download / Install / Setup
Since version 1.0.0, el4r introduced installer.
If you got error when downloading, you must update Ruby.
Here is the shell commands to download, install and setup.
el4r-rctool setups and updates your dotfiles automatically.

To update older el4r (<= 0.9.1), you must remove these lines from
~/.emacs,
(add-to-list 'load-path “~/src/el4r/elisp/”)
(require 'el4r)
(el4r-boot)
and this line from ~/.el4r/init.rb by hand.
el4r_load “el4r-mode.rb”
In newer el4r, el4r-rctool updates your dotfiles automatically.

ruby -ropen-uri -e
‘URI(“http://www.rubyist.net/~rubikitch/archive/el4r-1.0.0.tar.gz”).read.display’
| tar xzf -
cd el4r-1.0.0
ruby setup.rb

ruby -S el4r-rctool -p
ruby -S el4r-rctool -i

The diretory to put EmacsRuby scripts is ~/.el4r by default.
The environment variable EL4R_HOME sets the directory to put EmacsRuby
scripts.

Here is a test program of el4r.

el4r - EmacsLisp for Ruby

Copyright (C) 2005 rubikitch [email protected]

Version: $Id: test-el4r.rb 953 2005-11-30 17:47:46Z rubikitch $

This program is free software; you can redistribute it and/or

modify

it under the terms of the GNU General Public License as published

by

the Free Software Foundation; either version 2 of the License, or

(at your option) any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program; if not, write to the Free Software

Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA

02111-1307 USA

require ‘test/unit’

require ‘tempfile’
require ‘tmpdir’
require ‘pathname’
require ‘fileutils’
class << Tempfile
def path(content, dir=Dir.tmpdir)
x = Tempfile.open(“content”, dir)
x.write content
x.close
x.open
x.path
end

def pathname(content, dir=Dir.tmpdir)
Pathname.new(path(content, dir=Dir.tmpdir))
end
end

El4r self test.

class TestEl4r < Test::Unit::TestCase

ElMixin is already included/extended.

So we can write EmacsRuby in this class.

Testing ELListCell#to_ary.

This method enables us to multiple assignment.

def test_to_ary
list = el4r_lisp_eval(%q((list 1 2)))
one, two = list

assert_equal(list.to_a, list.to_ary)
assert_equal(1, one)
assert_equal(2, two)

end

Testing with and match-string.

def test_match_string
lisp = %q((progn
(switch-to-buffer “a”)

          (save-excursion
            (insert "abcdefg\n")
            (goto-char 1)
            (re-search-forward "^\\\\(.+\\\\)$")
            )
          (match-string 1)))

ruby = lambda{
[with]
  with(:save_excursion) do
    goto_char 1
    re_search_forward('^\\(.+\\)$')
  end
  match_string 1
[/with]
}
assert_equal(el4r_lisp_eval(lisp), ruby[])

end

helper method:

execute a block with temporary buffer.

and return the contents of buffer.

def with_temp_buffer_string(&block)
with(:with_temp_buffer){
self.instance_eval(&block)
buffer_string
}
end

this test was in test.el

def test_test_el__debug_ruby_eval_report
actual = with_temp_buffer_string {
el4r_lisp_eval %q((progn
(el4r-debug-ruby-eval-report “nil”)
(el4r-debug-ruby-eval-report “true”)
(el4r-debug-ruby-eval-report “false”)
(el4r-debug-ruby-eval-report “1 + 6”)
(el4r-debug-ruby-eval-report “"String"”)
))
}
expected = <<EOB
nil
=> nil
true
=> t
false
=> nil
1 + 6
=> 7
“String”
=> “String”
EOB
assert_equal(expected, actual)
end

def test_test_el__condition_case

# (mode-info-describe-function 'signal 'elisp)
# (mode-info-describe-function 'condition-case 'elisp)
el4r_lisp_eval %q((progn

(put 'test-error
'error-conditions
'(error test-error))
(put 'test-error ‘error-message “Test Error”)
))
#’
el4r_lisp_eval %q((progn
(setq error-desc nil)
(condition-case err
(signal 'test-error ‘(123))
(test-error (setq error-desc (format “Error is passed: %s” err)))
)
))
#’
assert_equal(“Error is passed: (test-error 123)”, elvar.error_desc)

el4r_lisp_eval %q((progn

(setq error-desc nil)
(condition-case err
(el4r-ruby-eval “el4r_lisp_eval("(signal 'test-error '(123))")”)
(test-error (setq error-desc (format “Error is passed: %s” err)))
)
))
#’
assert_equal(“Error is passed: (test-error 123)”, elvar.error_desc)
end

eval test

def test_el4r_eval
result = with_temp_buffer_string{
el4r_lisp_eval(<<‘EOF’)
(insert-string (el4r-ruby-eval “"Hello from ruby from emacs
from ruby!\n"”))
EOF
}
assert_equal(“Hello from ruby from emacs from ruby!\n”, result)
assert_equal(true, el4r_lisp_eval(‘t’))
end

list: cons, car/cdr

def test_list
list = el(“'(3 2 1)”)
list = cons(4, list)
assert_equal(“(4 3 2 1)”, prin1_to_string(list))

ary = []
while list
  ary << car(list)
  list = cdr(list)
end
assert_equal("[4, 3, 2, 1]", ary.inspect)

end

pass a Ruby object to Emacs

def test_object
obj = Object.new
assert_equal(“Is ruby object passed? … true”,
“Is ruby object passed? … #{car(cons(obj, nil)) ==
obj}”)
end

Using defun ( Proc → Lambda conversion )

def test_defun_function
defun(:my_ruby_func) { |a|
0
}
# redefine
defun(:my_ruby_func) { |a|
“String from my_ruby_func: ‘#{a}’”
}
assert_equal(“String from my_ruby_func: ‘Hello!’”,
my_ruby_func(“Hello!”))
end

defun a command

def test_defun_command_1
defun(:my_command, :interactive => true) {
insert_string(“My Interactive command from Ruby.”); newline
}

assert_equal("My Interactive command from Ruby.\n",
             with_temp_buffer_string{ 

call_interactively(:my_command) })

end

defun a command with docstring

def test_defun_command_2

[my_command2]
defun(:my_command2,
      :interactive => "d", :docstring => "description...") { |point|
  insert_string("Current point is #{point}."); newline
}
[/my_command2]
assert_equal("d", nth(1, commandp(:my_command2)))
assert_equal("description...", documentation(:my_command2))
assert_equal("Current point is 1.\n",
             with_temp_buffer_string{ 

call_interactively(:my_command2) })
end

defining odd-named function

def test_defun_oddname
# Lisp can define `1+1’ function! LOL
defun(“1+1”){2}
assert_equal(2, funcall(“1+1”))
end

Calling lambda

def test_lambda
lambda = el4r_lisp_eval(“(lambda (i) (+ i 1))”)
assert_equal(2, funcall(lambda, 1))
end

Calling special form like save-excursion

def test_with
x = with_temp_buffer_string {
insert_string(“a\n”)
with(:save_excursion) {
beginning_of_buffer
insert_string(“This is inserted at the beginning of buffer.”);
newline
}
}
assert_equal(“This is inserted at the beginning of buffer.\na\n”, x)
end

ELListCell

def test_ELListCell
assert_equal([1, 2], cons(1, cons(2, nil)).to_a )
assert_equal([10,20], el4r_lisp_eval(%((list 1 2))).map{|x| x*10})

assert_equal({'a'=>1, 'b'=>2}, list(cons("a",1), cons("b", 

2)).to_hash)
assert_raises(TypeError){ list(cons(“a”,1), “b”, “c”).to_hash }

assert_equal("ELListCell[1]", list(1).inspect)
assert_equal("ELListCell[1, 2]", list(1,2).inspect)

end

ELConsCell

def test_ELConsCell
assert_equal([1,2], el4r_cons_to_rubyary(cons(1,2)))
assert_equal(“ELConsCell[1, 2]”, cons(1,2).inspect)

assert_equal("ELListCell[1, 2, ELConsCell[3, 4]]", 

list(1,2,cons(3,4)).inspect)
assert_equal(“ELListCell[1, 2]”, cons(1, list(2)).inspect)
end

ELVector

def test_ELVector
v = el4r_lisp_eval(“[1 2]”)
assert( vectorp(v) )
assert_equal(“ELVector[1, 2]”, v.inspect)
assert_equal(1, v[0])
assert_equal(1, v[-2])
assert_raises(ArgumentError) { v[2] } # index is too large
assert_raises(TypeError) { v[“X”] }

assert_equal([1, 2], v[0,2])
assert_equal([1, 2], v.to_a)

# Enumerable
assert_equal(1, v.find{|x| x==1})

# to_ary
one, = v
assert_equal(1, one)

# aset
elvar.v = v
assert_equal(10, v[0]=10)
assert_equal(10, v[0])
assert_equal([10,2], v.to_a)
assert_equal(10, elvar.v[0])
assert_equal([10,2], elvar.v.to_a)
assert_raises(ArgumentError) { v[2]=3 } # index is too large
assert_raises(TypeError) { v["X"]=1 }

v[-1]=20
assert_equal([10,20], elvar.v.to_a)

end

Accessing to lisp variables with elvar

def test_elvar
elvar.myvar = 123
assert_equal(123, elvar.myvar)

elvar["myvar"] = 456
assert_equal(456, elvar["myvar"])

assert( elvar.myvar == elvar["myvar"] )

end

get/set an odd-named variable

def test_elvar__oddname
elvar[“an/odd+variable!”] = 10
assert_equal(10, elvar[“an/odd+variable!”])
end

Error passing

def test_error
assert_raises(RuntimeError) {
el4r_lisp_eval(<<-‘EOF’)
(el4r-ruby-eval “raise "Is error handled correctly?"”))
EOF
}
end

let

def test_let
elvar.testval = 12
testval_in_letblock = nil
let(:testval, 24) {
testval_in_letblock = elvar.testval
}

assert_equal(24, testval_in_letblock)
assert_equal(12, elvar.testval)

end

Regexp convert: Convert Ruby regexps to MESSY Emacs regexps.

def test_regexp

(find-node “(emacs-ja)Regexps”)

conv = lambda{|from,to| assert_equal(to, el4r_conv_regexp(from)) }
conv[ //, '' ]
conv[ /a/, 'a' ]
conv[ /a./, 'a.' ]
conv[ /a*/, 'a*' ]
conv[ /a+/, 'a+' ]
conv[ /a?/, 'a?' ]
conv[ /[ab]/, '[ab]' ]
conv[ /[^ab]/, '[^ab]' ]
conv[ /^ab/, '^ab' ]
conv[ /ab$/, 'ab$' ]
conv[ /a|b/, 'a\|b' ]
conv[ /(ab)/, '\(ab\)' ]
conv[ /\As/, '\`s' ]
conv[ /s\Z/, %q[s\'] ]
# \=
conv[ /\bball\B/, '\bball\B']
# \<
# \>
conv[ /\w/, '[0-9A-Za-z_]']
conv[ /\W/, '[^0-9A-Za-z_]']
# \sC
# \SC
# \D (number)

end

Now you can specify a Ruby regexp to string-match, re-search-forward

and so on
def test_string_match
s = “a”
assert_equal(0, string_match(“a”, s))
assert_equal(0, string_match(/a/, s))
assert_equal(0, string_match(‘(a|\b)’, s))
assert_equal(0, string_match(/a|b/, s))
assert_equal(0, string_match(/^a/, s))
assert_equal(0, string_match(/a$/, s))
assert_equal(0, string_match(/.*/, s))
assert_equal(nil, string_match(/not-match/, s))

end

ElMixin: elisp {}

def test_elmixin
eval %{
class ::Foo
include ElMixin
def foo
elisp {
[self.class, outer.class]
}
end

    def one
      1
    end
  end

}

el4r, outer = Foo.new.foo
assert_equal(El4r::ELInstance, el4r)
assert_equal(Foo, outer)

end

EL error

def test_elerror
errormsg = nil
begin
el4r_lisp_eval(%q((defun errorfunc0 ())))
with(:with_current_buffer, “scratch”){
let(:x, 1) {
with(:save_excursion){
errorfunc0 1 # wrong number of argument!!
}
}
}
flunk
rescue
errormsg = $!.to_s
end

assert_match(/\n\(errorfunc0.+save-excursion.+let.+with-current-buffer.+$/m, 

errormsg.to_s)
end

to_s: Implicitly call prin1_to_string

def test_to_s
list = funcall(:list,1)
assert_equal(“(1)”, “#{list}”)
assert_equal( prin1_to_string(list), list.to_s)
end

defadvice 1

def test_defadvice_1
defun(:adtest1){
elvar.v = 1
}
with(:defadvice, el(“adtest1 (after adv activate)”)){
elvar.v = 2
}
adtest1

assert_equal(2, elvar.v)

end

defadvice 2

def test_defadvice_2
elvar.w = 0
elvar.x = 0
defun(:adtest2){
elvar.w += 1
3
}
defadvice(:adtest2, :around, :adv2, :activate) {
ad_do_it
elvar.x = 10
ad_do_it
}
ret = adtest2()

assert_equal(2, elvar.w)
assert_equal(10, elvar.x)
assert_equal(3, ret)

end

defadvice 3

def test_defadvice_3
begin

[adtest3]
  # define a function
  defun(:adtest3){ 1 }
[/adtest3]
  assert_equal(1, adtest3())
  assert_equal(nil, commandp(:adtest3))
[adtest3-advice]
  # now define an advice
  defadvice(:adtest3, :around, :adv3, :activate,
            :docstring=>"test advice", :interactive=>true) {
    ad_do_it
    elvar.ad_return_value = 2
  }
[/ad_return_value]
  assert(commandp(:adtest3))
  assert_equal(2, adtest3())
  assert_match(/test advice/, documentation(:adtest3))
ensure
  ad_deactivate :adtest3

fmakunbound :adtest3

end

end

bufstr

def test_bufstr
s = bufstr(newbuf(:name=>“axx”, :contents=>“foo!”))
assert_equal(“foo!”, s)

newbuf(:name=>"axxg", :contents=>"bar!", :current=>true)
s = bufstr
assert_equal("bar!", s)

end

def xtest_ad_do_it_invalid
assert_raises(El4r::El4rError){
ad_do_it
}
end

el_load

def test_el_load
begin
el = File.expand_path(“elloadtest.el”)
open(el, “w”){|w| w.puts(%q((setq elloadtest 100)))}
el_load(el)
assert_equal(100, elvar.elloadtest)
ensure
File.unlink el
end
end

equality

def test_EQUAL
b1 = current_buffer
b2 = current_buffer
assert(b1 == b1)
assert(b1 == b2)
assert_equal(b1,b2)
end

test delete-other-windows workaround in xemacs

def test_delete_other_windows
w = selected_window
elvar.window_min_height = 1
split_window
split_window
delete_other_windows
assert(one_window_p)
assert(eq(w, selected_window))
end

Lisp string → Ruby string special case

def test_el4r_lisp2ruby__normal
cmp = lambda{|str| assert_equal(str, eval(el4r_lisp2ruby(str)))}

(mode-info-describe-function 'prin1-to-string 'elisp)

(string= “\021” (el4r-ruby-eval (el4r-lisp2ruby “\021”)))

cmp[ "" ]
cmp[ "a"*999999 ]
cmp[ '1' ]
cmp[ 'a' ]
cmp[ '\\' ]
cmp[ '\\\\' ]
cmp[ '\\\\\\' ]
cmp[ '""' ]
cmp[ '"' ]
cmp[ "''" ]
cmp[ '#{1}' ]
cmp[ '\#{1}' ]
cmp[ '#{\'1\'}' ]
cmp[ '#@a' ]
cmp[ "\306\374\313\334\270\354" ]  # NIHONGO in EUC-JP

end

def test_el4r_lisp2ruby__treat_ctrl_codes
cmp = lambda{|str| assert_equal(str, eval(el4r_lisp2ruby(str)))}
elvar.coding_system_for_write :binary
elvar.coding_system_for_write :binary
set_buffer_file_coding_system :binary
el4r_treat_ctrl_codes {
cmp[ “” ]
cmp[ “a”*999999 ]
cmp[ ‘1’ ]
cmp[ ‘a’ ]
cmp[ ‘\’ ]
cmp[ ‘\\’ ]
cmp[ ‘\\\’ ]
cmp[ ‘“”’ ]
cmp[ ‘"’ ]
cmp[ “‘’” ]
cmp[ ‘#{1}’ ]
cmp[ ‘#{1}’ ]
cmp[ ‘#{'1'}’ ]
cmp[ ‘#@a’ ]

  cmp[ "\ca" ]
  cmp[ "\cb" ]
  cmp[ "\cc" ]
  cmp[ "\cd" ]
  cmp[ "\ce" ]
  cmp[ "\cf" ]
  cmp[ "\cg" ]
  cmp[ "\ch" ]
  cmp[ "\ci" ]
  cmp[ "\cj" ]
  cmp[ "\ck" ]
  cmp[ "\cl" ]
  # C-m
  # cmp[ "\cn" ]  failed on xemacs
  # cmp[ "\co" ]  failed on xemacs
  cmp[ "\cp" ]
  cmp[ "\cq" ]
  # C-r
  cmp[ "\cs" ]
  cmp[ "\ct" ]
  cmp[ "\cu" ]
  cmp[ "\cv" ]
  cmp[ "\cw" ]
  cmp[ "\cx" ]
  # cmp[ "\cy" ]
  cmp[ "\cz" ]
  cmp[ "\306\374\313\334\270\354" ]  # NIHONGO in EUC-JP
}

end

def el4r_load_test_helper(dir)
begin
$loaded = nil
tmpscript = “#{dir}/testtmp.rb”
“$loaded = true”.writef(tmpscript)
el4r_load “testtmp.rb”
assert_equal(true, $loaded)
ensure
FileUtils.rm_f tmpscript
end
end

def test_el4r_load__load_path
begin
load_path_orig = el4r.conf.el4r_load_path
tmp = Dir.tmpdir
load_path = [ tmp, “#{tmp}/a” ]
el4r.conf.el4r_load_path = load_path
load_path.each do |dir|
FileUtils.mkdir_p dir
el4r_load_test_helper dir
end
ensure
el4r.conf.el4r_load_path = load_path_orig
FileUtils.rm_rf “#{tmp}/a”
end

end

def test_el4r_load__not_exist
assert_raises(LoadError) { el4r_load “__not_exist.rb” }
assert_equal(false, el4r_load(“__not_exist.rb”, true))
end

def test_el4r_load__order
begin
$loaded = nil
load_path = el4r.conf.el4r_load_path = [ el4r_homedir,
el4r.site_dir ]
FileUtils.mkdir_p load_path
rb = “testtmp.rb”
home_rb = File.expand_path(rb, el4r_homedir)
site_rb = File.expand_path(rb, el4r.site_dir)
“$loaded = :OK”.writef(home_rb)
“$loaded = :NG”.writef(site_rb)
el4r_load rb
assert_equal(:OK, $loaded)
ensure
FileUtils.rm_f [home_rb, site_rb]
end
end

def test_stdlib_loaded
assert_equal(true, fboundp(:winconf_push))
end

def test_winconf
# make a winconf
switch_to_buffer “a buffer”
insert “string”
pt = point
# current_window_configuration does not works with xemacs -batch. I
do not know why.
assert( one_window_p )
buf = current_buffer

winconf_push

# alter the winconf
goto_char 1
split_window

winconf_pop

# revive the winconf
assert( one_window_p )
assert_equal(buf, current_buffer)
assert_equal(pt, point)

end

def test_el4r_output
printf(“\t\n\ca!%s!”,“a”)
print(1)
assert_equal(“\t\n\ca!a!1”, bufstr(“el4r:output”))
end

def test_process_autoloads
begin
tmp = Dir.tmpdir
autoload_dir = “#{tmp}/autoload”
FileUtils.mkdir_p autoload_dir
$ary = []
%w[01first.rb 02second.rb 03third.rb].each_with_index do |fn, i|
open(File.join(autoload_dir, fn), “w”){|f| f.write “$ary <<
#{i}” }
end
el4r_process_autoloads autoload_dir

  assert_equal [0,1,2], $ary
ensure
  FileUtils.rm_rf autoload_dir
end

end

def test_eval_after_load
begin
tmp = Dir.tmpdir
add_to_list :load_path, tmp
el = “#{tmp}/hoge.el”
open(el, “w”){|f| f.write “(setq hoge 100)” }

  elvar.hoge = 1
  eval_after_load("hoge") do
    elvar.hoge = 200
  end
  assert_equal 1, elvar.hoge

  el_load "hoge"
  assert_equal 200, elvar.hoge
ensure
  FileUtils.rm_f el
end

end

def test_define_derived_mode
@passed = false

[derived]
define_derived_mode(:foo_mode, :fundamental_mode, "FOO", "doc") do
  @passed = true
end
[/derived]
assert_equal false, @passed
foo_mode
assert_equal true, @passed
assert_equal "foo-mode", elvar.major_mode.to_s

@passed = false
define_derived_mode("bar-mode", el(:foo_mode), "Bar") do
  @passed = true
end
assert_equal false, @passed
bar_mode
assert_equal true, @passed

define_derived_mode("baz-mode", el(:bar_mode), "Baz")
baz_mode
assert_equal "baz-mode", elvar.major_mode.to_s

end

def test_define_minor_mode
@passed = false

[minor-mode]
define_minor_mode(:a_minor_mode, "test minor mode") do
  @passed = true
end
[/minor-mode]
assert_equal false, @passed
a_minor_mode
assert_equal true, @passed
assert_equal true, elvar.a_minor_mode

end

end of TestEl4r

end

newbuf examples

class TestNewbuf < Test::Unit::TestCase
include ElMixin

def setup
@bufname = “buffer-does-not-exist!!!”
end

def teardown
kill_buffer(@bufname) if get_buffer(@bufname)
end

def setbuf
set_buffer @x
end

def test_create
@x = newbuf(:name=>@bufname)
setbuf
assert_equal(true, bufferp(@x))
assert_equal(@bufname, buffer_name(@x))
assert_equal(“”, buffer_string)

y = newbuf(:name=>@bufname)
assert(eq(@x,y))

end

def test_contents
@x = newbuf(:name=>@bufname, :contents=>“foo”)
setbuf
assert_equal(“foo”, buffer_string)
assert_equal(4, “foo”.length+1)
assert_equal(4, point)

# buffer is erased
@x = newbuf(:name=>@bufname, :contents=>"bar")
setbuf
assert_equal("bar", buffer_string)

end

def test_file
begin
file = Tempfile.path(“abcd”)
@x = newbuf(:file=>file)
setbuf
assert_equal(file, buffer_file_name)
assert_equal(“abcd”, buffer_string)
ensure
kill_buffer nil
File.unlink file
end
end

def test_name_and_file
begin
file1 = Tempfile.path(“abcd”)
@x = newbuf(:name=>@bufname, :file=>file1)
setbuf
assert_equal(nil, buffer_file_name)
assert_equal(“abcd”, buffer_string)

  # buffer is erased
  file2 = Tempfile.path("abcde")
  @x = newbuf(:name=>@bufname, :file=>file2)
  setbuf
  assert_equal("abcde", buffer_string)

ensure
  kill_buffer nil
  File.unlink file1
  File.unlink file2
end

end

def test_argerror
assert_raises(ArgumentError){ newbuf }
assert_raises(ArgumentError){ newbuf(:name=>nil) }
assert_raises(ArgumentError){ newbuf(1) }
assert_raises(ArgumentError){ newbuf(“1”) } # hmm.
assert_raises(ArgumentError){ newbuf(:name=>@bufname, :line=>“a”) }
assert_raises(ArgumentError){ newbuf(:name=>@bufname, :point=>“a”) }
end

def test_current_line
@x = newbuf(:name=>@bufname, :contents=>“a\nb\nc\nd”, :line=>2)
setbuf
assert_equal(“b”, char_to_string(char_after))
end

def test_point
@x = newbuf(:name=>@bufname, :contents=>“abcde”, :point=>2)
setbuf
assert_equal(“b”, char_to_string(char_after))
end

def test_display
elvar.pop_up_windows = true
@x = newbuf(:name=>@bufname, :display=>true)
assert(get_buffer_window(@x))
assert_nil(one_window_p)
assert_nil(eq(selected_window, get_buffer_window(@x)))
end

def test_display_pop
elvar.pop_up_windows = true
@x = newbuf(:name=>@bufname, :display=>:pop)
assert(get_buffer_window(@x))
assert_nil(one_window_p)
assert(eq(selected_window, get_buffer_window(@x)))
end

def test_display_only
elvar.pop_up_windows = true
@x = newbuf(:name=>@bufname, :display=>:only)
assert(get_buffer_window(@x))
assert(one_window_p)
assert(eq(selected_window, get_buffer_window(@x)))
end

def test_current
@x = newbuf(:name=>@bufname, :current=>true)
assert_nil(get_buffer_window(@x))
assert(eq(current_buffer, @x))
end

def test_read_only
b1 = newbuf(:name=>@bufname, :current=>true, :read_only=>true,
:contents=>“a”)
assert(eq(elvar.buffer_read_only, true))
assert_equal(“a”, buffer_string)

b2 = newbuf(:name=>@bufname, :current=>true, :read_only=>true, 

:contents=>“c”)
assert(eq(b1,b2))
assert(eq(elvar.buffer_read_only, true))
assert_equal(“c”, buffer_string)
end

def test_bury
buf = newbuf(:name=>@bufname, :display=>:pop, :bury=>true)
assert(eq(buf, (buffer_list nil)[-1]))
end

def test_block
buf = newbuf(:name=>@bufname, :current=>true) {
text_mode
}
mode = with(:with_current_buffer,buf){elvar.major_mode}.to_s
assert_equal(“text-mode”, mode)
end
end

class TestDefunWithinClass < Test::Unit::TestCase

class Foo
include ElMixin

def initialize(x)
  elvar.v = x[:value]
  defun(:twice_v) do
    elvar.v *= 2
  end

  defun(:str0) do
    do_str0 x[:str]
  end
end

def do_str0(str)
  (str*2).upcase
end

end

def test0
Foo.new(:value=>10, :str=>“ab”)
twice_v
assert_equal(20, elvar.v)
assert_equal(“ABAB”, str0)
end
end

class TestElApp < Test::Unit::TestCase

class Foo < ElApp
def initialize(x)
elvar.v = x[:value]
defun(:twice_v) do
elvar.v *= 2
end

  defun(:str0) do
    do_str0 x[:str]
  end
end

def do_str0(str)
  (str*2).capitalize
end

end

def test0
Foo.run(:value=>10, :str=>“ab”)
twice_v
assert_equal(20, elvar.v)
assert_equal(“Abab”, str0)
end
end