#
# test_version.py
#
# Test suite for the distutils.version module.  This test suite
# completely thumbs its nose at the Python style of comparing
# previously-generated output files with new output from the current
# code.  Thbbtbttt!!  Instead it uses the Perl style of printing out "ok
# x" or "not ok x" for each individual test, so that no a priori
# knowledge outside of the test program is needed to determine if it
# succeeds; it is self-containing (apart from the module being tested).
# 
# Also, there are currently several tests known to fail with the
# LooseVersion class.  There's nothing wrong with the code; it's clear
# and simple code written to a clear and simple specification.  I just
# don't think that specification is enough to meet people's expectations
# about comparing version numbers with letters in them, and I've written
# the test suite around those comparisons rather than around matching
# the specification to the implementation.  Probably bad practice -- sue
# me.
#
# written by Greg Ward, 1998/12/17
#
# $Id$
#

from distutils.version import StrictVersion, LooseVersion


TestNum = 0


def test (code, globs):
    global TestNum

    TestNum = TestNum + 1
    ok = eval (code, globs)
    if ok:
        print "ok %d" % TestNum
    else:
        print "not ok %d: '%s' not true" % (TestNum, code)
        

def test_cmp (test_class, v1, v2, expected):
    global TestNum

    if expected == '==':
        ok = ((test_class (v1) == test_class (v2)) and
              (test_class (v1) == v2) and
              (v1 == test_class (v2)))
    elif expected == '>':
        ok = ((test_class (v1) > test_class (v2)) and
              (test_class (v1) > v2) and
              (v1 > test_class (v2)))
    elif expected == '<':
        ok = ((test_class (v1) < test_class (v2)) and
              (test_class (v1) < v2) and
              (v1 < test_class (v2)))

    TestNum = TestNum + 1
    if ok:
        print "ok %d" % TestNum
    else:
        print "not ok %d: with %s, expected %s %s %s" % \
              (TestNum, test_class.__name__, v1, expected, v2)


def test_str (test_class, vstring, expected=None):
    global TestNum

    if expected is None: expected = vstring
    ver = test_class (vstring)
    TestNum = TestNum + 1
    if (str (ver) == expected):
        print "ok %d" % TestNum
    else:
        print "not ok %d: with %s, expected str (%s) == %s" % \
              (TestNum, test_class.__name__, vstring, expected)


v1 = StrictVersion ('3.4.2')
v2 = StrictVersion ('3.4.2a3')
v3 = StrictVersion ('3.4.3')

test ("v1 > v2", globals())
test ("v1 == '3.4.2'", globals())
test ("v1 < '3.4.3'", globals())
test ("v1 > '3.4.2b3'", globals())
test ("v2 < v3", globals())
test ("v3 > v1", globals())

test_cmp (StrictVersion, '3.4.2', '3.4.2', '==')
test_cmp (StrictVersion, '3.3', '3.3.0', '==')
test_cmp (StrictVersion, '3.3', '3.3.1', '<')
test_cmp (StrictVersion, '1.0', '0.9', '>')
test_cmp (StrictVersion, '1.0', '0.9a3', '>')
test_cmp (StrictVersion, '1.0', '1.0a3', '>')
test_cmp (StrictVersion, '1.0a10', '1.0a2', '>')
test_cmp (StrictVersion, '1.0.3', '1.0.2b4', '>')
test_cmp (StrictVersion, '1.0.3a3', '1.0.3a2', '>')
test_cmp (StrictVersion, '1.0.3a3', '1.0.2', '>')

test_str (StrictVersion, '0.9')
test_str (StrictVersion, '0.9.3')
test_str (StrictVersion, '0.9.0', '0.9')
test_str (StrictVersion, '1.0a3')
test_str (StrictVersion, '1.0.3b3')

# duplicate the above tests; as expected, LooseVersion gives
# counterintuitive results when comparing a "prerelease" version
# number ('1.0a3') with the same version minus "prerelease" stuff
# ('1.0')
test_cmp (LooseVersion, '3.4.2', '3.4.2', '==')
print "expect failure:"
test_cmp (LooseVersion, '3.3', '3.3.0', '==') # how *should* these compare?
test_cmp (LooseVersion, '3.3', '3.3.1', '<')
test_cmp (LooseVersion, '1.0', '0.9', '>')
test_cmp (LooseVersion, '1.0', '0.9a3', '>')
print "expect failure:"
test_cmp (LooseVersion, '1.0', '1.0a3', '>')
test_cmp (LooseVersion, '1.0a10', '1.0a2', '>')
test_cmp (LooseVersion, '1.0.3', '1.0.2b4', '>')
test_cmp (LooseVersion, '1.0.3a3', '1.0.3a2', '>')
test_cmp (LooseVersion, '1.0.3a3', '1.0.2', '>')

test_str (LooseVersion, '0.9')
test_str (LooseVersion, '0.9.3')
test_str (LooseVersion, '0.9.0')    # 0.9.0 and 0.9 NOT equivalent!
test_str (LooseVersion, '1.0a3')
test_str (LooseVersion, '1.0.3b3')

# now a bunch of stuff that can only be represented using LooseVersion
# (note that I have coded these tests as to how I *think* LooseVersion
# should behave, not as to how I know it must behave! thus some
# of these will fail)
test_cmp (LooseVersion, '1.5.1', '1.5.2b2', '<')
test_cmp (LooseVersion, '1.5.2b2', '1.5.2b3', '<')
print "expect failure:"
test_cmp (LooseVersion, '1.5.2b2', '1.5.2', '<')
test_cmp (LooseVersion, '1996.07.12', '1996.06.24', '>')
test_cmp (LooseVersion, '3.2.pl1', '3.2', '>')
test_cmp (LooseVersion, '3.2.pl1', '3.2.pl6', '<')
test_cmp (LooseVersion, '3.2.pl6', '3.3', '<')
test_cmp (LooseVersion, '3.2pl1', '3.2', '>')
test_cmp (LooseVersion, '3.2pl1', '3.2pl6', '<')
test_cmp (LooseVersion, '3.2pl6', '3.3', '<')
test_cmp (LooseVersion, '2.2beta29', '2.2beta29', '==')
print "expect failure:"
test_cmp (LooseVersion, '2.2beta29', '2.2', '<')
test_cmp (LooseVersion, '2.2beta29', '2.2beta30', '<')
test_cmp (LooseVersion, '2.2beta29', '2.2beta25', '>')
test_cmp (LooseVersion, '2.2beta29', '2.3.0', '<')
test_cmp (LooseVersion, '1.13++', '1.13+', '>')
test_cmp (LooseVersion, '1.13++', '1.13+++', '<')

samples = [
  '1.5.1',
  '1.5.2b2',
  '161',
  '3.10a',
  '8.02',
  '3.4j',
  '1996.07.12',
  '3.2.pl0',
  '3.1.1.6',
  '2g6',
  '11g',
  '0.960923',
  '2.2beta29',
  '1.13++',
  '5.5.kw',
  '2.0b1pl0',
  ]

map (lambda v: test_str (LooseVersion, v), samples)
