1#
2# Copyright (c) 2010 Testrepository Contributors
3#
4# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
5# license at the users choice. A copy of both licenses are available in the
6# project source as Apache-2.0 and BSD. You may not use this file except in
7# compliance with one of these two licences.
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
12# license you chose for the specific language governing permissions and
13# limitations under that license.
14
15"""Tests for the arguments package."""
16
17from testtools.matchers import (
18    Equals,
19    raises,
20    )
21
22from testrepository import arguments
23from testrepository.tests import ResourcedTestCase
24
25
26class TestAbstractArgument(ResourcedTestCase):
27
28    def test_init_base(self):
29        arg = arguments.AbstractArgument('name')
30        self.assertEqual('name', arg.name)
31        self.assertEqual('name', arg.summary())
32
33    def test_init_optional(self):
34        arg = arguments.AbstractArgument('name', min=0)
35        self.assertEqual(0, arg.minimum_count)
36        self.assertEqual('name?', arg.summary())
37
38    def test_init_repeating(self):
39        arg = arguments.AbstractArgument('name', max=None)
40        self.assertEqual(None, arg.maximum_count)
41        self.assertEqual('name+', arg.summary())
42
43    def test_init_optional_repeating(self):
44        arg = arguments.AbstractArgument('name', min=0, max=None)
45        self.assertEqual(None, arg.maximum_count)
46        self.assertEqual('name*', arg.summary())
47
48    def test_init_arbitrary(self):
49        arg = arguments.AbstractArgument('name', max=2)
50        self.assertEqual('name{1,2}', arg.summary())
51
52    def test_init_arbitrary_infinite(self):
53        arg = arguments.AbstractArgument('name', min=2, max=None)
54        self.assertEqual('name{2,}', arg.summary())
55
56    def test_parsing_calls__parse_one(self):
57        calls = []
58        class AnArgument(arguments.AbstractArgument):
59            def _parse_one(self, arg):
60                calls.append(arg)
61                return ('1', arg)
62        argument = AnArgument('foo', max=2)
63        args = ['thing', 'other', 'stranger']
64        # results are returned
65        self.assertEqual([('1', 'thing'), ('1', 'other')],
66            argument.parse(args))
67        # used args are removed
68        self.assertEqual(['stranger'], args)
69        # parse function was used
70        self.assertEqual(['thing', 'other'], calls)
71
72    def test_parsing_unlimited(self):
73        class AnArgument(arguments.AbstractArgument):
74            def _parse_one(self, arg):
75                return arg
76        argument = AnArgument('foo', max=None)
77        args = ['thing', 'other']
78        # results are returned
79        self.assertEqual(['thing', 'other'], argument.parse(args))
80        # used args are removed
81        self.assertEqual([], args)
82
83    def test_parsing_too_few(self):
84        class AnArgument(arguments.AbstractArgument):
85            def _parse_one(self, arg):
86                return arg
87        argument = AnArgument('foo')
88        self.assertThat(lambda: argument.parse([]), raises(ValueError))
89
90    def test_parsing_optional_not_matching(self):
91        class AnArgument(arguments.AbstractArgument):
92            def _parse_one(self, arg):
93                raise ValueError('not an argument')
94        argument = AnArgument('foo', min=0)
95        args = ['a', 'b']
96        self.assertThat(argument.parse(args), Equals([]))
97        self.assertThat(args, Equals(['a', 'b']))
98
99
100# No interface tests for now, because the interface we expect is really just
101# _parse_one; however if bugs or issues show up... then we should add them.
102