~jan0sch/smederee
Showing details for patch c2f2de0476156ddff922d7593c4316b8c06b294f.
diff -rN -u old-smederee/CHANGELOG.md new-smederee/CHANGELOG.md --- old-smederee/CHANGELOG.md 2025-02-01 19:02:02.848647153 +0000 +++ new-smederee/CHANGELOG.md 2025-02-01 19:02:02.848647153 +0000 @@ -20,6 +20,10 @@ ## Unreleased +### Fixed + +- history summary shows wrong number of lines that were added/removed + ## 0.2.0 (2022-11-03) ### Changed diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala --- old-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala 2025-02-01 19:02:02.848647153 +0000 +++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/VcsRepository.scala 2025-02-01 19:02:02.848647153 +0000 @@ -360,9 +360,19 @@ .map(summary => (summary \ "modify_file").toList.flatMap { file => val filename = VcsPatchFilename.from(file.text) - val added_lines = (file \ "added_lines" \@ "num").headOption.map(_.toInt).getOrElse(0) - val removed_lines = (file \ "removed_lines" \@ "num").headOption.map(_.toInt).getOrElse(0) - filename.map(filename => VcsPatchSummaryFileModification(added_lines, filename, removed_lines)) + val added_lines = file \ "added_lines" \@ "num" + val removed_lines = file \ "removed_lines" \@ "num" + val added = + if (added_lines.nonEmpty && added_lines.forall(_.isDigit)) + added_lines.toInt + else + 0 + val removed = + if (removed_lines.nonEmpty && removed_lines.forall(_.isDigit)) + removed_lines.toInt + else + 0 + filename.map(filename => VcsPatchSummaryFileModification(added, filename, removed)) } ) .getOrElse(List.empty) diff -rN -u old-smederee/modules/hub/src/test/scala/de/smederee/hub/VcsRepositoryPatchMetadataTest.scala new-smederee/modules/hub/src/test/scala/de/smederee/hub/VcsRepositoryPatchMetadataTest.scala --- old-smederee/modules/hub/src/test/scala/de/smederee/hub/VcsRepositoryPatchMetadataTest.scala 1970-01-01 00:00:00.000000000 +0000 +++ new-smederee/modules/hub/src/test/scala/de/smederee/hub/VcsRepositoryPatchMetadataTest.scala 2025-02-01 19:02:02.848647153 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2022 Contributors as noted in the AUTHORS.md file + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.smederee.hub + +import cats.syntax.all._ +import de.smederee.hub.Generators.given + +import munit._ +import org.scalacheck._ +import org.scalacheck.Prop._ + +final class VcsRepositoryPatchMetadataTest extends ScalaCheckSuite { + private val genVcsPatchFilename: Gen[VcsPatchFilename] = + Gen.nonEmptyListOf(Gen.alphaNumChar).map(chars => VcsPatchFilename(chars.mkString)) + private val genVcsPatchFilenames: Gen[List[VcsPatchFilename]] = Gen.listOf(genVcsPatchFilename) + private val genVcsPatchSummaryFileModification: Gen[VcsPatchSummaryFileModification] = for { + name <- genVcsPatchFilename + added <- Gen.choose(0, Int.MaxValue) + removed <- Gen.choose(0, Int.MaxValue) + } yield VcsPatchSummaryFileModification(added, name, removed) + private val genVcsPatchSummaryFileModifications: Gen[List[VcsPatchSummaryFileModification]] = + Gen.listOf(genVcsPatchSummaryFileModification) + + /** Create a darcs xml patch element from the given input for testing purposes. + * + * @return + * An xml node which holds all information required to mimick a darcs log xml-output patch entry. + */ + private def createPatchXml( + added: List[VcsPatchFilename], + modified: List[VcsPatchSummaryFileModification], + removed: List[VcsPatchFilename] + ): scala.xml.Node = { + // We need to preserve the xml parts as they are because line breaks etc. would be added to file names! + // format: off + val added_files = added.map(filename => <add_file>{filename.toString}</add_file>) + val removed_files = removed.map(filename => <remove_file>{filename.toString}</remove_file>) + val modified_files = modified.map { summary => + <modify_file>{summary.name.toString}<removed_lines num={summary.removed.toString}/><added_lines num={summary.added.toString}/></modify_file> + } + val patch = + <patch> + <name>TEST</name> + <comment>A test comment...</comment> + <summary> + {added_files} + {modified_files} + {removed_files} + </summary> + </patch> + // format: on + patch + } + + property("VcsPatchSummary#fromDarcsXmlLog must parse a given XML node correctly") { + forAll(genVcsPatchFilenames, genVcsPatchSummaryFileModifications, genVcsPatchFilenames) { + ( + added: List[VcsPatchFilename], + modified: List[VcsPatchSummaryFileModification], + removed: List[VcsPatchFilename] + ) => + val xmlInput = createPatchXml(added, modified, removed) + val expected = VcsPatchSummary(added, modified, removed) + VcsPatchSummary.fromDarcsXmlLog(xmlInput) match { + case None => fail("VcsPatchSummary could not be generated!") + case Some(obtained) => assertEquals(obtained, expected) + } + } + } + +}