Source for: test_justify_row.py [raw]

  1import pytest
  2
  3import boxes
  4
  5
  6def test_justify_simple():
  7    """Test a simple use case."""
  8    # First setup what we will use, our "test case"
  9    separation = .1
 10    row = [
 11        boxes.Box(x=i + i * separation, w=1, h=1, letter="a")
 12        for i in range(10)
 13    ]
 14    page = boxes.Box(w=50, h=50)
 15
 16    # Check expected characteristics
 17    assert len(row) == 10
 18    assert row[-1].x + row[-1].w == 10.9
 19
 20    # Do the thing
 21    boxes.justify_row(row, page, separation)
 22
 23    # Check the expected behavior
 24
 25    # Should have the same number of elements
 26    assert len(row) == 10
 27    # The first element should be flushed-left
 28    assert row[0].x == page.x
 29    # The last element should be flushed-right
 30    # Use approx because of floating point error
 31    assert pytest.approx(row[-1].x + row[-1].w) == page.x + page.w
 32
 33
 34def test_justify_with_spaces():
 35    """Test a simple use case with spaces."""
 36    separation = .1
 37    row = [
 38        boxes.Box(x=i + i * separation, w=1, h=1, letter="a")
 39        for i in range(10)
 40    ]
 41    row[5].letter = " "
 42    row[5].stretchy = True
 43    page = boxes.Box(w=50, h=50)
 44
 45    assert len(row) == 10
 46    assert row[-1].x + row[-1].w == 10.9
 47
 48    boxes.justify_row(row, page, separation)
 49
 50    # Should have the same number of elements
 51    assert len(row) == 10
 52    # The first element should be flushed-left
 53    assert row[0].x == page.x
 54    # The last element should be flushed-right
 55    # Use approx() because floating point adds a tiny error here
 56    assert pytest.approx(row[-1].x + row[-1].w) == page.x + page.w
 57    # The element in position 5 must have absorbed all the slack
 58    # So is 1 (it's width) + 30.1 (slack) units wide
 59    assert row[5].w == 40.1
 60
 61
 62def test_justify_ends_with_newline():
 63    """Test a use case with a newline."""
 64    separation = .1
 65    row = [
 66        boxes.Box(x=i + i * separation, w=1, h=1, letter="a")
 67        for i in range(10)
 68    ]
 69    row[-1].letter = "\n"
 70    page = boxes.Box(w=50, h=50)
 71
 72    assert len(row) == 10
 73    assert row[-1].x + row[-1].w == 10.9
 74
 75    boxes.justify_row(row, page, separation)
 76
 77    # Should have the same number of elements
 78    assert len(row) == 10
 79    # The first element should be flushed-left
 80    assert row[0].x == page.x
 81    # The last element should NOT be flushed-right
 82    assert row[-1].x + row[-1].w == 10.9
 83
 84
 85def test_justify_trailing_spaces():
 86    """Test a use case with traling spaces."""
 87    separation = .1
 88    row = [
 89        boxes.Box(x=i + i * separation, w=1, h=1, letter="a")
 90        for i in range(10)
 91    ]
 92    row[-1].letter = " "
 93    row[-2].letter = " "
 94    page = boxes.Box(w=50, h=50)
 95
 96    assert len(row) == 10
 97    assert row[-1].x + row[-1].w == 10.9
 98
 99    boxes.justify_row(row, page, separation)
100
101    # Should have lost the 2 trailing spaces
102    assert len(row) == 8
103    # The first element should be flushed-left
104    assert row[0].x == page.x
105    # The last element should be flushed-right
106    # Use approx because of floating point error
107    assert pytest.approx(row[-1].x + row[-1].w) == page.x + page.w
108
109
110def test_justify_puts_things_in_a_row():
111    """Test a simple use case with spaces."""
112    separation = .1
113    row = [
114        boxes.Box(x=i + i * separation, w=1, h=1, letter="a")
115        for i in range(10)
116    ]
117    row[5].letter = " "
118    row[5].stretchy = True
119    page = boxes.Box(w=50, h=50)
120
121    assert len(row) == 10
122    assert row[-1].x + row[-1].w == 10.9
123
124    boxes.justify_row(row, page, separation)
125
126    # Should have the same number of elements
127    assert len(row) == 10
128    # The first element should be flushed-left
129    assert row[0].x == page.x
130    # The last element should be flushed-right
131    # Use approx() because floating point adds a tiny error here
132    assert pytest.approx(row[-1].x + row[-1].w) == page.x + page.w
133    # All elements should be separated correctly.
134    separations = [
135        separation - (row[i].x - (row[i - 1].x + row[i - 1].w))
136        for i in range(1, len(row))
137    ]
138    # Again, floating point is inaccurate
139    assert max(separations) < 0.00001
140    assert min(separations) > -0.00001
141
142
143def test_adds_hyphen():
144    """jusify_row is suppose to turn soft-hyphens at the end of rows into
145    real hyphens."""
146    separation = .1
147    row = [
148        boxes.Box(x=i + i * separation, w=1, h=1, letter="\xad")
149        for i in range(10)
150    ]
151    page = boxes.Box(w=50, h=50)
152
153    assert row[-1].letter == "\xad"
154
155    boxes.justify_row(row, page, separation)
156
157    hy = boxes.hyphenbox()
158    assert row[-1].letter == hy.letter
159
160
161def test_justify_overfull(tmpdir):
162    """If a line is overfull, it still should be justified."""
163
164    separation = 0.05
165    page = boxes.Box(0, 0, 30, 50)
166    # Our failing text
167    inp = tmpdir.mkdir("sub").join("hello.txt")
168    inp.write(
169        "take delight in vexing me. You have no compassion for my poor nerves.\”"
170    )
171    # Adjust widths:
172    row = boxes.create_text_boxes(inp)
173    # Put side by side
174    boxes.fill_row(row[:], page, separation)
175
176    # Should be overwide
177    assert row[-1].x > page.w
178
179    boxes.justify_row(row, page, separation)
180
181    # Should now be justified
182    assert row[-1].x + row[-1].w == pytest.approx(page.w)
183