Skip to content

Commit 237b6e0

Browse files
committed
Add unit test
Refactor constructors Redefine equals and hashCode in TextChunk and TextElement
1 parent cd769f1 commit 237b6e0

3 files changed

Lines changed: 264 additions & 8 deletions

File tree

src/main/java/technology/tabula/TextChunk.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,35 @@ public List<TextChunk> squeeze(Character c, int minRunLength) {
155155

156156
}
157157

158-
public static boolean allSameChar(List<TextChunk> textChunks) {
158+
159+
160+
@Override
161+
public int hashCode() {
162+
final int prime = 31;
163+
int result = super.hashCode();
164+
result = prime * result
165+
+ ((textElements == null) ? 0 : textElements.hashCode());
166+
return result;
167+
}
168+
169+
@Override
170+
public boolean equals(Object obj) {
171+
if (this == obj)
172+
return true;
173+
if (!super.equals(obj))
174+
return false;
175+
if (getClass() != obj.getClass())
176+
return false;
177+
TextChunk other = (TextChunk) obj;
178+
if (textElements == null) {
179+
if (other.textElements != null)
180+
return false;
181+
} else if (!textElements.equals(other.textElements))
182+
return false;
183+
return true;
184+
}
185+
186+
public static boolean allSameChar(List<TextChunk> textChunks) {
159187
char first = textChunks.get(0).getText().charAt(0);
160188
for (TextChunk tc: textChunks) {
161189
if (!tc.isSameChar(first)) return false;

src/main/java/technology/tabula/TextElement.java

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,7 @@ public class TextElement extends Rectangle implements HasText {
1616

1717
public TextElement(float y, float x, float width, float height,
1818
PDFont font, float fontSize, String c, float widthOfSpace) {
19-
super();
20-
this.setRect(x, y, width, height);
21-
this.text = c;
22-
this.widthOfSpace = widthOfSpace;
23-
this.fontSize = fontSize;
24-
this.font = font;
19+
this(y, x, width, height, font, fontSize, c, widthOfSpace, 0f);
2520
}
2621

2722
public TextElement(float y, float x, float width, float height,
@@ -63,7 +58,50 @@ public String toString() {
6358
return sb.toString();
6459
}
6560

66-
public static List<TextChunk> mergeWords(List<TextElement> textElements) {
61+
@Override
62+
public int hashCode() {
63+
final int prime = 31;
64+
int result = super.hashCode();
65+
result = prime * result + java.lang.Float.floatToIntBits(dir);
66+
result = prime * result + ((font == null) ? 0 : font.hashCode());
67+
result = prime * result + java.lang.Float.floatToIntBits(fontSize);
68+
result = prime * result + ((text == null) ? 0 : text.hashCode());
69+
result = prime * result + java.lang.Float.floatToIntBits(widthOfSpace);
70+
return result;
71+
}
72+
73+
@Override
74+
public boolean equals(Object obj) {
75+
if (this == obj)
76+
return true;
77+
if (!super.equals(obj))
78+
return false;
79+
if (getClass() != obj.getClass())
80+
return false;
81+
TextElement other = (TextElement) obj;
82+
if (java.lang.Float.floatToIntBits(dir) != java.lang.Float
83+
.floatToIntBits(other.dir))
84+
return false;
85+
if (font == null) {
86+
if (other.font != null)
87+
return false;
88+
} else if (!font.equals(other.font))
89+
return false;
90+
if (java.lang.Float.floatToIntBits(fontSize) != java.lang.Float
91+
.floatToIntBits(other.fontSize))
92+
return false;
93+
if (text == null) {
94+
if (other.text != null)
95+
return false;
96+
} else if (!text.equals(other.text))
97+
return false;
98+
if (java.lang.Float.floatToIntBits(widthOfSpace) != java.lang.Float
99+
.floatToIntBits(other.widthOfSpace))
100+
return false;
101+
return true;
102+
}
103+
104+
public static List<TextChunk> mergeWords(List<TextElement> textElements) {
67105
return mergeWords(textElements, new ArrayList<Ruling>());
68106
}
69107

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package technology.tabula;
2+
3+
import java.io.IOException;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
7+
import org.apache.pdfbox.pdmodel.font.PDType1Font;
8+
import org.junit.Assert;
9+
import org.junit.Test;
10+
11+
public class TestTextElement {
12+
13+
14+
@Test
15+
public void createTextElement() throws IOException {
16+
17+
TextElement textElement = new TextElement(5f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f);
18+
19+
Assert.assertNotNull(textElement);
20+
Assert.assertEquals("A", textElement.getText());
21+
Assert.assertEquals(1f, textElement.getFontSize(), 0);
22+
Assert.assertEquals(15f, textElement.getLeft(), 0);
23+
Assert.assertEquals(5f, textElement.getTop(), 0);
24+
Assert.assertEquals(10f, textElement.getWidth(), 0);
25+
Assert.assertEquals(20f, textElement.getHeight(), 0);
26+
Assert.assertEquals(PDType1Font.HELVETICA, textElement.getFont());
27+
Assert.assertEquals(1f, textElement.getWidthOfSpace(), 0);
28+
Assert.assertEquals(0f, textElement.getDirection(), 0);
29+
30+
31+
}
32+
33+
@Test
34+
public void createTextElementWithDirection() throws IOException {
35+
36+
TextElement textElement = new TextElement(5f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f);
37+
38+
Assert.assertNotNull(textElement);
39+
Assert.assertEquals("A", textElement.getText());
40+
Assert.assertEquals(1f, textElement.getFontSize(), 0);
41+
Assert.assertEquals(15f, textElement.getLeft(), 0);
42+
Assert.assertEquals(5f, textElement.getTop(), 0);
43+
Assert.assertEquals(10f, textElement.getWidth(), 0);
44+
Assert.assertEquals(20f, textElement.getHeight(), 0);
45+
Assert.assertEquals(PDType1Font.HELVETICA, textElement.getFont());
46+
Assert.assertEquals(1f, textElement.getWidthOfSpace(), 0);
47+
Assert.assertEquals(6f, textElement.getDirection(), 0);
48+
49+
50+
}
51+
52+
@Test
53+
public void mergeFourElementsIntoFourWords() {
54+
55+
List<TextElement> elements = new ArrayList<TextElement>();
56+
elements.add(new TextElement(0f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
57+
elements.add(new TextElement(20f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "B", 1f, 6f));
58+
elements.add(new TextElement(40f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "C", 1f, 6f));
59+
elements.add(new TextElement(60f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "D", 1f, 6f));
60+
61+
List<TextChunk> words = TextElement.mergeWords(elements);
62+
63+
List<TextChunk> expectedWords = new ArrayList<TextChunk>();
64+
expectedWords.add(new TextChunk(new TextElement(0f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f)));
65+
expectedWords.add(new TextChunk(new TextElement(20f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "B", 1f, 6f)));
66+
expectedWords.add(new TextChunk(new TextElement(40f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "C", 1f, 6f)));
67+
expectedWords.add(new TextChunk(new TextElement(60f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "D", 1f, 6f)));
68+
69+
Assert.assertEquals(expectedWords, words);
70+
71+
}
72+
73+
@Test
74+
public void mergeFourElementsIntoOneWord() {
75+
76+
List<TextElement> elements = new ArrayList<TextElement>();
77+
elements.add(new TextElement(0f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
78+
elements.add(new TextElement(0f, 25f, 10f, 20f, PDType1Font.HELVETICA, 1f, "B", 1f, 6f));
79+
elements.add(new TextElement(0f, 35f, 10f, 20f, PDType1Font.HELVETICA, 1f, "C", 1f, 6f));
80+
elements.add(new TextElement(0f, 45f, 10f, 20f, PDType1Font.HELVETICA, 1f, "D", 1f, 6f));
81+
82+
List<TextChunk> words = TextElement.mergeWords(elements);
83+
84+
List<TextChunk> expectedWords = new ArrayList<TextChunk>();
85+
TextChunk textChunk = new TextChunk(new TextElement(0f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
86+
textChunk.add(new TextElement(0f, 25f, 10f, 20f, PDType1Font.HELVETICA, 1f, "B", 1f, 6f));
87+
textChunk.add(new TextElement(0f, 35f, 10f, 20f, PDType1Font.HELVETICA, 1f, "C", 1f, 6f));
88+
textChunk.add(new TextElement(0f, 45f, 10f, 20f, PDType1Font.HELVETICA, 1f, "D", 1f, 6f));
89+
expectedWords.add(textChunk);
90+
91+
Assert.assertEquals(expectedWords, words);
92+
93+
}
94+
95+
@Test
96+
public void mergeElementsWithSkippingRules() {
97+
98+
List<TextElement> elements = new ArrayList<TextElement>();
99+
elements.add(new TextElement(0f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
100+
elements.add(new TextElement(0f, 17f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
101+
elements.add(new TextElement(0f, 25f, 10f, 20f, PDType1Font.HELVETICA, 1f, "B", 1f, 6f));
102+
elements.add(new TextElement(0.001f, 25f, 10f, 20f, PDType1Font.HELVETICA, 1f, " ", 1f, 6f));
103+
elements.add(new TextElement(0f, 35f, 10f, 20f, PDType1Font.HELVETICA, 1f, "C", 1f, 6f));
104+
elements.add(new TextElement(0f, 45f, 10f, 20f, PDType1Font.TIMES_ROMAN, 10f, "D", 1f, 6f));
105+
106+
List<TextChunk> words = TextElement.mergeWords(elements);
107+
108+
List<TextChunk> expectedWords = new ArrayList<TextChunk>();
109+
TextChunk textChunk = new TextChunk(new TextElement(0f, 15f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
110+
textChunk.add(new TextElement(0f, 25f, 10f, 20f, PDType1Font.HELVETICA, 1f, "B", 1f, 6f));
111+
textChunk.add(new TextElement(0f, 35f, 10f, 20f, PDType1Font.HELVETICA, 1f, "C", 1f, 6f));
112+
textChunk.add(new TextElement(0f, 45f, 10f, 20f, PDType1Font.TIMES_ROMAN, 10f, "D", 1f, 6f));
113+
expectedWords.add(textChunk);
114+
115+
Assert.assertEquals(expectedWords, words);
116+
117+
}
118+
119+
@Test
120+
public void mergeTenElementsIntoTwoWords() {
121+
122+
List<TextElement> elements = new ArrayList<TextElement>();
123+
elements.add(new TextElement(0f, 0f, 10f, 20f, PDType1Font.HELVETICA, 1f, "H", 1f, 6f));
124+
elements.add(new TextElement(0f, 10f, 10f, 20f, PDType1Font.HELVETICA, 1f, "O", 1f, 6f));
125+
elements.add(new TextElement(0f, 20f, 10f, 20f, PDType1Font.HELVETICA, 1f, "L", 1f, 6f));
126+
elements.add(new TextElement(0f, 30f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
127+
elements.add(new TextElement(0f, 60f, 10f, 20f, PDType1Font.HELVETICA, 1f, "M", 1f, 6f));
128+
elements.add(new TextElement(0f, 70f, 10f, 20f, PDType1Font.HELVETICA, 1f, "U", 1f, 6f));
129+
elements.add(new TextElement(0f, 80f, 10f, 20f, PDType1Font.HELVETICA, 1f, "N", 1f, 6f));
130+
elements.add(new TextElement(0f, 90f, 10f, 20f, PDType1Font.HELVETICA, 1f, "D", 1f, 6f));
131+
elements.add(new TextElement(0f, 100f, 10f, 20f, PDType1Font.HELVETICA, 1f, "O", 1f, 6f));
132+
133+
List<TextChunk> words = TextElement.mergeWords(elements);
134+
135+
List<TextChunk> expectedWords = new ArrayList<TextChunk>();
136+
TextChunk textChunk = new TextChunk(new TextElement(0f, 0f, 10f, 20f, PDType1Font.HELVETICA, 1f, "H", 1f, 6f));
137+
textChunk.add(new TextElement(0f, 10f, 10f, 20f, PDType1Font.HELVETICA, 1f, "O", 1f, 6f));
138+
textChunk.add(new TextElement(0f, 20f, 10f, 20f, PDType1Font.HELVETICA, 1f, "L", 1f, 6f));
139+
textChunk.add(new TextElement(0f, 30f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
140+
textChunk.add(new TextElement(0f, 30f, 10.5f, 20f, PDType1Font.HELVETICA, 1f, " ", 1f)); //Check why width=10.5?
141+
expectedWords.add(textChunk);
142+
TextChunk textChunk2 = new TextChunk(new TextElement(0f, 60f, 10f, 20f, PDType1Font.HELVETICA, 1f, "M", 1f, 6f));
143+
textChunk2.add(new TextElement(0f, 70f, 10f, 20f, PDType1Font.HELVETICA, 1f, "U", 1f, 6f));
144+
textChunk2.add(new TextElement(0f, 80f, 10f, 20f, PDType1Font.HELVETICA, 1f, "N", 1f, 6f));
145+
textChunk2.add(new TextElement(0f, 90f, 10f, 20f, PDType1Font.HELVETICA, 1f, "D", 1f, 6f));
146+
textChunk2.add(new TextElement(0f, 100f, 10f, 20f, PDType1Font.HELVETICA, 1f, "O", 1f, 6f));
147+
expectedWords.add(textChunk2);
148+
149+
Assert.assertEquals(2, words.size());
150+
Assert.assertEquals(expectedWords, words);
151+
152+
}
153+
154+
@Test
155+
public void mergeTenElementsIntoTwoLines() {
156+
157+
List<TextElement> elements = new ArrayList<TextElement>();
158+
elements.add(new TextElement(0f, 0f, 10f, 20f, PDType1Font.HELVETICA, 1f, "H", 1f, 6f));
159+
elements.add(new TextElement(0f, 10f, 10f, 20f, PDType1Font.HELVETICA, 1f, "O", 1f, 6f));
160+
elements.add(new TextElement(0f, 20f, 10f, 20f, PDType1Font.HELVETICA, 1f, "L", 1f, 6f));
161+
elements.add(new TextElement(0f, 30f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
162+
elements.add(new TextElement(20f, 0f, 10f, 20f, PDType1Font.HELVETICA, 1f, "M", 1f, 6f));
163+
elements.add(new TextElement(20f, 10f, 10f, 20f, PDType1Font.HELVETICA, 1f, "U", 1f, 6f));
164+
elements.add(new TextElement(20f, 20f, 10f, 20f, PDType1Font.HELVETICA, 1f, "N", 1f, 6f));
165+
elements.add(new TextElement(20f, 30f, 10f, 20f, PDType1Font.HELVETICA, 1f, "D", 1f, 6f));
166+
elements.add(new TextElement(20f, 40f, 10f, 20f, PDType1Font.HELVETICA, 1f, "O", 1f, 6f));
167+
168+
List<TextChunk> words = TextElement.mergeWords(elements);
169+
170+
List<TextChunk> expectedWords = new ArrayList<TextChunk>();
171+
TextChunk textChunk = new TextChunk(new TextElement(0f, 0f, 10f, 20f, PDType1Font.HELVETICA, 1f, "H", 1f, 6f));
172+
textChunk.add(new TextElement(0f, 10f, 10f, 20f, PDType1Font.HELVETICA, 1f, "O", 1f, 6f));
173+
textChunk.add(new TextElement(0f, 20f, 10f, 20f, PDType1Font.HELVETICA, 1f, "L", 1f, 6f));
174+
textChunk.add(new TextElement(0f, 30f, 10f, 20f, PDType1Font.HELVETICA, 1f, "A", 1f, 6f));
175+
expectedWords.add(textChunk);
176+
TextChunk textChunk2 = new TextChunk(new TextElement(20f, 0f, 10f, 20f, PDType1Font.HELVETICA, 1f, "M", 1f, 6f));
177+
textChunk2.add(new TextElement(20f, 10f, 10f, 20f, PDType1Font.HELVETICA, 1f, "U", 1f, 6f));
178+
textChunk2.add(new TextElement(20f, 20f, 10f, 20f, PDType1Font.HELVETICA, 1f, "N", 1f, 6f));
179+
textChunk2.add(new TextElement(20f, 30f, 10f, 20f, PDType1Font.HELVETICA, 1f, "D", 1f, 6f));
180+
textChunk2.add(new TextElement(20f, 40f, 10f, 20f, PDType1Font.HELVETICA, 1f, "O", 1f, 6f));
181+
expectedWords.add(textChunk2);
182+
183+
Assert.assertEquals(2, words.size());
184+
Assert.assertEquals(expectedWords, words);
185+
186+
}
187+
188+
189+
190+
}

0 commit comments

Comments
 (0)