#!/usr/local/bin/ruby -d -Ke

require 'textbuf'

puts

def ev( code, bind = nil )
  eval code, bind || TOPLEVEL_BINDING
end


$assert_n = 1

def chk( code, bind = nil )
  unless ev( code, bind ) then
    raise ArgumentError, "\n\ntest #{$assert_n} fail: #{code}"
  end
  $assert_n += 1
end

def try( code, bind = nil )
  print "trying test #{$assert_n}: #{code} ..."
  ev code, bind
  puts "ok"
  $assert_n += 1
end

$stdout.sync = true

###
###
###

puts 'fundamental test'

buf = TextBuffer.new
try "buf.inspect"

m = buf.new_mark
try "m.inspect"

try "GC.start"

#----

puts 'insertion test'

str1 = 'string1'
str2 = 'string2'
str3 = 'string3'
m.insert str1
m.insert str2
m.insert str3

$whole = str1 + str2 + str3

chk 'm.index == $whole.size'
chk "m.index == m.byte_index"

#----

puts 'back test'

m.back 1
chk 'm.index == $whole.size - 1'
chk 'm.index == m.byte_index'

m.back 1
chk 'm.index == $whole.size - 2'
chk "m.index == m.byte_index"

m.back 1
chk 'm.index == $whole.size - 3'
chk "m.index == m.byte_index"

#----

puts 'forward test'

m.forward 1
chk 'm.index == $whole.size - 2'
chk "m.index == m.byte_index"

m.forward 1
chk 'm.index == $whole.size - 1'
chk "m.index == m.byte_index"

m.forward 1
chk 'm.index == $whole.size'
chk "m.index == m.byte_index"

#----

puts 'motion test (big)'

m.forward 1000
m.back    1000
m.forward 1000
m.back    1000
m.forward 1000
m.back    1000

chk 'm.index == 0'
chk "m.index == m.byte_index"

#----

puts 'substr test'

chk 'm[1000] == $whole'
chk 'm[5] == $whole[0,5]'

#---

puts 'mark list test'

m2 = buf.new_mark
chk 'm2.index == 0'
chk "m2.index == m2.byte_index"

m2.forward 1
chk 'm2.index == 1'
chk "m2.index == m2.byte_index"

m2.forward 1
chk 'm2.index == 2'
chk "m2.index == m2.byte_index"

m2.forward 1
chk 'm2.index == 3'
chk "m2.index == m2.byte_index"

chk 'm2[5] == $whole[3,5]'

m3 = buf.new_mark(0)
chk 'm3.index == 0'
chk "m3.index == m3.byte_index"

m2.back 1
chk 'm2.index == 2'
chk "m2.index == m2.byte_index"

m2.back 1
chk 'm2.index == 1'
chk "m2.index == m2.byte_index"

m2.back 1
chk 'm2.index == 0'
chk "m2.index == m2.byte_index"

chk 'm2[5] == $whole[0,5]'


#----

puts 'RO each test'

m.head
s = ''
m.each_line_ro do |line|
  s << line
  try "GC.start", binding
end
chk 's == $whole'
try "GC.start"


#----

puts 'insert again'

m2.forward 1000

1.times do
  0.upto( 9 ) do |i|
    m2.insert i.to_s
    m2.back 1
  end
end
m2.back 1000

chk "m2[1000] == buf.string"

chk "m2.line == 1"


#----

puts 'motion test (2)'

m2.head
chk "m2.index == 0"
m2.tail
chk "m2.index == buf.size"
m2.head
chk "m2.index == 0"

chk "m2.line == 1"

#----

puts 'delete test (2)'

buf.size.times do
  m2.delete 1
end
chk "buf.size == 0"

chk "m2.line == 1"


#----

puts 'freeze check'

mm = buf.new_mark
# mm.insert 'str' * 10
mm.freeze
freeze_check = true
begin
  mm.move 1
  freeze_check = false
rescue
  puts "frozen check worked: #{$!}"
end
chk 'freeze_check'


#----

puts 'line test'

m.head
m.insert "line\n" * 10
chk 'm.line == 11'

m.prev_line
chk 'm.line == 10'

m.prev_line
m.prev_line
chk 'm.line == 8'

m.prev_line
m.next_line
chk 'm.line == 8'

m.line -= 3
chk 'm.line == 5'

m.line += 2
chk 'm.line == 7'

m.head
chk 'm.index == 0'
chk 'm.line == 1'

#----

puts 'match test'

chk 'buf.index(/line/) == 0'
chk "buf.index('line') == 0"

#----

puts 'etc test'

buf.clear
chk 'buf.size == 0'
chk 'm.index == 0'

#----

puts 'japanese test'

buf.clear
m.insert 'あいうえおかきくけこ'
chk 'buf.size == 10'
chk 'buf.byte_size == 20'

m.head
chk 'm.index == 0'
m.forward 1
chk 'm.index == 1'
chk 'm.byte_index == 2'
m.forward 1
chk 'm.index == 2'
chk 'm.byte_index == 4'
m.back 1
chk 'm.index == 1'
chk 'm.byte_index == 2'

chk "m[1] == 'い'"
chk "m[2] == 'いう'"

m.delete 1
chk "m[1] == 'う'"
chk "m[2] == 'うえ'"

#----

puts 'gc test (final)'

m2 = nil
try 'GC.start'

buf = nil
try 'GC.start'

m = nil
try 'GC.start'

#----

puts 'insertion test (heavy)'

buf = TextBuffer.new
a = 'a'
10000.times { buf << a }

#----

print "\n\n    ok\n\n\n"
