1"""
2Digress comparers.
3"""
4
5from digress.errors import ComparisonError
6
7import os
8from itertools import imap, izip
9
10def compare_direct(value_a, value_b):
11    if value_a != value_b:
12        raise ComparisonError("%s is not %s" % (value_a, value_b))
13
14def compare_pass(value_a, value_b):
15    """
16    Always true, as long as the test is passed.
17    """
18
19def compare_tolerance(tolerance):
20    def _compare_tolerance(value_a, value_b):
21        if abs(value_a - value_b) > tolerance:
22            raise ComparisonError("%s is not %s (tolerance: %s)" % (
23                value_a,
24                value_b,
25                tolerance
26            ))
27    return _compare_tolerance
28
29def compare_files(file_a, file_b):
30    size_a = os.path.getsize(file_a)
31    size_b = os.path.getsize(file_b)
32
33    print file_a, file_b
34
35    if size_a != size_b:
36        raise ComparisonError("%s is not the same size as %s" % (
37            file_a,
38            file_b
39        ))
40
41    BUFFER_SIZE = 8196
42
43    offset = 0
44
45    with open(file_a) as f_a:
46        with open(file_b) as f_b:
47            for chunk_a, chunk_b in izip(
48                imap(
49                    lambda i: f_a.read(BUFFER_SIZE),
50                    xrange(size_a // BUFFER_SIZE + 1)
51                ),
52                imap(
53                    lambda i: f_b.read(BUFFER_SIZE),
54                    xrange(size_b // BUFFER_SIZE + 1)
55                )
56            ):
57                chunk_size = len(chunk_a)
58
59                if chunk_a != chunk_b:
60                    for i in xrange(chunk_size):
61                        if chunk_a[i] != chunk_b[i]:
62                            raise ComparisonError("%s differs from %s at offset %d" % (
63                                file_a,
64                                file_b,
65                                offset + i
66                            ))
67
68                offset += chunk_size
69