OSDN Git Service

Merge branch '201312-KinPenalty' into wdoor-stable
[shogi-server/shogi-server.git] / test / TC_command.rb
index 7c23e1b..5e231fa 100644 (file)
 $:.unshift File.join(File.dirname(__FILE__), "..")
+$topdir = File.expand_path File.dirname(__FILE__)
 require 'test/unit'
+require 'tempfile'
+require 'test/mock_game'
+require 'test/mock_log_message'
+require 'test/mock_player'
 require 'shogi_server/login'
 require 'shogi_server/player'
 require 'shogi_server/command'
 
-def log_warning(str)
-  $stderr.puts str
-end
-
-def log_error(str)
-  $stderr.puts str
-end
-
-class MockPlayer < ShogiServer::BasicPlayer
-  attr_reader :out
-  attr_accessor :game, :status, :protocol
-  attr_accessor :game_name
-
-  def initialize
-    @out      = []
-    @game     = nil
-    @status   = nil
-    @protocol = nil
-    @game_name = "dummy_game_name"
-  end
-
-  def write_safe(str)
-    @out << str
-  end
-end
-
-class MockGame
-  attr_accessor :finish_flag
-  attr_reader :log
-  attr_accessor :prepared_expire
-  attr_accessor :rejected
-  attr_accessor :is_startable_status
-  attr_accessor :started
-  attr_accessor :game_id
 
+class MockLeague
   def initialize
-    @finish_flag     = false
-    @log             = []
-    @prepared_expire = false
-    @rejected        = false
-    @is_startable_status = false
-    @started             = false
-    @game_id         = "dummy_game_id"
-    @monitoron_called = false
-    @monitoroff_called = false
-  end
-
-  def handle_one_move(move, player)
-    return @finish_flag
-  end
-
-  def log_game(str)
-    @log << str
-  end
-
-  def prepared_expire?
-    return @prepared_expire
-  end
+    @games = {}
+    @games["dummy_game_id"] = MockGame.new
 
-  def reject(str)
-    @rejected = true
+    reset_players
   end
 
-  def is_startable_status?
-    return @is_startable_status
+  def reset_players
+    $p1 = MockPlayer.new
+    $p1.name = "p1"
+    $p1.status = "game_waiting"
+    $p1.sente = true
+    $p2 = MockPlayer.new
+    $p2.name = "p2"
+    $p2.status = "game_waiting"
+    $p2.sente = false
   end
 
-  def start
-    @started = true
+  def games
+    return @games
   end
 
-  def show
-    return "dummy_game_show"
+  def rated_players
+    return []
   end
 
-  def monitoron(player)
-    @monitoron_called = true
+  def players
+    return [MockPlayer.new]
   end
 
-  def monitoroff(player)
-    @monitoroff_called = true
+  def event
+    return "test"
   end
-end
 
-class MockLeague
-  def initialize
-    @games = {}
-    @games["dummy_game_id"] = MockGame.new
+  def dir
+    return $topdir
   end
 
-  def games
-    return @games
+  def get_player(status, game_id, sente, searcher)
+    if sente == true
+      return $p1
+    elsif sente == false
+      return $p2
+    elsif sente == nil
+      return nil
+    else
+      return nil
+    end
   end
 
-  def rated_players
-    return []
+  def find_all_players
+    [$p1,$p2].each {|pp| yield pp}
   end
 
-  def players
-    return [MockPlayer.new]
+  def find_rival(player, game_name)
+    case player.sente
+    when nil # no preference
+      return get_player("game_waiting", game_name, nil, player)
+    when true # rival must be gote
+      return get_player("game_waiting", game_name, false, player) 
+    when false # rival must be sente 
+      return get_player("game_waiting", game_name, true, player) 
+    else
+      return :continue
+    end
   end
 end
 
@@ -112,6 +84,7 @@ class TestFactoryMethod < Test::Unit::TestCase
 
   def setup
     @p = MockPlayer.new
+    @p.name = "test_factory_method_player"
     $league = MockLeague.new
   end
 
@@ -160,11 +133,21 @@ class TestFactoryMethod < Test::Unit::TestCase
     assert_instance_of(ShogiServer::MonitorOnCommand, cmd)
   end
 
+  def test_monitor2on_command
+    cmd = ShogiServer::Command.factory("%%MONITOR2ON game_id", @p)
+    assert_instance_of(ShogiServer::Monitor2OnCommand, cmd)
+  end
+
   def test_monitoroff_command
     cmd = ShogiServer::Command.factory("%%MONITOROFF game_id", @p)
     assert_instance_of(ShogiServer::MonitorOffCommand, cmd)
   end
 
+  def test_monitor2off_command
+    cmd = ShogiServer::Command.factory("%%MONITOR2OFF game_id", @p)
+    assert_instance_of(ShogiServer::Monitor2OffCommand, cmd)
+  end
+
   def test_help_command
     cmd = ShogiServer::Command.factory("%%HELP", @p)
     assert_instance_of(ShogiServer::HelpCommand, cmd)
@@ -225,9 +208,68 @@ class TestFactoryMethod < Test::Unit::TestCase
     assert_instance_of(ShogiServer::SpaceCommand, cmd)
   end
 
+  def test_setbuoy_command
+    cmd = ShogiServer::Command.factory("%%SETBUOY buoy_test-1500-0 +7776FU", @p)
+    assert_instance_of(ShogiServer::SetBuoyCommand, cmd)
+  end
+
+  def test_setbuoy_command_with_counter
+    cmd = ShogiServer::Command.factory("%%SETBUOY buoy_test-1500-0 +7776FU 3", @p)
+    assert_instance_of(ShogiServer::SetBuoyCommand, cmd)
+  end
+
+  def test_deletebuoy_command
+    cmd = ShogiServer::Command.factory("%%DELETEBUOY buoy_test-1500-0", @p)
+    assert_instance_of(ShogiServer::DeleteBuoyCommand, cmd)
+  end
+
+  def test_getbuoycount_command
+    cmd = ShogiServer::Command.factory("%%GETBUOYCOUNT buoy_test-1500-0", @p)
+    assert_instance_of(ShogiServer::GetBuoyCountCommand, cmd)
+  end
+
+  def test_fork_command
+    cmd = ShogiServer::Command.factory("%%FORK server-denou-14400-60+p1+p2+20130223185013 buoy_denou-14400-60", @p)
+    assert_instance_of(ShogiServer::ForkCommand, cmd)
+  end
+
+  def test_fork_command2
+    cmd = ShogiServer::Command.factory("%%FORK server-denou-14400-60+p1+p2+20130223185013", @p)
+    assert_instance_of(ShogiServer::ForkCommand, cmd)
+  end
+
+  def test_void_command
+    cmd = ShogiServer::Command.factory("%%%HOGE", @p)
+    assert_instance_of(ShogiServer::VoidCommand, cmd)
+  end
+
   def test_error
     cmd = ShogiServer::Command.factory("should_be_error", @p)
     assert_instance_of(ShogiServer::ErrorCommand, cmd)
+    cmd.call
+    assert_match /unknown command: should_be_error/, cmd.msg
+  end
+
+  def test_error_login
+    cmd = ShogiServer::Command.factory("LOGIN hoge foo", @p)
+    assert_instance_of(ShogiServer::ErrorCommand, cmd)
+    cmd.call
+    assert_no_match /unknown command: LOGIN hoge foo/, cmd.msg
+
+    cmd = ShogiServer::Command.factory("LOGin hoge foo", @p)
+    assert_instance_of(ShogiServer::ErrorCommand, cmd)
+    cmd.call
+    assert_no_match /unknown command: LOGIN hoge foo/, cmd.msg
+
+    cmd = ShogiServer::Command.factory("LOGIN  hoge foo", @p)
+    assert_instance_of(ShogiServer::ErrorCommand, cmd)
+    cmd.call
+    assert_no_match /unknown command: LOGIN hoge foo/, cmd.msg
+
+    cmd = ShogiServer::Command.factory("LOGINhoge foo", @p)
+    assert_instance_of(ShogiServer::ErrorCommand, cmd)
+    cmd.call
+    assert_no_match /unknown command: LOGIN hoge foo/, cmd.msg
   end
 end
 
@@ -465,6 +507,46 @@ class TestMonitorOnCommand < Test::Unit::TestCase
 
     assert_equal(:continue, rc)
   end
+
+  def test_call_read_logfile
+    game = MockGame.new
+    cmd = ShogiServer::MonitorOnCommand.new("%%MONITORON hoge", @p, game)
+    rc = cmd.call
+    assert_equal("##[MONITOR][dummy_game_id] dummy_game_show\n##[MONITOR][dummy_game_id] line1\n##[MONITOR][dummy_game_id] line2\n##[MONITOR][dummy_game_id] +OK\n", @p.out.join)
+    assert_equal(:continue, rc)
+  end
+end
+
+#
+#
+class TestMonitor2OnCommand < Test::Unit::TestCase 
+  def setup
+    @p = MockPlayer.new
+    @game = MockGame.new
+    @p.game = @game
+  end
+
+  def test_call
+    cmd = ShogiServer::Monitor2OnCommand.new("%%MONITOR2ON hoge", @p, nil)
+    rc = cmd.call
+
+    assert_equal(:continue, rc)
+  end
+
+  def test_call_read_logfile
+    $tempfile = Tempfile.new("TC_command_test_call_read_logfile")
+    $tempfile.write "hoge\nfoo\n"
+    $tempfile.close
+    game = MockGame.new
+    def game.logfile
+      $tempfile.path
+    end
+    cmd = ShogiServer::Monitor2OnCommand.new("%%MONITOR2ON hoge", @p, game)
+    rc = cmd.call
+    assert_equal("##[MONITOR2][dummy_game_id] hoge\n##[MONITOR2][dummy_game_id] foo\n##[MONITOR2][dummy_game_id] +OK\n", @p.out.join)
+    assert_equal(:continue, rc)
+    $tempfile = nil
+  end
 end
 
 #
@@ -486,6 +568,23 @@ end
 
 #
 #
+class TestMonitor2OffCommand < Test::Unit::TestCase 
+  def setup
+    @p = MockPlayer.new
+    @game = MockGame.new
+    @p.game = @game
+  end
+
+  def test_call
+    cmd = ShogiServer::Monitor2OffCommand.new("%%MONITOR2OFF hoge", @p, nil)
+    rc = cmd.call
+
+    assert_equal(:continue, rc)
+  end
+end
+
+#
+#
 class TestHelpCommand < Test::Unit::TestCase 
   def setup
     @p = MockPlayer.new
@@ -706,4 +805,281 @@ class TestErrorCommand < Test::Unit::TestCase
   end
 end
 
+class BaseTestBuoyCommand < Test::Unit::TestCase
+  def setup
+    @p = MockPlayer.new
+    $league = MockLeague.new
+
+    delete_buoy_yaml
+    @buoy = ShogiServer::Buoy.new
+  end
+
+  def teadown
+    delete_buoy_yaml
+  end
+
+  def delete_buoy_yaml
+    file = File.join($topdir, "buoy.yaml")
+    File.delete file if File.exist? file
+  end
+
+  def test_dummy
+    assert true
+  end
+end
+
+
+#
+#
+class TestSetBuoyCommand < BaseTestBuoyCommand
+  
+  def setup
+    super
+    @p.name = "set_buoy_player"
+  end
+
+  def test_call_2
+    assert @buoy.is_new_game?("buoy_hoge-1500-0")
+    cmd = ShogiServer::SetBuoyCommand.new "%%SETBUOY", @p, "buoy_hoge-1500-0", "+7776FU", 2
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert !@buoy.is_new_game?("buoy_hoge-1500-0")
+    assert !$p1.out.empty?
+    assert !$p2.out.empty?
+    buoy_game2 = @buoy.get_game("buoy_hoge-1500-0")
+    assert_equal ShogiServer::BuoyGame.new("buoy_hoge-1500-0", "+7776FU", @p.name, 1), buoy_game2
+  end
+
+  def test_call_1
+    assert @buoy.is_new_game?("buoy_hoge-1500-0")
+    cmd = ShogiServer::SetBuoyCommand.new "%%SETBUOY", @p, "buoy_hoge-1500-0", "+7776FU", 1
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert @buoy.is_new_game?("buoy_hoge-1500-0")
+    assert !$p1.out.empty?
+    assert !$p2.out.empty?
+  end
+
+  def test_call_error_not_buoy_game_name
+    assert @buoy.is_new_game?("buoy_hoge-1500-0")
+    cmd = ShogiServer::SetBuoyCommand.new "%%SETBUOY", @p, "buoyhoge-1500-0", "+7776FU", 1
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert $p1.out.empty?
+    assert $p2.out.empty?
+    assert @buoy.is_new_game?("buoy_hoge-1500-0")
+  end
+
+  def test_call_error_duplicated_game_name
+    assert @buoy.is_new_game?("buoy_duplicated-1500-0")
+    bg = ShogiServer::BuoyGame.new("buoy_duplicated-1500-0", ["+7776FU"], @p.name, 1)
+    @buoy.add_game bg
+    assert !@buoy.is_new_game?("buoy_duplicated-1500-0")
+    
+    cmd = ShogiServer::SetBuoyCommand.new "%%SETBUOY", @p, "buoy_duplicated-1500-0", "+7776FU", 1
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert $p1.out.empty?
+    assert $p2.out.empty?
+    assert !@buoy.is_new_game?("buoy_duplicated-1500-0")
+  end
+
+  def test_call_error_bad_moves
+    assert @buoy.is_new_game?("buoy_badmoves-1500-0")
+    cmd = ShogiServer::SetBuoyCommand.new "%%SETBUOY", @p, "buoy_badmoves-1500-0", "+7776FU+8786FU", 1
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert $p1.out.empty?
+    assert $p2.out.empty?
+    assert @buoy.is_new_game?("buoy_badmoves-1500-0")
+  end
+
+  def test_call_error_bad_counter
+    assert @buoy.is_new_game?("buoy_badcounter-1500-0")
+    cmd = ShogiServer::SetBuoyCommand.new "%%SETBUOY", @p, "buoy_badcounter-1500-0", "+7776FU", 0
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert $p1.out.empty?
+    assert $p2.out.empty?
+    assert @buoy.is_new_game?("buoy_badcounter-1500-0")
+  end
+end
+
+
+#
+#
+class TestDeleteBuoyCommand < BaseTestBuoyCommand
+  def test_call
+    buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1)
+    assert @buoy.is_new_game?(buoy_game.game_name)
+    @buoy.add_game buoy_game
+    assert !@buoy.is_new_game?(buoy_game.game_name)
+    cmd = ShogiServer::DeleteBuoyCommand.new "%%DELETEBUOY", @p, buoy_game.game_name
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert $p1.out.empty?
+    assert $p2.out.empty?
+    assert @buoy.is_new_game?(buoy_game.game_name)
+  end
+
+  def test_call_not_exist
+    buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1)
+    assert @buoy.is_new_game?(buoy_game.game_name)
+    cmd = ShogiServer::DeleteBuoyCommand.new "%%DELETEBUOY", @p, buoy_game.game_name
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert $p1.out.empty?
+    assert $p2.out.empty?
+    assert @buoy.is_new_game?(buoy_game.game_name)
+  end
+
+  def test_call_another_player
+    buoy_game = ShogiServer::BuoyGame.new("buoy_anotherplayer-1500-0", "+7776FU", "another_player", 1)
+    assert @buoy.is_new_game?(buoy_game.game_name)
+    @buoy.add_game(buoy_game)
+    assert !@buoy.is_new_game?(buoy_game.game_name)
+
+    cmd = ShogiServer::DeleteBuoyCommand.new "%%DELETEBUOY", @p, buoy_game.game_name
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert_equal "##[ERROR] you are not allowed to delete a buoy game that you did not set: buoy_anotherplayer-1500-0\n", @p.out.first
+    assert !@buoy.is_new_game?(buoy_game.game_name)
+  end
+end
+
+#
+#
+class TestForkCommand < Test::Unit::TestCase
+  def setup
+    @player = MockPlayer.new
+  end
+
+  def test_new_buoy_game_name
+    src = "%%FORK server+denou-14400-60+p1+p2+20130223185013"
+    c = ShogiServer::ForkCommand.new src, @player, "server+denou-14400-60+p1+p2+20130223185013", nil, 13
+    c.decide_new_buoy_game_name
+    assert_equal "buoy_denou_13-14400-60", c.new_buoy_game
+  end
+
+  def test_new_buoy_game_name2
+    src = "%%FORK server+denou-14400-060+p1+p2+20130223185013"
+    c = ShogiServer::ForkCommand.new src, @player, "server+denou-14400-060+p1+p2+20130223185013", nil, 13
+    c.decide_new_buoy_game_name
+    assert_equal "buoy_denou_13-14400-060", c.new_buoy_game
+  end
+end
+
+#
+#
+class TestGetBuoyCountCommand < BaseTestBuoyCommand
+  def test_call
+    buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1)
+    assert @buoy.is_new_game?(buoy_game.game_name)
+    @buoy.add_game buoy_game
+    assert !@buoy.is_new_game?(buoy_game.game_name)
+    cmd = ShogiServer::GetBuoyCountCommand.new "%%GETBUOYCOUNT", @p, buoy_game.game_name
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert_equal ["##[GETBUOYCOUNT] 1\n", "##[GETBUOYCOUNT] +OK\n"], @p.out
+  end
+
+  def test_call_not_exist
+    buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1)
+    assert @buoy.is_new_game?(buoy_game.game_name)
+    cmd = ShogiServer::GetBuoyCountCommand.new "%%GETBUOYCOUNT", @p, buoy_game.game_name
+    rt = cmd.call
+    assert_equal :continue, rt
+    assert_equal ["##[GETBUOYCOUNT] -1\n", "##[GETBUOYCOUNT] +OK\n"], @p.out
+  end
+end
+
+#
+#
+class TestMonitorHandler < Test::Unit::TestCase
+  def test_not_equal_players
+    @player1 = MockPlayer.new
+    @handler1 = ShogiServer::MonitorHandler1.new @player1
+    @player2 = MockPlayer.new
+    @handler2 = ShogiServer::MonitorHandler1.new @player2
+
+    assert_not_equal(@handler1, @handler2)
+  end
+
+  def test_equal
+    @player1 = MockPlayer.new
+    @handler1 = ShogiServer::MonitorHandler1.new @player1
+    @handler2 = ShogiServer::MonitorHandler1.new @player1
+
+    assert_equal(@handler1, @handler2)
+  end
+end
+
+#
+#
+class TestMonitorHandler1 < Test::Unit::TestCase
+  def setup
+    @player = MockPlayer.new
+    @handler = ShogiServer::MonitorHandler1.new @player
+  end
+
+  def test_type
+    assert_equal(1, @handler.type)
+  end
 
+  def test_header
+    assert_equal("MONITOR", @handler.header)
+  end
+  
+  def test_equal
+    assert_equal @handler, @handler
+    assert_not_equal @handler, nil
+  end
+
+  def test_not_equal
+    assert_not_equal(@handler, ShogiServer::MonitorHandler2.new(@player))
+  end
+
+  def test_write_safe
+    @handler.write_safe("game_id", "hoge")
+    assert_equal("##[MONITOR][game_id] hoge\n##[MONITOR][game_id] +OK\n", 
+                 @player.out.join)
+  end
+end
+
+#
+#
+class TestMonitorHandler2 < Test::Unit::TestCase
+  def setup
+    @player = MockPlayer.new
+    @handler = ShogiServer::MonitorHandler2.new @player
+  end
+
+  def test_type
+    assert_equal(2, @handler.type)
+  end
+
+  def test_header
+    assert_equal("MONITOR2", @handler.header)
+  end
+
+  def test_equal
+    assert_equal @handler, @handler
+    assert_not_equal @handler, nil
+  end
+
+  def test_not_equal
+    assert_not_equal(@handler, ShogiServer::MonitorHandler1.new(@player))
+  end
+
+  def test_write_safe
+    @handler.write_safe("game_id", "hoge")
+    assert_equal("##[MONITOR2][game_id] hoge\n##[MONITOR2][game_id] +OK\n", 
+                 @player.out.join)
+  end
+
+  def test_write_safe2
+    @handler.write_safe("game_id", "hoge\nfoo")
+    assert_equal("##[MONITOR2][game_id] hoge\n##[MONITOR2][game_id] foo\n##[MONITOR2][game_id] +OK\n", 
+                 @player.out.join)
+  end
+end