cocos2d / cocos2d-console

cocos2d command line tool
152 stars 190 forks source link

New version_compare() function #425

Closed olehermanse closed 7 years ago

olehermanse commented 7 years ago

Follow up from: #424

def version_compare(a, op, b):
    '''Compares two version numbers to see if a op b is true

    op is operator
    op can be ">", "<", "==", "!=", ">=", "<="
    a and b are version numbers (dot separated)
    a and b can be string, float or int

    Please note that: 3 == 3.0 == 3.0.0 ... ("==" is not a simple string cmp)
    '''
    allowed = [">", "<", "==", "!=", ">=", "<="]
    if op not in allowed:
        raise ValueError("op must be one of {}".format(allowed))

    # Use recursion to simplify operators:
    if op[0] == "<": # Reverse args and inequality sign:
        return version_compare(b, op.replace("<",">"), a)
    if op == ">=":
        return version_compare(a,"==",b) or version_compare(a,">",b)
    if op == "!=":
        return not version_compare(a,"==",b)

    # We now have 1 of 2 base cases, "==" or ">":
    assert op in ["==", ">"]

    a = [int(x) for x in str(a).split(".")]
    b = [int(x) for x in str(b).split(".")]

    for i in range(max(len(a), len(b))):
        ai, bi = 0, 0   # digits
        if len(a) > i:
            ai = a[i]
        if len(b) > i:
            bi = b[i]
        if ai > bi:
            if op == ">":
                return True
            else: # op "=="
                return False
        if ai < bi:
            # Both "==" and ">" are False:
            return False
    if op == ">":
        return False    # op ">" and all digits were equal
    return True         # op "==" and all digits were equal

# Previous version_minimum tests:
assert version_compare(1, ">=", 1.0)
assert version_compare(1, ">=", "1.0.0")
assert version_compare(2, ">=", 1)
assert version_compare(2.0, ">=", 1.0)
assert version_compare(2.3, ">=", 2.2)
assert version_compare("8.3.3", ">=", 8.3)
assert version_compare("3.10.1", ">=", "3.1.0.1")
assert not version_compare(1, ">=", 2)
assert not version_compare(8.2, ">=", 8.3)
assert not version_compare("8.0.0.1", ">=", 8.1)
assert not version_compare("3.1.0.1", ">=", "3.10.1")

# New tests:
assert version_compare(1, "==", 1.0)
assert version_compare(3.7, "==", "3.7.0")
assert version_compare(1.0, "==", "1.0.0.0.0")
assert not version_compare(1.0, "==", "1.1")
assert not version_compare(1.0, "==", "1.0.0.0.1")
assert version_compare(1, ">", 0)
assert not version_compare(1, ">", 2)
assert version_compare(10, "<", 100)
assert version_compare(999, "<", 9999)
assert version_compare("3.1.1", "<", 3.11)
assert not version_compare(3, "<", 2)
assert version_compare("10", "!=", 100)
assert not version_compare(10, "!=", "10")
assert version_compare(50, "<=", 50)
assert version_compare(49, "<=", 50)
assert not version_compare("4.99", "<=", .499)
assert version_compare("3.1.1", "<=", 3.11)

print("Works fine")
$ python3 version_compare.py 
Works fine