Commit 3f68e9fb authored by Simon Will's avatar Simon Will
Browse files

Fix Position.after_mora classmethod and add tests

parent dea04d9f
Loading
Loading
Loading
Loading
+32 −7
Original line number Diff line number Diff line
@@ -448,30 +448,48 @@ class Verse:
class Position:

    def __init__(self, reading: Reading, mora: int, word_boundary: bool,
                 token: Token, syllable: Syllable,
                 token: Token, syllable: Syllable, punctuation: str = None,
                 meter: '.meters.Meter' = None, element: int = None):
        self.reading = reading
        self.mora = mora
        self.word_boundary = word_boundary
        self.token = token
        self.syllable = syllable
        self.punctuation = punctuation
        self.meter = meter
        self.element = element

    @classmethod
    def after_mora(cls, reading: Reading, mora: int) -> 'Position':
        morae = 0
        position = None
        punctuation = ''
        for token in reading.tokens:
            if token.is_punct():
                punctuation += token.text
            for i, syllable in enumerate(token.syllables):
                word_boundary = i == 0
                if morae == mora:
                if morae == mora and syllable.syllable_length > 0:
                    position = cls(
                        reading=reading, mora=mora, token=token,
                        syllable=syllable, word_boundary=word_boundary,
                        meter=meter
                        punctuation=punctuation
                    )
                    return position
                else:
                    morae += syllable.syllable_length
                    punctuation = ''
        else:
            # The position has not been found. There are two possibilities:
            if morae == mora:
                # The position is at the end of the sentence.
                position = cls(
                    reading=reading, mora=mora, token=None, syllable=None,
                    word_boundary=True, punctuation=punctuation
                )
                return position
            else:
                # There is no syllable boundary at the given mora.
                return None

    @classmethod
    def after_element(cls, reading: Reading, meter: '.meters.Meter',
@@ -483,11 +501,18 @@ class Position:
    def after(cls, type: str, reading: Reading, position_number: int,
             meter: '.meters.Meter') -> 'Position':
        if type == 'mora':
            return cls.after_mora(*args, reading, position_number)
            return cls.after_mora(reading, position_number)
        elif type == 'element':
            return cls.after_element(*args, reading, meter, position_number)
            return cls.after_element(reading, meter, position_number)
        else:
            raise ValueError(
                'The after type has to be "mora" or "element", but is {!r}'
                .format(spec)
            )

    def __repr__(self):
        return 'Position(' + ', '.join(
            '{key}={val!r}'.format(key=attr, val=getattr(self, attr))
            for attr in ['reading', 'mora', 'word_boundary', 'token', 'syllable',
                         'punctuation', 'meter', 'element']
        ) + ')'
+178 −3
Original line number Diff line number Diff line
@@ -3,18 +3,30 @@
import os.path
import json

import pytest

import allzweckmesser as azm

Position = azm.model.Position

TEST_DIR = os.path.dirname(__file__)


@pytest.fixture()
def verse_models():
    verse_filepath = os.path.join(TEST_DIR, 'verses.json')
    verse_models = azm.model.from_json(verse_filepath)
    return verse_models


def test_import_json():

    verse_filepath = os.path.join(TEST_DIR, 'verses.json')

    verse_models = azm.model.from_json(verse_filepath)

    verse_list_from_model = [verse_model.to_dict() for verse_model in verse_models]
    verse_list_from_model = [verse_model.to_dict()
                             for verse_model in verse_models]

    with open(verse_filepath, 'r') as verse_file:
        verse_list_from_json = json.loads(verse_file.read())
@@ -25,8 +37,171 @@ def test_import_json():
        parsed_verses = azm.scanner.parse_verse(verse)

    for verse_model in parsed_verses:
        #print(json.dumps(json.loads(verse_model.to_json()), indent=4, sort_keys=True))
        #print(json.dumps(json.loads(verse_model.to_json()), indent=4,
        #                 sort_keys=True))
        pass


def test_position_after_mora(verse_models):
    hex_reading = verse_models[3].readings[0]
    begin = Position.after_mora(hex_reading, 0)
    assert isinstance(begin, Position)
    assert begin.mora == 0
    assert begin.word_boundary
    assert begin.token.text == 'an'
    assert begin.syllable.text == 'an'
    assert begin.punctuation == ''

    assert Position.after_mora(hex_reading, 1) is None

    after2 = Position.after_mora(hex_reading, 2)
    assert isinstance(after2, Position)
    assert after2.mora == 2
    assert after2.word_boundary
    assert after2.token.text == 'quod'
    assert after2.syllable.text == 'quod'
    assert after2.punctuation == ','

    after3 = Position.after_mora(hex_reading, 3)
    assert isinstance(after3, Position)
    assert after3.mora == 3
    assert after3.word_boundary
    assert after3.token.text == 'ubique'
    assert after3.syllable.text == 'u'
    assert after3.punctuation == ''

    after4 = Position.after_mora(hex_reading, 4)
    assert isinstance(after4, Position)
    assert after4.mora == 4
    assert not after4.word_boundary
    assert after4.token.text == 'ubique'
    assert after4.syllable.text == 'bi'
    assert after4.punctuation == ''

    assert Position.after_mora(hex_reading, 5) is None

    after6 = Position.after_mora(hex_reading, 6)
    assert isinstance(after6, Position)
    assert after6.mora == 6
    assert not after6.word_boundary
    assert after6.token.text == 'ubique'
    assert after6.syllable.text == 'que'
    assert after6.punctuation == ''

    after7 = Position.after_mora(hex_reading, 7)
    assert isinstance(after7, Position)
    assert after7.mora == 7
    assert after7.word_boundary
    assert after7.token.text == 'tuum'
    assert after7.syllable.text == 'tu'
    assert after7.punctuation == ','

    after8 = Position.after_mora(hex_reading, 8)
    assert isinstance(after8, Position)
    assert after8.mora == 8
    assert not after8.word_boundary
    assert after8.token.text == 'tuum'
    assert after8.syllable.text == 'um'
    assert after8.punctuation == ''

    assert Position.after_mora(hex_reading, 9) is None

    after10 = Position.after_mora(hex_reading, 10)
    assert isinstance(after10, Position)
    assert after10.mora == 10
    assert after10.word_boundary
    assert after10.token.text == 'tua'
    assert after10.syllable.text == 'tu'
    assert after10.punctuation == '?'

    after11 = Position.after_mora(hex_reading, 11)
    assert isinstance(after11, Position)
    assert after11.mora == 11
    assert not after11.word_boundary
    assert after11.token.text == 'tua'
    assert after11.syllable.text == 'a'
    assert after11.punctuation == ''

    after12 = Position.after_mora(hex_reading, 12)
    assert isinstance(after12, Position)
    assert after12.mora == 12
    assert after12.word_boundary
    assert after12.token.text == 'sunt'
    assert after12.syllable.text == 'sunt'
    assert after12.punctuation == ''

    assert Position.after_mora(hex_reading, 13) is None

    after14 = Position.after_mora(hex_reading, 14)
    assert isinstance(after14, Position)
    assert after14.mora == 14
    assert after14.word_boundary
    assert after14.token.text == 'Heliconia'
    assert after14.syllable.text == 'He'
    assert after14.punctuation == ''

    after15 = Position.after_mora(hex_reading, 15)
    assert isinstance(after15, Position)
    assert after15.mora == 15
    assert not after15.word_boundary
    assert after15.token.text == 'Heliconia'
    assert after15.syllable.text == 'li'
    assert after15.punctuation == ''

    after16 = Position.after_mora(hex_reading, 16)
    assert isinstance(after16, Position)
    assert after16.mora == 16
    assert not after16.word_boundary
    assert after16.token.text == 'Heliconia'
    assert after16.syllable.text == 'co'
    assert after16.punctuation == ''

    assert Position.after_mora(hex_reading, 17) is None

    after18 = Position.after_mora(hex_reading, 18)
    assert isinstance(after18, Position)
    assert after18.mora == 18
    assert not after18.word_boundary
    assert after18.token.text == 'Heliconia'
    assert after18.syllable.text == 'ni'
    assert after18.punctuation == ''

    after19 = Position.after_mora(hex_reading, 19)
    assert isinstance(after19, Position)
    assert after19.mora == 19
    assert not after19.word_boundary
    assert after19.token.text == 'Heliconia'
    assert after19.syllable.text == 'a'
    assert after19.punctuation == ''

    after20 = Position.after_mora(hex_reading, 20)
    assert isinstance(after20, Position)
    assert after20.mora == 20
    assert after20.word_boundary
    assert after20.token.text == 'Tempe'
    assert after20.syllable.text == 'Tem'
    assert after20.punctuation == ''

    assert Position.after_mora(hex_reading, 21) is None

    after22 = Position.after_mora(hex_reading, 22)
    assert isinstance(after22, Position)
    assert after22.mora == 22
    assert not after22.word_boundary
    assert after22.token.text == 'Tempe'
    assert after22.syllable.text == 'pe'
    assert after22.punctuation == ''

    assert Position.after_mora(hex_reading, 23) is None

    after24 = Position.after_mora(hex_reading, 24)
    assert isinstance(after24, Position)
    assert after24.mora == 24
    assert after24.word_boundary
    assert after24.token is None
    assert after24.syllable is None
    assert after24.punctuation == '?'


if __name__ == "__main__":
    test_import_json()