Browse files

Fixed sibling rebuild from Zipper with eliminated results

  • Loading branch information...
1 parent f37953d commit d9a6d43193688ff492fd0013cd9c860cec36a624 @djspiewak committed May 29, 2011
View
2 CHANGELOG.rst
@@ -7,6 +7,8 @@ CHANGELOG
* **Bug Fixes**
+ * ``Zipper#unselect`` fails to rebuild siblings at the second level when some
+ results have been dropped
* ``Zipper#unselect`` on empty selection results no functions appropriately
* `Issue 12`_ – Utility Operations on Group Return an Invalid Zipper
View
11 src/main/scala/com/codecommit/antixml/Zipper.scala
@@ -46,9 +46,14 @@ trait Zipper[+A <: Node] extends Group[A] with IndexedSeqLike[A, Zipper[A]] with
def unselect: Zipper[Node] = {
val nodes2 = (map zip parent.toVectorCase).foldLeft(VectorCase[Node]()) {
- case (acc, (Some((from, to, _, _)), _: Elem)) if from == to => acc
- case (acc, (Some((from, to, rebuild, childMap)), _: Elem)) => acc :+ rebuild(self.slice(from, to), childMap)
- case (acc, (_, e)) => acc :+ e
+ case (acc, (Some((from, to, rebuild, childMap)), _: Elem)) if from == to =>
+ acc :+ rebuild(Group(), childMap mapValues Function.const(Set[Int]()))
+
+ case (acc, (Some((from, to, rebuild, childMap)), _: Elem)) =>
+ acc :+ rebuild(self.slice(from, to), childMap)
+
+ case (acc, (_, e)) =>
+ acc :+ e
}
new Group(nodes2) with Zipper[Node] {
View
16 src/main/scala/com/codecommit/antixml/util/vectorCases.scala
@@ -145,14 +145,14 @@ private[antixml] case class Vector1[+A](_1: A) extends VectorCase[A] {
if (index == 0)
_1
else
- throw new IndexOutOfBoundsException
+ throw new IndexOutOfBoundsException(index.toString)
}
def updated[B >: A](index: Int, b: B) = {
if (index == 0)
Vector1(b)
else
- throw new IndexOutOfBoundsException
+ throw new IndexOutOfBoundsException(index.toString)
}
def ++[B >: A](that: VectorCase[B]) = that match {
@@ -178,13 +178,13 @@ private[antixml] case class Vector2[+A](_1: A, _2: A) extends VectorCase[A] {
def apply(index: Int) = index match {
case 0 => _1
case 1 => _2
- case _ => throw new IndexOutOfBoundsException
+ case _ => throw new IndexOutOfBoundsException(index.toString)
}
def updated[B >: A](index: Int, b: B) = index match {
case 0 => Vector2(b, _2)
case 1 => Vector2(_1, b)
- case _ => throw new IndexOutOfBoundsException
+ case _ => throw new IndexOutOfBoundsException(index.toString)
}
def ++[B >: A](that: VectorCase[B]) = that match {
@@ -210,14 +210,14 @@ private[antixml] case class Vector3[+A](_1: A, _2: A, _3: A) extends VectorCase[
case 0 => _1
case 1 => _2
case 2 => _3
- case _ => throw new IndexOutOfBoundsException
+ case _ => throw new IndexOutOfBoundsException(index.toString)
}
def updated[B >: A](index: Int, b: B) = index match {
case 0 => Vector3(b, _2, _3)
case 1 => Vector3(_1, b, _3)
case 2 => Vector3(_1, _2, b)
- case _ => throw new IndexOutOfBoundsException
+ case _ => throw new IndexOutOfBoundsException(index.toString)
}
def ++[B >: A](that: VectorCase[B]) = that match {
@@ -243,15 +243,15 @@ private[antixml] case class Vector4[+A](_1: A, _2: A, _3: A, _4: A) extends Vect
case 1 => _2
case 2 => _3
case 3 => _4
- case _ => throw new IndexOutOfBoundsException
+ case _ => throw new IndexOutOfBoundsException(index.toString)
}
def updated[B >: A](index: Int, b: B) = index match {
case 0 => Vector4(b, _2, _3, _4)
case 1 => Vector4(_1, b, _3, _4)
case 2 => Vector4(_1, _2, b, _4)
case 3 => Vector4(_1, _2, _3, b)
- case _ => throw new IndexOutOfBoundsException
+ case _ => throw new IndexOutOfBoundsException(index.toString)
}
def ++[B >: A](that: VectorCase[B]) = that match {
View
47 src/test/scala/com/codecommit/antixml/ZipperSpecs.scala
@@ -33,6 +33,7 @@ import org.specs2.ScalaCheck
import org.specs2.matcher.MustExpectable._
import org.scalacheck._
+import scala.collection.immutable.Map
import scala.io.Source
class ZipperSpecs extends Specification with ScalaCheck with XMLGenerators {
@@ -169,6 +170,42 @@ class ZipperSpecs extends Specification with ScalaCheck with XMLGenerators {
xml2 mustEqual xml
}
+
+ "rebuild following filter at the first level" in {
+ val books = bookstore \ 'book
+ val bookstore2 = (books filter (books(1) !=)).unselect
+
+ bookstore2.head must beLike {
+ case Elem(None, "bookstore", attrs, scopes, children) if attrs.isEmpty && scopes.isEmpty => {
+ children must haveSize(2)
+ children \ 'title \ text mustEqual Vector("For Whom the Bell Tolls", "Programming Scala")
+ }
+ }
+ }
+
+ "rebuild second level siblings following filter at the second level" in {
+ val titles = bookstore \ 'book \ 'title
+ val books2 = (titles filter (titles(1) ==)).unselect
+
+ books2 must haveSize(3)
+ books2(0) mustEqual <book><author>Hemmingway</author></book>.anti
+ books2(1) mustEqual <book><title>I, Robot</title><author>Isaac Asimov</author></book>.anti
+ books2(2) mustEqual <book><author>Dean Wampler</author><author>Alex Payne</author></book>.anti
+ }
+
+ "rebuild following filter at the second level" in {
+ val titles = bookstore \ 'book \ 'title
+ val bookstore2 = (titles filter (titles(1) !=)).unselect.unselect
+
+ bookstore2.head must beLike {
+ case Elem(None, "bookstore", attrs, scopes, children) if attrs.isEmpty && scopes.isEmpty =>
+ children must haveSize(3)
+ }
+
+ val titles2 = bookstore2 \ 'book \ 'title
+ titles2 must haveSize(2)
+ (titles2 \ text) mustEqual Vector("For Whom the Bell Tolls", "Programming Scala")
+ }
}
"utility methods on Zipper" >> {
@@ -181,6 +218,16 @@ class ZipperSpecs extends Specification with ScalaCheck with XMLGenerators {
func(xml.toZipper) mustEqual xml
}
+
+ "identity filter should return self" in check { xml: Group[Node] =>
+ val result = xml.toZipper filter Function.const(true)
+ result mustEqual xml
+ }
+
+ "identity filter and unselect should return self" in check { xml: Group[Node] =>
+ val sub = xml \ *
+ (sub filter Function.const(true) unselect) mustEqual xml
+ }
}
def resource(filename: String) =

0 comments on commit d9a6d43

Please sign in to comment.