示例#1
0
class TestTranslateStroke:

    class CaptureOutput:
        output = namedtuple('output', 'undo do prev')

        def __init__(self):
            self.output = []

        def __call__(self, undo, new, prev):
            prev = list(prev) if prev else None
            self.output = type(self).output(undo, new, prev)

    def t(self, strokes):
        """A quick way to make a translation."""
        strokes = [stroke(x) for x in strokes.split('/')]
        key = tuple(s.rtfcre for s in strokes)
        translation = self.dc.lookup(key)
        return Translation(strokes, translation)

    def lt(self, translations):
        """A quick way to make a list of translations."""
        return [self.t(x) for x in translations.split()]

    def define(self, key, value):
        key = normalize_steno(key)
        self.d[key] = value

    def translate(self, steno):
        self.tlor.translate(stroke(steno))

    def _check_translations(self, expected):
        # Hide from traceback on assertions (reduce output size for failed tests).
        __tracebackhide__ = operator.methodcaller('errisinstance', AssertionError)
        msg = '''
        translations:
            results: %s
            expected: %s
        ''' % (self.s.translations, expected)
        assert self.s.translations == expected, msg

    def _check_output(self, undo, do, prev):
        # Hide from traceback on assertions (reduce output size for failed tests).
        __tracebackhide__ = operator.methodcaller('errisinstance', AssertionError)
        msg = '''
        output:
            results: -%s
                     +%s
                     [%s]
            expected: -%s
                      +%s
                      [%s]
        ''' % (self.o.output + (undo, do, prev))
        assert self.o.output == (undo, do, prev), msg

    def setup_method(self):
        self.d = StenoDictionary()
        self.dc = StenoDictionaryCollection([self.d])
        self.s = _State()
        self.o = self.CaptureOutput()
        self.tlor = Translator()
        self.tlor.set_dictionary(self.dc)
        self.tlor.add_listener(self.o)
        self.tlor.set_state(self.s)

    def test_first_stroke(self):
        self.translate('-B')
        self._check_translations(self.lt('-B'))
        self._check_output([], self.lt('-B'), None)

    def test_second_stroke(self):
        self.define('S/P', 'spiders')
        self.s.translations = self.lt('S')
        self.translate('-T')
        self._check_translations(self.lt('S -T'))
        self._check_output([], self.lt('-T'), self.lt('S'))

    def test_second_stroke_tail(self):
        self.s.tail = self.t('T/A/EU/L')
        self.translate('-E')
        self._check_translations(self.lt('E'))
        self._check_output([], self.lt('E'), self.lt('T/A/EU/L'))

    def test_with_translation_1(self):
        self.define('S', 'is')
        self.define('-T', 'that')
        self.s.translations = self.lt('S')
        self.tlor.set_min_undo_length(2)
        self.translate('-T')
        self._check_translations(self.lt('S -T'))
        self._check_output([], self.lt('-T'), self.lt('S'))
        assert self.o.output.do[0].english == 'that'

    def test_with_translation_2(self):
        self.define('S', 'is')
        self.define('-T', 'that')
        self.s.translations = self.lt('S')
        self.tlor.set_min_undo_length(1)
        self.translate('-T')
        self._check_translations(self.lt('-T'))
        self._check_output([], self.lt('-T'), self.lt('S'))
        assert self.o.output.do[0].english == 'that'

    def test_finish_two_translation(self):
        self.define('S/T', 'hello')
        self.s.translations = self.lt('S')
        self.translate('T')
        self._check_translations(self.lt('S/T'))
        self._check_output(self.lt('S'), self.lt('S/T'), None)
        assert self.o.output.do[0].english == 'hello'
        assert self.o.output.do[0].replaced == self.lt('S')

    def test_finish_three_translation(self):
        self.define('S/T/-B', 'bye')
        self.s.translations = self.lt('S T')
        self.translate('-B')
        self._check_translations(self.lt('S/T/-B'))
        self._check_output(self.lt('S T'), self.lt('S/T/-B'), None)
        assert self.o.output.do[0].english == 'bye'
        assert self.o.output.do[0].replaced == self.lt('S T')

    def test_replace_translation(self):
        self.define('S/T/-B', 'longer')
        self.s.translations = self.lt('S/T')
        self.translate('-B')
        self._check_translations(self.lt('S/T/-B'))
        self._check_output(self.lt('S/T'), self.lt('S/T/-B'), None)
        assert self.o.output.do[0].english == 'longer'
        assert self.o.output.do[0].replaced == self.lt('S/T')

    def test_undo(self):
        self.s.translations = self.lt('POP')
        self.translate('*')
        self._check_translations([])
        self._check_output(self.lt('POP'), [], None)

    def test_empty_undo(self):
        self.translate('*')
        self._check_translations([])
        self._check_output([], [Translation([Stroke('*')], BACK_STRING)], None)

    def test_undo_translation(self):
        self.define('P/P', 'pop')
        self.translate('P')
        self.translate('P')
        self.translate('*')
        self._check_translations(self.lt('P'))
        self._check_output(self.lt('P/P'), self.lt('P'), None)

    def test_undo_longer_translation(self):
        self.define('P/P/-D', 'popped')
        self.translate('P')
        self.translate('P')
        self.translate('-D')
        self.translate('*')
        self._check_translations(self.lt('P P'))
        self._check_output(self.lt('P/P/-D'), self.lt('P P'), None)

    def test_undo_tail(self):
        self.s.tail = self.t('T/A/EU/L')
        self.translate('*')
        self._check_translations([])
        self._check_output([], [Translation([Stroke('*')], BACK_STRING)], [self.s.tail])

    def test_suffix_folding(self):
        self.define('K-L', 'look')
        self.define('-G', '{^ing}')
        lt = self.lt('K-LG')
        lt[0].english = 'look {^ing}'
        self.translate('K-LG')
        self._check_translations(lt)

    def test_suffix_folding_multi_stroke(self):
        self.define('E/HR', 'he will')
        self.define('-S', '{^s}')
        self.translate('E')
        self.translate('HR-S')
        output = ' '.join(t.english for t in self.s.translations)
        assert output == 'he will {^s}'

    def test_suffix_folding_doesnt_interfere(self):
        self.define('E/HR', 'he will')
        self.define('-S', '{^s}')
        self.define('E', 'he')
        self.define('HR-S', 'also')
        self.translate('E')
        self.translate('HR-S')
        output = ' '.join(t.english for t in self.s.translations)
        assert output == 'he also'

    def test_suffix_folding_no_suffix(self):
        self.define('K-L', 'look')
        lt = self.lt('K-LG')
        assert lt[0].english is None
        self.translate('K-LG')
        self._check_translations(lt)

    def test_suffix_folding_no_main(self):
        self.define('-G', '{^ing}')
        lt = self.lt('K-LG')
        assert lt[0].english is None
        self.translate('K-LG')
        self._check_translations(lt)

    def test_retrospective_insert_space(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('PER', 'perfect')
        self.define('SWAEUGS', 'situation')
        self.define('PER/SWAEUGS', 'persuasion')
        self.define('SP*', '{*?}')
        self.translate('PER')
        self.translate('SWAEUGS')
        self.translate('SP*')
        lt = self.lt('PER')
        undo = self.lt('PER/SWAEUGS')
        undo[0].replaced = lt
        do = self.lt('SP*')
        do[0].english = 'perfect situation'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_insert_space_undefined(self):
        # Should work when beginning or ending strokes aren't defined
        self.define('T/E/S/T', 'a longer key')
        self.define('STWR/STWR', 'test')
        self.define('SP*', '{*?}')
        self.translate('STWR')
        self.translate('STWR')
        self.translate('SP*')
        lt = self.lt('STWR')
        undo = self.lt('STWR/STWR')
        undo[0].replaced = lt
        do = self.lt('SP*')
        do[0].english = 'STWR STWR'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_delete_space(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('K', 'kick')
        self.define('PW', 'back')
        self.define('SP*', '{*!}')
        self.translate('K')
        self.translate('PW')
        self.translate('SP*')
        undo = self.lt('K PW')
        do = self.lt('SP*')
        do[0].english = 'kick{^~|^}back'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_delete_space_with_number(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('U', 'user')
        self.define('SP*', '{*!}')
        self.translate('U')
        self.translate('1-')
        self.translate('SP*')
        undo = self.lt('U 1-')
        do = self.lt('SP*')
        do[0].english = 'user{^~|^}{&1}'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_delete_space_with_period(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('P-P', '{.}')
        self.define('SH*', 'zshrc')
        self.define('SP*', '{*!}')
        self.translate('P-P')
        self.translate('SH*')
        self.translate('SP*')
        undo = self.lt('P-P SH*')
        do = self.lt('SP*')
        do[0].english = '{.}{^~|^}zshrc'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_toggle_asterisk(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('S', 'see')
        self.define('S*', 'sea')
        self.define('A*', '{*}')
        self.translate('S')
        self.translate('A*')
        self._check_translations(self.lt('S*'))
        self._check_output(self.lt('S'), self.lt('S*'), None)

    def test_retrospective_toggle_empty(self):
        self.define('A*', '{*}')
        self.translate('A*')
        self._check_translations(self.lt(''))
        assert self.o.output == []

    def test_retrospective_toggle_asterisk_replaced1(self):
        self.define('P-P', '{.}')
        self.define('SKEL', 'cancel')
        self.define('SKEL/TO-PB', 'skeleton')
        self.define('SKEL/TO*PB', 'not skeleton!')
        self.define('A*', '{*}')
        self.translate('P-P')
        self.translate('SKEL')
        self.translate('TO-PB')
        self.translate('A*')
        self._check_translations(self.lt('SKEL/TO*PB'))
        self._check_output(self.lt('SKEL/TO-PB'),
                          self.lt('SKEL/TO*PB'),
                          self.lt('P-P'))

    def test_retrospective_toggle_asterisk_replaced2(self):
        self.define('P-P', '{.}')
        self.define('SKEL', 'cancel')
        self.define('SKEL/TO-PB', 'skeleton')
        self.define('TO*PB', '{^ton}')
        self.define('A*', '{*}')
        self.translate('P-P')
        self.translate('SKEL')
        self.translate('TO-PB')
        self.translate('A*')
        self._check_translations(self.lt('SKEL TO*PB'))
        self._check_output(self.lt('SKEL/TO-PB'),
                          self.lt('SKEL TO*PB'),
                          self.lt('P-P'))

    def test_repeat_last_stroke1(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('TH', 'this')
        self.define('R*', '{*+}')
        self.translate('TH')
        self.translate('R*')
        undo = []
        do = self.lt('TH')
        state = self.lt('TH TH')
        self._check_translations(state)
        self._check_output(undo, do, do)

    def test_repeat_last_stroke2(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('THA', 'that')
        self.define('R*', '{*+}')
        self.translate('THA')
        self.translate('R*')
        undo = []
        do = self.lt('THA')
        state = self.lt('THA THA')
        self._check_translations(state)
        self._check_output(undo, do, do)

    def test_untranslate_translation(self):
        self.tlor.set_min_undo_length(2)
        self.define('TH', 'this')
        self.define('THA', 'that')
        self.translate('TH')
        self.translate('THA')
        self.tlor.untranslate_translation(self.t('THA'))
        self.tlor.untranslate_translation(self.t('TH'))
        self.tlor.flush()
        self._check_output(self.lt('TH THA'), [], None)
示例#2
0
class TestTranslateStroke:
    class CaptureOutput:
        output = namedtuple('output', 'undo do prev')

        def __init__(self):
            self.output = []

        def __call__(self, undo, new, prev):
            prev = list(prev) if prev else None
            self.output = type(self).output(undo, new, prev)

    def t(self, strokes):
        """A quick way to make a translation."""
        strokes = [stroke(x) for x in strokes.split('/')]
        key = tuple(s.rtfcre for s in strokes)
        translation = self.dc.lookup(key)
        return Translation(strokes, translation)

    def lt(self, translations):
        """A quick way to make a list of translations."""
        return [self.t(x) for x in translations.split()]

    def define(self, key, value):
        key = normalize_steno(key)
        self.d[key] = value

    def translate(self, steno):
        self.tlor.translate(stroke(steno))

    def _check_translations(self, expected):
        # Hide from traceback on assertions (reduce output size for failed tests).
        __tracebackhide__ = operator.methodcaller('errisinstance',
                                                  AssertionError)
        msg = '''
        translations:
            results: %s
            expected: %s
        ''' % (self.s.translations, expected)
        assert self.s.translations == expected, msg

    def _check_output(self, undo, do, prev):
        # Hide from traceback on assertions (reduce output size for failed tests).
        __tracebackhide__ = operator.methodcaller('errisinstance',
                                                  AssertionError)
        msg = '''
        output:
            results: -%s
                     +%s
                     [%s]
            expected: -%s
                      +%s
                      [%s]
        ''' % (self.o.output + (undo, do, prev))
        assert self.o.output == (undo, do, prev), msg

    def setup_method(self):
        self.d = StenoDictionary()
        self.dc = StenoDictionaryCollection([self.d])
        self.s = _State()
        self.o = self.CaptureOutput()
        self.tlor = Translator()
        self.tlor.set_dictionary(self.dc)
        self.tlor.add_listener(self.o)
        self.tlor.set_state(self.s)

    def test_first_stroke(self):
        self.translate('-B')
        self._check_translations(self.lt('-B'))
        self._check_output([], self.lt('-B'), None)

    def test_second_stroke(self):
        self.define('S/P', 'spiders')
        self.s.translations = self.lt('S')
        self.translate('-T')
        self._check_translations(self.lt('S -T'))
        self._check_output([], self.lt('-T'), self.lt('S'))

    def test_second_stroke_tail(self):
        self.s.tail = self.t('T/A/EU/L')
        self.translate('-E')
        self._check_translations(self.lt('E'))
        self._check_output([], self.lt('E'), self.lt('T/A/EU/L'))

    def test_with_translation_1(self):
        self.define('S', 'is')
        self.define('-T', 'that')
        self.s.translations = self.lt('S')
        self.tlor.set_min_undo_length(2)
        self.translate('-T')
        self._check_translations(self.lt('S -T'))
        self._check_output([], self.lt('-T'), self.lt('S'))
        assert self.o.output.do[0].english == 'that'

    def test_with_translation_2(self):
        self.define('S', 'is')
        self.define('-T', 'that')
        self.s.translations = self.lt('S')
        self.tlor.set_min_undo_length(1)
        self.translate('-T')
        self._check_translations(self.lt('-T'))
        self._check_output([], self.lt('-T'), self.lt('S'))
        assert self.o.output.do[0].english == 'that'

    def test_finish_two_translation(self):
        self.define('S/T', 'hello')
        self.s.translations = self.lt('S')
        self.translate('T')
        self._check_translations(self.lt('S/T'))
        self._check_output(self.lt('S'), self.lt('S/T'), None)
        assert self.o.output.do[0].english == 'hello'
        assert self.o.output.do[0].replaced == self.lt('S')

    def test_finish_three_translation(self):
        self.define('S/T/-B', 'bye')
        self.s.translations = self.lt('S T')
        self.translate('-B')
        self._check_translations(self.lt('S/T/-B'))
        self._check_output(self.lt('S T'), self.lt('S/T/-B'), None)
        assert self.o.output.do[0].english == 'bye'
        assert self.o.output.do[0].replaced == self.lt('S T')

    def test_replace_translation(self):
        self.define('S/T/-B', 'longer')
        self.s.translations = self.lt('S/T')
        self.translate('-B')
        self._check_translations(self.lt('S/T/-B'))
        self._check_output(self.lt('S/T'), self.lt('S/T/-B'), None)
        assert self.o.output.do[0].english == 'longer'
        assert self.o.output.do[0].replaced == self.lt('S/T')

    def test_undo(self):
        self.s.translations = self.lt('POP')
        self.translate('*')
        self._check_translations([])
        self._check_output(self.lt('POP'), [], None)

    def test_empty_undo(self):
        self.translate('*')
        self._check_translations([])
        self._check_output([], [Translation([Stroke('*')], BACK_STRING)], None)

    def test_undo_translation(self):
        self.define('P/P', 'pop')
        self.translate('P')
        self.translate('P')
        self.translate('*')
        self._check_translations(self.lt('P'))
        self._check_output(self.lt('P/P'), self.lt('P'), None)

    def test_undo_longer_translation(self):
        self.define('P/P/-D', 'popped')
        self.translate('P')
        self.translate('P')
        self.translate('-D')
        self.translate('*')
        self._check_translations(self.lt('P P'))
        self._check_output(self.lt('P/P/-D'), self.lt('P P'), None)

    def test_undo_tail(self):
        self.s.tail = self.t('T/A/EU/L')
        self.translate('*')
        self._check_translations([])
        self._check_output([], [Translation([Stroke('*')], BACK_STRING)],
                           [self.s.tail])

    def test_suffix_folding(self):
        self.define('K-L', 'look')
        self.define('-G', '{^ing}')
        lt = self.lt('K-LG')
        lt[0].english = 'look {^ing}'
        self.translate('K-LG')
        self._check_translations(lt)

    def test_suffix_folding_multi_stroke(self):
        self.define('E/HR', 'he will')
        self.define('-S', '{^s}')
        self.translate('E')
        self.translate('HR-S')
        output = ' '.join(t.english for t in self.s.translations)
        assert output == 'he will {^s}'

    def test_suffix_folding_doesnt_interfere(self):
        self.define('E/HR', 'he will')
        self.define('-S', '{^s}')
        self.define('E', 'he')
        self.define('HR-S', 'also')
        self.translate('E')
        self.translate('HR-S')
        output = ' '.join(t.english for t in self.s.translations)
        assert output == 'he also'

    def test_suffix_folding_no_suffix(self):
        self.define('K-L', 'look')
        lt = self.lt('K-LG')
        assert lt[0].english is None
        self.translate('K-LG')
        self._check_translations(lt)

    def test_suffix_folding_no_main(self):
        self.define('-G', '{^ing}')
        lt = self.lt('K-LG')
        assert lt[0].english is None
        self.translate('K-LG')
        self._check_translations(lt)

    def test_retrospective_insert_space(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('PER', 'perfect')
        self.define('SWAEUGS', 'situation')
        self.define('PER/SWAEUGS', 'persuasion')
        self.define('SP*', '{*?}')
        self.translate('PER')
        self.translate('SWAEUGS')
        self.translate('SP*')
        lt = self.lt('PER')
        undo = self.lt('PER/SWAEUGS')
        undo[0].replaced = lt
        do = self.lt('SP*')
        do[0].english = 'perfect situation'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_insert_space_undefined(self):
        # Should work when beginning or ending strokes aren't defined
        self.define('T/E/S/T', 'a longer key')
        self.define('STWR/STWR', 'test')
        self.define('SP*', '{*?}')
        self.translate('STWR')
        self.translate('STWR')
        self.translate('SP*')
        lt = self.lt('STWR')
        undo = self.lt('STWR/STWR')
        undo[0].replaced = lt
        do = self.lt('SP*')
        do[0].english = 'STWR STWR'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_delete_space(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('K', 'kick')
        self.define('PW', 'back')
        self.define('SP*', '{*!}')
        self.translate('K')
        self.translate('PW')
        self.translate('SP*')
        undo = self.lt('K PW')
        do = self.lt('SP*')
        do[0].english = 'kick{^~|^}back'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_delete_space_with_number(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('U', 'user')
        self.define('SP*', '{*!}')
        self.translate('U')
        self.translate('1-')
        self.translate('SP*')
        undo = self.lt('U 1-')
        do = self.lt('SP*')
        do[0].english = 'user{^~|^}{&1}'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_delete_space_with_period(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('P-P', '{.}')
        self.define('SH*', 'zshrc')
        self.define('SP*', '{*!}')
        self.translate('P-P')
        self.translate('SH*')
        self.translate('SP*')
        undo = self.lt('P-P SH*')
        do = self.lt('SP*')
        do[0].english = '{.}{^~|^}zshrc'
        do[0].is_retrospective_command = True
        do[0].replaced = undo
        self._check_translations(do)
        self._check_output(undo, do, None)

    def test_retrospective_toggle_asterisk(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('S', 'see')
        self.define('S*', 'sea')
        self.define('A*', '{*}')
        self.translate('S')
        self.translate('A*')
        self._check_translations(self.lt('S*'))
        self._check_output(self.lt('S'), self.lt('S*'), None)

    def test_retrospective_toggle_empty(self):
        self.define('A*', '{*}')
        self.translate('A*')
        self._check_translations(self.lt(''))
        assert self.o.output == []

    def test_retrospective_toggle_asterisk_replaced1(self):
        self.define('P-P', '{.}')
        self.define('SKEL', 'cancel')
        self.define('SKEL/TO-PB', 'skeleton')
        self.define('SKEL/TO*PB', 'not skeleton!')
        self.define('A*', '{*}')
        self.translate('P-P')
        self.translate('SKEL')
        self.translate('TO-PB')
        self.translate('A*')
        self._check_translations(self.lt('SKEL/TO*PB'))
        self._check_output(self.lt('SKEL/TO-PB'), self.lt('SKEL/TO*PB'),
                           self.lt('P-P'))

    def test_retrospective_toggle_asterisk_replaced2(self):
        self.define('P-P', '{.}')
        self.define('SKEL', 'cancel')
        self.define('SKEL/TO-PB', 'skeleton')
        self.define('TO*PB', '{^ton}')
        self.define('A*', '{*}')
        self.translate('P-P')
        self.translate('SKEL')
        self.translate('TO-PB')
        self.translate('A*')
        self._check_translations(self.lt('SKEL TO*PB'))
        self._check_output(self.lt('SKEL/TO-PB'), self.lt('SKEL TO*PB'),
                           self.lt('P-P'))

    def test_repeat_last_stroke1(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('TH', 'this')
        self.define('R*', '{*+}')
        self.translate('TH')
        self.translate('R*')
        undo = []
        do = self.lt('TH')
        state = self.lt('TH TH')
        self._check_translations(state)
        self._check_output(undo, do, do)

    def test_repeat_last_stroke2(self):
        self.define('T/E/S/T', 'a longer key')
        self.define('THA', 'that')
        self.define('R*', '{*+}')
        self.translate('THA')
        self.translate('R*')
        undo = []
        do = self.lt('THA')
        state = self.lt('THA THA')
        self._check_translations(state)
        self._check_output(undo, do, do)

    def test_untranslate_translation(self):
        self.tlor.set_min_undo_length(2)
        self.define('TH', 'this')
        self.define('THA', 'that')
        self.translate('TH')
        self.translate('THA')
        self.tlor.untranslate_translation(self.t('THA'))
        self.tlor.untranslate_translation(self.t('TH'))
        self.tlor.flush()
        self._check_output(self.lt('TH THA'), [], None)