Skip to content

Commit 4fc7b8f

Browse files
committed
Adding methods for removing passages from a set and tests.
1 parent f9f9708 commit 4fc7b8f

File tree

4 files changed

+180
-7
lines changed

4 files changed

+180
-7
lines changed

src/ScripturNum.php

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,19 @@ public function __get($what)
8080
case "endV":
8181
return $this->endV;
8282
}
83-
throw new \Error("The requested property does not exist.");
83+
throw new \Error("The requested property ($what) does not exist.");
8484
}
8585

86+
protected function startInt(): int
87+
{
88+
return ($this->int & (self::BOOK_MASK | self::START_MASK)) >> 12;
89+
}
90+
91+
protected function endInt(): int
92+
{
93+
return ($this->int & self::BOOK_MASK) >> 12 | ($this->int & self::END_MASK);
94+
}
95+
8696

8797
protected static $stringSettings = [
8898
'abbrev' => [
@@ -178,7 +188,7 @@ public function getLongString(): string
178188
*
179189
* @throws ScripturNumException
180190
*/
181-
public function toString($options): string
191+
public function toString($options = []): string
182192
{
183193
$s = $this->getStringWithSettings($options);
184194
if (isset($options['callback']) && is_callable($options['callback'])) {
@@ -310,6 +320,54 @@ protected function getStringWithSettings(&$options): string
310320
}
311321
}
312322

323+
/**
324+
* Remove a passage from this passage, returning an array of ScripturNum objects that represent the difference.
325+
*
326+
* @see ScripturNumArray::remove()
327+
*
328+
* @param $passageToRemove
329+
* @return ScripturNumArray
330+
* @throws ScripturNumException
331+
*/
332+
public function remove($passageToRemove): ScripturNumArray
333+
{
334+
// if no overlap at all, keep whole (condition 1)
335+
if (!$this->overlapsWith($passageToRemove)) {
336+
return new ScripturNumArray([$this]);
337+
}
338+
339+
// if fully contained, do not keep (condition 2)
340+
if ($passageToRemove->contains($this)) {
341+
return new ScripturNumArray([]);
342+
}
343+
344+
$return = new ScripturNumArray();
345+
346+
// if sn starts before other starts, keep sn start to other start-1 (condition 3)
347+
if ($this->startInt() < $passageToRemove->startInt()) {
348+
$return[] = static::newFromInts(
349+
$this->book,
350+
$this->startCh,
351+
$this->startV,
352+
$passageToRemove->startCh,
353+
$passageToRemove->startV - 1
354+
);
355+
}
356+
357+
// if sn ends after other ends, keep other end+1 to sn end (condition 4)
358+
if ($this->endInt() > $passageToRemove->endInt()) {
359+
$return[] = static::newFromInts(
360+
$this->book,
361+
$passageToRemove->endCh,
362+
$passageToRemove->endV + 1,
363+
$this->endCh,
364+
$this->endV
365+
);
366+
}
367+
368+
return $return;
369+
}
370+
313371

314372
/**
315373
* Returns true if the passage is an entire chapter.

src/ScripturNumArray.php

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,16 +260,45 @@ public function count(): int
260260
return count($this->container);
261261
}
262262

263+
public function remove(ScripturNum $other): ScripturNumArray
264+
{
265+
$result = new ScripturNumArray();
266+
267+
$this->sortAndCombineIfNeeded();
268+
269+
foreach ($this->container as $sn) {
270+
$r = $sn->remove($other);
271+
foreach ($r as $s) {
272+
$result[] = $s;
273+
}
274+
}
275+
276+
$result->sortAndCombineIfNeeded();
277+
278+
return $result;
279+
}
280+
281+
public function removeAll(ScripturNumArray $others): ScripturNumArray
282+
{
283+
$this->sortAndCombineIfNeeded();
284+
$others->sortAndCombineIfNeeded();
285+
286+
$r = new ScripturNumArray($this->container);
287+
288+
foreach ($others as $o) {
289+
$r = $r->remove($o);
290+
}
291+
292+
$r->sortAndCombineIfNeeded();
293+
return $r;
294+
}
295+
263296
/**
264297
* @return string
265298
*/
266299
public function __toString(): string
267300
{
268-
try {
269-
return $this->toString();
270-
} catch (ScripturNumException $e) {
271-
return '';
272-
}
301+
return $this->getString();
273302
}
274303

275304
/**

tests/ScripturNumArrayTests.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,32 @@ public function test_arrayAbbrev()
131131
$a = new ScripturNumArray(['Genesis 1:1-5', 'Exodus 3:1-10', 'John 3:16']);
132132
$this->assertEquals('Ge1.1-5, Ex3.1-10, Jn3.16', $a->toString('abbrev'));
133133
}
134+
135+
public function test_removeItem()
136+
{
137+
$a = new ScripturNumArray(['Genesis 1:1-5', 'Exodus 3:1-10', 'John 3:16']);
138+
$b = new ScripturNum('Genesis 1:1-5');
139+
$c = $a->remove($b);
140+
$this->assertCount(2, $c);
141+
$this->assertEquals('Exodus 3:1-10', (string)$c[0]);
142+
$this->assertEquals('John 3:16', (string)$c[1]);
143+
}
144+
145+
public function test_removeItem_notFound()
146+
{
147+
$a = new ScripturNumArray(['Genesis 1:1-5', 'Exodus 3:1-10', 'John 3:16']);
148+
$b = new ScripturNum('Romans 1:1-5');
149+
$c = $a->remove($b);
150+
$this->assertCount(3, $c);
151+
}
152+
153+
public function test_removeAll()
154+
{
155+
$a = new ScripturNumArray(['Genesis 1:1-5', 'Exodus 3:1-10', 'John 3', 'Genesis 1:1-5']);
156+
$b = new ScripturNumArray(['Genesis 1:1-5', 'John 3:16']);
157+
$c = $a->removeAll($b);
158+
$this->assertCount(3, $c);
159+
$this->assertEquals('Exodus 3:1-10', (string)$c[0]);
160+
$this->assertEquals('John 3:1-15', (string)$c[1]);
161+
}
134162
}

tests/ScripturNumPublicTests.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ public function test_intToCats() {
145145
$this->assertEquals(19001002, $concatEnd);
146146
}
147147

148+
public function test_stringNoOption()
149+
{
150+
$n = new ScripturNum('John 3:16');
151+
$this->assertEquals('John 3:16', $n->toString());
152+
}
153+
148154

149155

150156
public function test_issue01() {
@@ -1024,4 +1030,56 @@ public function test_issue15d()
10241030
$sn = ScripturNum::extractFromString($a, false, $e);
10251031
$this->assertEquals("1 John 2:28", $sn->toString());
10261032
}
1033+
1034+
public function test_remove_noOverlap()
1035+
{
1036+
$a = new ScripturNum("Exodus 20");
1037+
$b = new ScripturNum("Exodus 21");
1038+
$result = $a->remove($b);
1039+
$this->assertEquals("Exodus 20", $result->toString());
1040+
}
1041+
1042+
public function test_remove_noOverlap_book()
1043+
{
1044+
$a = new ScripturNum("Exodus 20");
1045+
$b = new ScripturNum("Genesis 21");
1046+
$result = $a->remove($b);
1047+
$this->assertEquals("Exodus 20", $result->toString());
1048+
}
1049+
1050+
public function test_remove_fullyContained()
1051+
{
1052+
$a = new ScripturNum("Exodus 20:5");
1053+
$b = new ScripturNum("Exodus 20");
1054+
$result = $a->remove($b);
1055+
$this->assertCount(0, $result);
1056+
}
1057+
1058+
public function test_remove_split()
1059+
{
1060+
$a = new ScripturNum("Exodus 20");
1061+
$b = new ScripturNum("Exodus 20:5");
1062+
$result = $a->remove($b);
1063+
$this->assertCount(2, $result);
1064+
$this->assertEquals("Exodus 20:1-4", (string)$result[0]);
1065+
$this->assertEquals("Exodus 20:6-26", (string)$result[1]);
1066+
}
1067+
1068+
public function test_remove_overlapEnd()
1069+
{
1070+
$a = new ScripturNum("Exodus 20-21");
1071+
$b = new ScripturNum("Exodus 21-22");
1072+
$result = $a->remove($b);
1073+
$this->assertCount(1, $result);
1074+
$this->assertEquals("Exodus 20", (string)$result);
1075+
}
1076+
1077+
public function test_remove_overlapStart()
1078+
{
1079+
$a = new ScripturNum("Exodus 20-21");
1080+
$b = new ScripturNum("Exodus 19-20");
1081+
$result = $a->remove($b);
1082+
$this->assertCount(1, $result);
1083+
$this->assertEquals("Exodus 21", (string)$result);
1084+
}
10271085
}

0 commit comments

Comments
 (0)