#!/usr/bin/ruby -Ilib/
#
# test_logic: perform unit tests on apt-listbugs/logic
#
# Copyright (C) 2008       Junichi Uekawa <dancer@debian.org>
# Copyright (C) 2011-2013  Francesco Poli <invernomuto@paranoici.org>
#
#  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 with
#  the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL-2;
#  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
#  Suite 330, Boston, MA  02111-1307  USA
#
#


require 'test/unit'
require 'apt-listbugs/logic'

class Mock_config_apt
  def command()
    "apt"
  end
end

class Mock_config_list
  def command()
    "list"
  end
end

class TC_BugsFactory < Test::Unit::TestCase
  def setup
    Factory::config=Mock_config_apt.new
  end

  def teardown
    Factory::config=nil
  end

  # find_max_version_below_ver()/find_min_version_above_ver() arguments:
  #   *  space-delimited sequence of versions
  #   *  threshold version
  #   *  package name

  def test_find_max_version_below_ver

    assert_equal("1.0",
                 Factory::BugsFactory.find_max_version_below_ver("0.8 1.0 1.5 2.0",
                                                                 "1.3",
                                                                 "test"),
                 "max version below version, common case")

    assert_equal("1.0",
                 Factory::BugsFactory.find_max_version_below_ver("1.0 2.0 0.8 1.5",
                                                                 "1.3",
                                                                 "test"),
                 "max version below version, unordered versions")

    assert_equal("1.0",
                 Factory::BugsFactory.find_max_version_below_ver("0.8 1.0 1.0 1.5 2.0 2.0",
                                                                 "1.3",
                                                                 "test"),
                 "max version below version, with duplicates")

    assert_equal("1.5",
                 Factory::BugsFactory.find_max_version_below_ver("0.8 1.0 1.5 2.0",
                                                                 "1.5",
                                                                 "test"),
                 "max version below version, exact found")

    assert_equal(nil,
                 Factory::BugsFactory.find_max_version_below_ver("0.8 1.0 1.5 2.0",
                                                                 "0.5",
                                                                 "test"),
                 "max version below version, none below")

    assert_equal("2.0",
                 Factory::BugsFactory.find_max_version_below_ver("0.8 1.0 1.5 2.0",
                                                                 "2.1",
                                                                 "test"),
                 "max version below version, all below")

  end

  def test_find_min_version_above_ver

    assert_equal("1.5",
                 Factory::BugsFactory.find_min_version_above_ver("0.8 1.0 1.5 2.0",
                                                                 "1.3",
                                                                 "test"),
                 "min version above version, common case")

    assert_equal("1.5",
                 Factory::BugsFactory.find_min_version_above_ver("1.0 2.0 0.8 1.5",
                                                                 "1.3",
                                                                 "test"),
                 "min version above version, unordered versions")

    assert_equal("1.5",
                 Factory::BugsFactory.find_min_version_above_ver("0.8 0.8 1.0 1.5 1.5 2.0 2.0",
                                                                 "1.3",
                                                                 "test"),
                 "min version above version, with duplicates")

    assert_equal("1.0",
                 Factory::BugsFactory.find_min_version_above_ver("0.8 1.0 1.5 2.0",
                                                                 "0.8",
                                                                 "test"),
                 "min version above version, exact found")

    assert_equal(nil,
                 Factory::BugsFactory.find_min_version_above_ver("0.8 1.0 1.5 2.0",
                                                                 "2.5",
                                                                 "test"),
                 "min version above version, none above")

    assert_equal("0.8",
                 Factory::BugsFactory.find_min_version_above_ver("0.8 1.0 1.5 2.0",
                                                                 "0.7",
                                                                 "test"),
                 "min version above version, all above")

  end

  # am_i_buggy() arguments:
  #   *  source package name
  #   *  version under consideration
  #   *  space-delimited sequence of fixed versions
  #   *  space-delimited sequence of found versions

  def test_am_i_buggy
    # Legend:  V  version under consideration
    #          o  version where the bug is found
    #          x  version where the bug is fixed
    #          ?  irrelevant data
    #
    # version  1    2     3      4    5
    # a)  ----------------V------------------  buggy
    # b)  ----------------V------x-----------  buggy
    # c)  ----------------V------o-----------  non-buggy
    # d)  ----------------V------o----x------  non-buggy
    # e)  ----------------V------x----o------  buggy
    # e') ----------------V-----(xo)---------  buggy
    # f)  ----------o-----V--- ? -- ? -- ? --  buggy
    # f') --------------(oV)-- ? -- ? -- ? --  buggy
    # g)  ----------x-----V--- ? -- ? -- ? --  non-buggy
    # g') --------------(xV)-- ? -- ? -- ? --  non-buggy
    # h)  -----o----x-----V--- ? -- ? -- ? --  non-buggy
    # h') -----o--------(xV)-- ? -- ? -- ? --  non-buggy
    # i)  -----x----o-----V--- ? -- ? -- ? --  buggy
    # i') -----x--------(oV)-- ? -- ? -- ? --  buggy
    # j)  --------(xo)----V--- ? -- ? -- ? --  buggy
    # j') -------------(xoV)-- ? -- ? -- ? --  buggy

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 [""].join(" "), # fixed
                                                 [""].join(" ")  # found
                                                 ),
                 "a)  ----------------V------------------  buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["4"].join(" "), # fixed
                                                 [""].join(" ")  # found
                                                 ),
                 "b)  ----------------V------x-----------  buggy")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 [""].join(" "), # fixed
                                                 ["4"].join(" ")  # found
                                                 ),
                 "c)  ----------------V------o-----------  non-buggy")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["5"].join(" "), # fixed
                                                 ["4"].join(" ")  # found
                                                 ),
                 "d)  ----------------V------o----x------  non-buggy")


    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["4"].join(" "), # fixed
                                                 ["5"].join(" ")  # found
                                                 ),
                 "e)  ----------------V------x----o------  buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["4"].join(" "), # fixed
                                                 ["4"].join(" ")  # found
                                                 ),
                 "e') ----------------V-----(xo)---------  buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 [""].join(" "), # fixed
                                                 ["2"].join(" ")  # found
                                                 ),
                 "f)  ----------o-----V--- ? -- ? -- ? --  buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 [""].join(" "), # fixed
                                                 ["3"].join(" ")  # found
                                                 ),
                 "f') --------------(oV)-- ? -- ? -- ? --  buggy")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["2","4"].join(" "), # fixed
                                                 ["5"].join(" ")  # found
                                                 ),
                 "g)  ----------x-----V--- ? -- ? -- ? --  non-buggy")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["3","4"].join(" "), # fixed
                                                 ["4"].join(" ")  # found
                                                 ),
                 "g') --------------(xV)-- ? -- ? -- ? --  non-buggy")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["2","5"].join(" "), # fixed
                                                 ["1","4"].join(" ")  # found
                                                 ),
                 "h)  -----o----x-----V--- ? -- ? -- ? --  non-buggy")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["3","4"].join(" "), # fixed
                                                 ["1","5"].join(" ")  # found
                                                 ),
                 "h') -----o--------(xV)-- ? -- ? -- ? --  non-buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["1","5"].join(" "), # fixed
                                                 ["2","4"].join(" ")  # found
                                                 ),
                 "i)  -----x----o-----V--- ? -- ? -- ? --  buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["1","5"].join(" "), # fixed
                                                 ["3","5"].join(" ")  # found
                                                 ),
                 "i') -----x--------(oV)-- ? -- ? -- ? --  buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["2","4"].join(" "), # fixed
                                                 ["2","5"].join(" ")  # found
                                                 ),
                 "j)  --------(xo)----V--- ? -- ? -- ? --  buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3",
                                                 ["3","4"].join(" "), # fixed
                                                 ["3"].join(" ")  # found
                                                 ),
                 "j') -------------(xoV)-- ? -- ? -- ? --  buggy")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "1.5",
                                                 ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                 ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                 ),
                 "Bug is found right now")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "2.0",
                                                 ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                 ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                 ),
                 "Bug is fixed right now")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "1.0",
                                                 ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                 ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                 ),
                 "Bug is found and then fixed multiple times in the future")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "1.0",
                                                 "apt-test/2.0", # fixed
                                                 nil # found
                                                 ),
                 "Bug is fixed sometime in the future")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3.0",
                                                 "apt-test/2.0", # fixed
                                                 nil # found
                                                 ),
                 "Bug is fixed sometime in the past")

    assert_equal(true,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3.0",
                                                 nil, # fixed
                                                 "apt-test/1.0" # found
                                                 ),
                 "Bug is found in the past, but never fixed")

    assert_equal(false,
                 Factory::BugsFactory.am_i_buggy(
                                                 "apt-test",
                                                 "3.0",
                                                 "4.0", # fixed
                                                 "3.5" # found
                                                 ),
                 "Bug is found and then fixed in the future")

  end

  # bug_is_irrelevant() arguments:
  #   *  package name
  #   *  currently installed version, if any
  #   *  version to be installed or checked, if specified
  #   *  bug number
  #   *  space-delimited sequence of fixed versions
  #   *  space-delimited sequence of found versions
  #   *  bug stat (default: "")
  # N.B.: bug_is_irrelevant() returns true, if the bug can be ignored

  def test_bug_is_irrelevant

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        "1.5", "2.0",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "upgrade that fixes a bug")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        "1.0", "2.5",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "upgrade that skips over a bug region")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        "3.0", "3.5",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "latest upgrade that fixes a bug")


    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        "2.5", "3.0",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "latest upgrade that introduces a bug")


    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        "1.0", "3.0",
                                                        123458,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "upgrade that jumps from non-buggy to reopened buggy")

    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        "1.0", "1.7",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "upgrade that jumps into a bug region")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("audacious",
                                                        "1.5.0-1", "1.5.0-2",
                                                        485109,
                                                        nil, # fixed
                                                        ["audacious/1.4.6-2", "audacious/1.5.0-2"].join(" ")  # found
                                                        ),
                 "upgrade that jumps to a found version from an already buggy version")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        "1.7", "3.0",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "upgrade that jumps from buggy to buggy")

    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        nil, "3.0",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "new installation of a buggy version")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        nil, "3.5",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "new installation of a non-buggy version")

    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("perl",
                                                        "5.10.0-10", "5.10.0-11",
                                                        492816,
                                                        nil, # fixed
                                                        ["perl/5.10.0-11"].join(" ")  # found
                                                        ),
                 "upgrade to a newly found unfixed bug")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt",
                                                        "0.4.1", "0.7.14",
                                                        482476,
                                                        nil, # fixed
                                                        ["apt/0.7.11", "apt/0.6.46.4-0.1"].join(" "), # found
                                                        "done"
                                                        ),
                 "bug which is 'done' without fixed version info: upgrade")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt",
                                                        nil, "0.7.14",
                                                        482476,
                                                        nil, # fixed
                                                        ["apt/0.7.11", "apt/0.6.46.4-0.1"].join(" "), # found
                                                        "done"
                                                        ),
                 "bug which is 'done' without fixed version info: installation")

    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("apt",
                                                        "0.4.1", "0.7.14",
                                                        482476,
                                                        "0.7.15", # fixed
                                                        ["apt/0.7.11", "apt/0.6.46.4-0.1"].join(" "), # found
                                                        "done"
                                                        ),
                 "bug which is 'done' with fixed version info: upgrade")

    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("apt",
                                                        nil, "0.7.14",
                                                        482476,
                                                        "0.7.15", # fixed
                                                        ["apt/0.7.11", "apt/0.6.46.4-0.1"].join(" "), # found
                                                        "done"
                                                        ),
                 "bug which is 'done' with fixed version info: installation")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        "0.1", "0.2",
                                                        4321,
                                                        "0.5", # fixed
                                                        "0.3", # found
                                                        "done"
                                                        ),
                 "bug which is found and fixed in future versions")

  end
end

class TC_BugsFactory_List < Test::Unit::TestCase
  def setup
    Factory::config=Mock_config_list.new
  end

  def teardown
    Factory::config=nil
  end

  def test_bug_is_irrelevant_list

    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        nil, "3.1",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "apt-listbugs list with buggy version")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        nil, "3.6",
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "apt-listbugs list with non-buggy version")

    assert_equal(false,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        nil, nil,
                                                        123456,
                                                        ["apt-test/2.0", "apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/1.5", "apt-test/3.0"].join(" ")  # found
                                                        ),
                 "apt-listbugs list without specifying any version")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt",
                                                        nil, "0.7.14+b1",
                                                        482476,
                                                        ["0.7.14"].join(" "), # fixed
                                                        ["apt/0.7.11", "apt/0.6.46.4-0.1"].join(" ")  # found
                                                        ),
                 "apt-listbugs list apt/0.7.14+b1 which is fixed")

    assert_equal(true,
                 Factory::BugsFactory.bug_is_irrelevant("apt-test",
                                                        nil, "3.0",
                                                        123456,
                                                        ["apt-test/3.5"].join(" "), # fixed
                                                        ["apt-test/3.2"].join(" ")  # found
                                                        ),
                 "bug that is found later than this version")


  end
end

class TC_AppConfig < Test::Unit::TestCase
  def setup
    @a=AppConfig.new
  end

  def teardown
  end

  def test_statmap
    assert_equal("my_undefined",
                 @a.statmap("my_undefined"),
                 "statmap of an undefined value")

    assert_equal("Outstanding",
                 @a.statmap("pending"),
                 "statmap of pending")

    assert_equal("Forwarded",
                 @a.statmap("forwarded"),
                 "statmap of forwarded")

    assert_equal("Pending Upload",
                 @a.statmap("pending-fixed"),
                 "statmap of pending-fixed")

    assert_equal("Fixed in NMU",
                 @a.statmap("fixed"),
                 "statmap of fixed")

    assert_equal("From other Branch",
                 @a.statmap("absent"),
                 "statmap of absent")

    assert_equal("Resolved in some Version",
                 @a.statmap("done"),
                 "statmap of done")
  end
end
