def testRandom(self):
     for i in range(1000):
         number = random.randint(1, 1000000000)
         self.assertEqual(
             AlphabeticNumbers.int_from_str(AlphabeticNumbers.str_from_int(number)),
             number
         )
Beispiel #2
0
    def to_python(self, value):
        """
        Convert range string value to ``Range`` rangeconfig value.

        Returns
        -------
        Range
        """
        value = super(RangeSelectorField, self).to_python(value)
        if value in self.empty_values:
            return

        # extract all components
        r = re.compile(
            r'^(?P<A>(?P<A1>[A-Z]+):(?P<A2>[A-Z]+))$'
            r'|^(?P<N>(?P<N1>\d+):(?P<N2>\d+))$'
            r'|^(?P<AN>(?P<AN_A1>[A-Z]+)(?P<AN_N1>\d+):(?P<AN_A2>[A-Z]+)(?P<AN_N2>\d+))$'
        )

        # make sure overall pattern is valid
        if not r.findall(value):
            raise forms.ValidationError(self.error_messages['invalid'])

        datarange = None

        # extract rangeconfig values
        m = r.match(value)
        for group in ['A', 'N', 'AN']:
            if not m.group(group):
                continue
            if group == 'A':
                datarange = Range(
                    AlphabeticNumbers.int_from_str(m.group('A1')),
                    None,
                    AlphabeticNumbers.int_from_str(m.group('A2')),
                    None
                )
            elif group == 'N':
                datarange = Range(
                    None,
                    int(m.group('N1')),
                    None,
                    int(m.group('N2'))
                )
            else:
                datarange = Range(
                    AlphabeticNumbers.int_from_str(m.group('AN_A1')),
                    int(m.group('AN_N1')),
                    AlphabeticNumbers.int_from_str(m.group('AN_A2')),
                    int(m.group('AN_N2'))
                )

        return datarange
    def test_str_from_int(self):
        data = [
            ('A', 1),
            ('Z', 26),
            ('AA', 27),
            ('BA', 53),
            ('AAA', 703),
            ('XZZ', 16926),
            ('ZZZ', 18278),
        ]
        for d in data:
            assert AlphabeticNumbers.str_from_int(d[1]) == d[0]

        for i in [0, -1]:
            with pytest.raises(ValueError):
                AlphabeticNumbers.str_from_int(i)
    def test_str_from_int(self):
        data = [
            ('A', 1),
            ('Z', 26),
            ('AA', 27),
            ('BA', 53),
            ('AAA', 703),
            ('XZZ', 16926),
            ('ZZZ', 18278),
        ]
        for d in data:
            self.assertEqual(AlphabeticNumbers.str_from_int(d[1]), d[0])

        for i in [0, -1]:
            with self.assertRaises(ValueError):
                AlphabeticNumbers.str_from_int(i)
 def test_int_from_str(self):
     data = [
         ('A', 1),
         ('Z', 26),
         ('AA', 27),
         ('BA', 53),
         ('AAA', 703),
         ('XZZ', 16926),
         ('ZZZ', 18278),
     ]
     for d in data:
         assert AlphabeticNumbers.int_from_str(d[0]) == d[1]
    def to_python(self, data, *args, **kwargs):
        """
        Uses ``CharField`` character validation. If is successful, this
        functionvalidates the rangeconfig selection. It makes sure that either
        column or row is provided and that they are both in increasing order -
        that top-left coordinate is indeed top-left since it coordinates have
        to be smaller compared to bottom-right.
        """
        data = super(self.__class__, self).to_python(data, *args, **kwargs)
        if data in EMPTY_VALUES:
            return ''

        # extract all components
        import re

        r = re.compile(
            r'^(?P<A>(?P<A1>[A-Z]+):(?P<A2>[A-Z]+))$|^(?P<N>(?P<N1>\d+):(?P<N2>\d+))$|^(?P<AN>(?P<AN_A1>[A-Z]+)(?P<AN_N1>\d+):(?P<AN_A2>[A-Z]+)(?P<AN_N2>\d+))$'
        )

        # make sure overall pattern is valid
        if not r.findall(data):
            raise forms.ValidationError(self.error_messages['invalid'])

        datarange = None

        # extract rangeconfig values
        m = r.match(data)
        for group in ['A', 'N', 'AN']:
            if not m.group(group):
                continue
            if group == 'A':
                datarange = (
                    AlphabeticNumbers.int_from_str(m.group('A1')),
                    None,
                    AlphabeticNumbers.int_from_str(m.group('A2')),
                    None
                )
            elif group == 'N':
                datarange = (
                    None,
                    int(m.group('N1')),
                    None,
                    int(m.group('N2'))
                )
            else:
                datarange = (
                    AlphabeticNumbers.int_from_str(m.group('AN_A1')),
                    int(m.group('AN_N1')),
                    AlphabeticNumbers.int_from_str(m.group('AN_A2')),
                    int(m.group('AN_N2'))
                )

        # make sure the first rangeconfig coordinate is top-left
        for i in range(2):
            if datarange[i]:
                if datarange[2 + i] < datarange[i]:
                    raise forms.ValidationError(self.error_messages['values'])

        # functions for validating rows and columns
        def validateMax(n, offset=0):
            if datarange[0 + offset]:
                if datarange[2 + offset] - datarange[0 + offset] + 1 > n:
                    return False
                return True
            return None

        # validate the maximum rows and columns
        if self.max_cols:
            if validateMax(self.max_cols) is False:
                raise forms.ValidationError(
                    self.error_messages['max_cols'].format(self.max_cols))
        if self.max_rows:
            if validateMax(self.max_rows, 1) is False:
                raise forms.ValidationError(
                    self.error_messages['max_rows'].format(self.max_rows))
        if self.max_either:
            if not validateMax(self.max_either, 1) and not validateMax(self.max_either):
                raise forms.ValidationError(
                    self.error_messages['max_either'].format(self.max_either))

        return datarange