#!/usr/bin/env ruby
# -*- ruby -*-

# Copyright 2000, 2001 by Jim Weirich (jweirich@one.net).
# All rights reserved.

# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.

require 'runit/testcase'
require 'runit/cui/testrunner'

require 'gem/listmodels'

$last_suite = RUNIT::TestSuite.new


######################################################################
class TestMethodListModel < RUNIT::TestCase

  class MockClassModel
    include Observable
    def selection
      "Parent"
    end
  end

  class MockView
    attr_accessor :updated, :list
    def initialize (model)
      @model = model
      @updated = false
    end
    def update
      @updated = true
      @list = @model.items
    end
  end

  def setup
    @finder = Gem::MethodFinder.new
    @model = Gem::MethodListModel.new (@finder)
  end

  def teardown
    @model = nil
  end

  def test_fill_class_name
    @model.fill_from("Parent")
    assert_equals "Parent", @model.source
    assert_equals ['pub'], @model.items
  end

  def test_fill_class
    @model.fill_from(Parent)
    assert_equals "Parent", @model.source
    assert_equals ['pub'], @model.items
  end

  def test_notification
    ob = MockView.new(@model)
    @model.add_observer(ob)
    assert ! ob.updated
    @model.fill_from(Parent)
    assert ob.updated
    assert_equal ob.list, @model.items
  end

  def test_observer
    cm = MockClassModel.new
    @model.use_class_model(cm)
    cm.changed
    cm.notify_observers
    assert_equals "Parent", @model.source
    assert_equals ['pub'], @model.items
  end
end

$last_suite.add_test (TestMethodListModel.suite)



######################################################################
class TestModuleListModel < RUNIT::TestCase

  class MockMonitor
    attr_reader :selection
    def initialize
      @selection = nil
    end
    def select_name (name)
      @selection = name
    end
  end

  def setup
    @model = Gem::ModuleListModel.new
  end

  def teardown
    @model = nil
  end

  def test_modules
    @model.fill_from ("Parent")
    assert_equal [Mone, Kernel].sort, @model.items
  end

  def test_monitor
    mm = MockMonitor.new
    @model.selection_monitor = mm
    assert_equal nil, mm.selection
    @model.fill_from ("Parent")
    assert_equal nil, mm.selection
    @model.select(1)
    assert_equal "Mone", mm.selection
  end
end

$last_suite.add_test (TestModuleListModel.suite)


######################################################################
class TestChildListModel < RUNIT::TestCase
  def setup
    @model = Gem::ChildListModel.new
  end

  def teardown
    @model = nil
  end

  def test_children
    @model.fill_from ("Parent")
    assert_equal [Child, Sibling], @model.items
  end

end

$last_suite.add_test (TestChildListModel.suite)


######################################################################
class TestClassListModel < RUNIT::TestCase
  def setup
    @model = Gem::ClassListModel.new
  end

  def teardown
    @model = nil
  end

  def test_classes
    @model.fill_from (nil)
    classes = @model.items
    assert classes.member?("ArgumentError")
    assert classes.member?("Array")
  end

  def test_non_system
    Gem::ClassListModel.record_system_modules
    @model.include_system = false
    @model.fill_from (nil)
    assert ! @model.items.member?("Array")
  end

  def test_selection
    assert_equal -1, @model.selection_index
    @model.fill_from (nil)
    assert_equal "", @model.selection
    @model.select(1)
    assert_equal 1, @model.selection_index
    array_index = @model.items.index("Array")
    assert array_index >= 0
    @model.select(array_index)
    assert_equal "Array", @model.selection
    @model.fill_from (nil)
    assert_equal -1, @model.selection_index
  end

  def test_select_by_name
    assert_equal -1, @model.selection_index
    @model.fill_from (nil)
    assert_equal "", @model.selection
    @model.select_name("Array")
    assert@model.selection_index >= 0
    assert_equal "Array", @model.items[@model.selection_index]
    assert_equal "Array", @model.selection
    @model.select_name("Kernel")
    assert_equal "Kernel (M)", @model.items[@model.selection_index]
  end
end

$last_suite.add_test (TestClassListModel.suite)


######################################################################
$anon = Class.new
class AnonymousParent < $anon
end

######################################################################
class TestClassListModel2 < RUNIT::TestCase

  def test_create
    cm = get_model
    assert_not_nil cm
  end

  def test_fill
    cm = get_model
    assert cm.items.member?("Integer")
    assert cm.items.member?("Kernel (M)")
  end

  def test_select
    cm = get_model
    assert_equal -1, cm.selection_index
    assert_equal "", cm.selection
    cm.select_name("Integer")
    assert cm.selection_index > -1
    assert_equal "Integer", cm.selection
  end

  def test_anonymous_classes
    cm = get_model
    cm.select_name($anon.to_s)
    assert cm.selection_index > -1
    assert_match cm.selection, /^#<Class[ 0-9a-z]+>$/
  end

  private # ----------------------------------------------------------

  def get_model
    m = Gem::ClassListModel.new
    m.fill_from("")
    m
  end    

end

$last_suite.add_test (TestClassListModel2.suite)


######################################################################
class TestClassBroswerModel < RUNIT::TestCase

  def test_create
    finder = Gem::MethodFinder.new
    bm = Gem::ClassBrowserModel.new(finder)
    assert_not_nil bm
    bm.fill
    assert bm.class_model.items.member?("Integer")
    assert bm.class_model.items.member?("AnonymousParent")
    assert_match bm.class_model.items[0], /^#<Class[ 0-9a-z]+>$/
  end
end

$last_suite.add_test (TestClassBroswerModel.suite)


######################################################################

if __FILE__ == $0 then
  RUNIT::CUI::TestRunner.quiet_mode = true
  RUNIT::CUI::TestRunner.run ($last_suite)
end
