diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/pathAssertions.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/pathAssertions.kt index 45ac998950..9b297cf945 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/pathAssertions.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/api/fluent/en_GB/pathAssertions.kt @@ -286,6 +286,18 @@ fun Expect.isRegularFile(): Expect = fun Expect.isDirectory(): Expect = _logicAppend { isDirectory() } +/** + * Expects that the subject of the assertion (a [Path]) is a relative path; + * meaning that the [Path] specified in this instance does not start at the file system root. + * + * @return An [Expect] for the current subject of the assertion. + * @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct. + * + * @since 0.14.0 + */ +fun Expect.isRelative(): Expect = + _logicAppend { isRelative() } + /** * Creates an [Expect] for the property [Path.extension][ch.tutteli.niok.extension] * (provided via [niok](https://github.com/robstoll/niok)) of the subject of the assertion, diff --git a/apis/fluent-en_GB/atrium-api-fluent-en_GB-jvm/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/PathAssertionsSpec.kt b/apis/fluent-en_GB/atrium-api-fluent-en_GB-jvm/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/PathAssertionsSpec.kt index 845c641257..dec3fb3c77 100644 --- a/apis/fluent-en_GB/atrium-api-fluent-en_GB-jvm/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/PathAssertionsSpec.kt +++ b/apis/fluent-en_GB/atrium-api-fluent-en_GB-jvm/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/PathAssertionsSpec.kt @@ -20,6 +20,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe fun0(Expect::isExecutable), fun0(Expect::isRegularFile), fun0(Expect::isDirectory), + fun0(Expect::isRelative), fun1(Expect::hasSameBinaryContentAs), fun3(Expect::hasSameTextualContentAs), fun1(Companion::hasSameTextualContentAsDefaultArgs) diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/keywords.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/keywords.kt index dbfbf65ff1..4c2da334bf 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/keywords.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-common/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/keywords.kt @@ -22,6 +22,14 @@ object aRegularFile : Keyword */ object aDirectory : Keyword +/** + * A helper construct to allow expressing assertions about a path being relative. + * It can be used for a parameterless function so that it has one parameter and thus can be used as infix function. + * + * @since 0.14.0 + */ +object relative : Keyword + /** * Represents a helper construct which allows to express blankness. * It can be used for a parameterless function so that it has one parameter and thus can be used as infix function. diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/pathAssertions.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/pathAssertions.kt index 993c75a9ca..a578755b40 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/pathAssertions.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/api/infix/en_GB/pathAssertions.kt @@ -296,6 +296,19 @@ infix fun Expect.toBe(@Suppress("UNUSED_PARAMETER") aRegularFile: infix fun Expect.toBe(@Suppress("UNUSED_PARAMETER") aDirectory: aDirectory): Expect = _logicAppend { isDirectory() } +/** + * Expects that the subject of the assertion (a [Path]) is a relative path; + * meaning that the [Path] specified in this instance does not start at the file system root. + * + * @return An [Expect] for the current subject of the assertion. + * @throws AssertionError Might throw an [AssertionError] if the assertion made is not correct. + * + * @since 0.14.0 + */ +infix fun Expect.toBe(@Suppress("UNUSED_PARAMETER") relative: relative): Expect = + _logicAppend { isRelative() } + + /** * Creates an [Expect] for the property [Path.extension][ch.tutteli.niok.extension] * (provided via [niok](https://github.com/robstoll/niok)) of the subject of the assertion, diff --git a/apis/infix-en_GB/atrium-api-infix-en_GB-jvm/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/PathAssertionsSpec.kt b/apis/infix-en_GB/atrium-api-infix-en_GB-jvm/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/PathAssertionsSpec.kt index fdb1f810e7..0becea6b4a 100644 --- a/apis/infix-en_GB/atrium-api-infix-en_GB-jvm/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/PathAssertionsSpec.kt +++ b/apis/infix-en_GB/atrium-api-infix-en_GB-jvm/src/test/kotlin/ch/tutteli/atrium/api/infix/en_GB/PathAssertionsSpec.kt @@ -21,6 +21,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe "toBe ${executable::class.simpleName}" to Companion::isExecutable, "toBe ${aRegularFile::class.simpleName}" to Companion::isRegularFile, "toBe ${aDirectory::class.simpleName}" to Companion::isDirectory, + "toBe ${relative::class.simpleName}" to Companion::isRelative, fun1(Expect::hasSameBinaryContentAs), fun3(Companion::hasSameTextualContentAs), fun1(Companion::hasSameTextualContentAsDefaultArgs) @@ -34,6 +35,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe private fun isExecutable(expect: Expect) = expect toBe executable private fun isRegularFile(expect: Expect) = expect toBe aRegularFile private fun isDirectory(expect: Expect) = expect toBe aDirectory + private fun isRelative(expect: Expect) = expect toBe relative private fun hasSameTextualContentAs( expect: Expect, @@ -62,6 +64,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe a1 toBe writable a1 toBe aRegularFile a1 toBe aDirectory + a1 toBe relative a1 hasSameTextualContentAs withEncoding(Paths.get("a")) a1 hasSameTextualContentAs Paths.get("a") } diff --git a/logic/atrium-logic-jvm/src/generated/kotlin/ch/tutteli/atrium/logic/path.kt b/logic/atrium-logic-jvm/src/generated/kotlin/ch/tutteli/atrium/logic/path.kt index f206d28c41..f7f2623bb7 100644 --- a/logic/atrium-logic-jvm/src/generated/kotlin/ch/tutteli/atrium/logic/path.kt +++ b/logic/atrium-logic-jvm/src/generated/kotlin/ch/tutteli/atrium/logic/path.kt @@ -32,6 +32,7 @@ fun AssertionContainer.isWritable(): Assertion = impl.isWritable(t fun AssertionContainer.isExecutable(): Assertion = impl.isExecutable(this) fun AssertionContainer.isRegularFile(): Assertion = impl.isRegularFile(this) fun AssertionContainer.isDirectory(): Assertion = impl.isDirectory(this) +fun AssertionContainer.isRelative(): Assertion = impl.isRelative(this) fun AssertionContainer.hasSameTextualContentAs(targetPath: Path, sourceCharset: Charset, targetCharset: Charset): Assertion = impl.hasSameTextualContentAs(this, targetPath, sourceCharset, targetCharset) diff --git a/logic/atrium-logic-jvm/src/main/kotlin/ch/tutteli/atrium/logic/PathAssertions.kt b/logic/atrium-logic-jvm/src/main/kotlin/ch/tutteli/atrium/logic/PathAssertions.kt index 2d22d1506d..39ca2ed22e 100644 --- a/logic/atrium-logic-jvm/src/main/kotlin/ch/tutteli/atrium/logic/PathAssertions.kt +++ b/logic/atrium-logic-jvm/src/main/kotlin/ch/tutteli/atrium/logic/PathAssertions.kt @@ -28,6 +28,7 @@ interface PathAssertions { fun isExecutable(container: AssertionContainer): Assertion fun isRegularFile(container: AssertionContainer): Assertion fun isDirectory(container: AssertionContainer): Assertion + fun isRelative(container: AssertionContainer): Assertion fun hasSameTextualContentAs( container: AssertionContainer, diff --git a/logic/atrium-logic-jvm/src/main/kotlin/ch/tutteli/atrium/logic/impl/DefaultPathAssertions.kt b/logic/atrium-logic-jvm/src/main/kotlin/ch/tutteli/atrium/logic/impl/DefaultPathAssertions.kt index 313c3378fd..692005f4f3 100644 --- a/logic/atrium-logic-jvm/src/main/kotlin/ch/tutteli/atrium/logic/impl/DefaultPathAssertions.kt +++ b/logic/atrium-logic-jvm/src/main/kotlin/ch/tutteli/atrium/logic/impl/DefaultPathAssertions.kt @@ -109,6 +109,9 @@ class DefaultPathAssertions : PathAssertions { override fun isDirectory(container: AssertionContainer): Assertion = fileTypeAssertion(container, A_DIRECTORY) { it.isDirectory } + override fun isRelative(container: AssertionContainer): Assertion = + container.createDescriptiveAssertion(DescriptionBasic.IS, RELATIVE_PATH) { !it.isAbsolute } + private fun filePermissionAssertion( container: AssertionContainer, permissionName: Translatable, @@ -147,7 +150,6 @@ class DefaultPathAssertions : PathAssertions { .build() } - override fun fileName(container: AssertionContainer): FeatureExtractorBuilder.ExecutionStep = container.manualFeature(FILE_NAME) { fileName.toString() } diff --git a/misc/deprecated/apis/fluent-en_GB-jdk8/atrium-api-fluent-en_GB-jdk8-jvm/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/jdk8/PathAssertionsSpec.kt b/misc/deprecated/apis/fluent-en_GB-jdk8/atrium-api-fluent-en_GB-jdk8-jvm/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/jdk8/PathAssertionsSpec.kt index 0d19b3915e..12bf47c485 100644 --- a/misc/deprecated/apis/fluent-en_GB-jdk8/atrium-api-fluent-en_GB-jdk8-jvm/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/jdk8/PathAssertionsSpec.kt +++ b/misc/deprecated/apis/fluent-en_GB-jdk8/atrium-api-fluent-en_GB-jdk8-jvm/src/test/kotlin/ch/tutteli/atrium/api/fluent/en_GB/jdk8/PathAssertionsSpec.kt @@ -4,6 +4,7 @@ package ch.tutteli.atrium.api.fluent.en_GB.jdk8 import ch.tutteli.atrium.api.fluent.en_GB.isExecutable +import ch.tutteli.atrium.api.fluent.en_GB.isRelative import ch.tutteli.atrium.creating.Expect import ch.tutteli.atrium.specs.fun0 import ch.tutteli.atrium.specs.fun1 @@ -24,6 +25,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe fun0(Expect::isExecutable), // checks the new function from fluent-jvm because it is not implemented in fluent-jkd8 fun0(Expect::isRegularFile), fun0(Expect::isDirectory), + fun0(Expect::isRelative), // checks the new function from fluent-jvm because it is not implemented in fluent-jkd8 fun1(Expect::hasSameBinaryContentAs), fun3(Expect::hasSameTextualContentAs), fun1(Companion::hasSameTextualContentAsDefaultArgs) diff --git a/misc/specs/atrium-specs-jvm/src/main/kotlin/ch/tutteli/atrium/specs/integration/PathAssertionsSpec.kt b/misc/specs/atrium-specs-jvm/src/main/kotlin/ch/tutteli/atrium/specs/integration/PathAssertionsSpec.kt index 59528edb41..e4dcfbac34 100644 --- a/misc/specs/atrium-specs-jvm/src/main/kotlin/ch/tutteli/atrium/specs/integration/PathAssertionsSpec.kt +++ b/misc/specs/atrium-specs-jvm/src/main/kotlin/ch/tutteli/atrium/specs/integration/PathAssertionsSpec.kt @@ -43,6 +43,7 @@ abstract class PathAssertionsSpec( isExecutable: Fun0, isRegularFile: Fun0, isDirectory: Fun0, + isRelative: Fun0, hasSameBinaryContentAs: Fun1, hasSameTextualContentAs: Fun3, hasSameTextualContentAsDefaultArgs: Fun1, @@ -62,6 +63,7 @@ abstract class PathAssertionsSpec( isExecutable.forSubjectLess(), isRegularFile.forSubjectLess(), isDirectory.forSubjectLess(), + isRelative.forSubjectLess(), hasSameBinaryContentAs.forSubjectLess(Paths.get("a")), hasSameTextualContentAs.forSubjectLess(Paths.get("a"), Charsets.ISO_8859_1, Charsets.ISO_8859_1), hasSameTextualContentAsDefaultArgs.forSubjectLess(Paths.get("a")) @@ -828,6 +830,24 @@ abstract class PathAssertionsSpec( } } + describeFun(isRelative) { + val isRelativeFun = isRelative.lambda + + it("throws an AssertionError for absolute path") { + val path = tempFolder.newFile("test") + expect { + expect(path).isRelativeFun() + }.toThrow { + messageContains("$isDescr: ${RELATIVE_PATH.getDefault()}") + } + } + + it("does not throw for relative path") { + val path = Paths.get("test/bla.txt") + expect(path).isRelativeFun() + } + } + describeFun(hasSameBinaryContentAs, hasSameTextualContentAs, hasSameTextualContentAsDefaultArgs) { val hasSameBinaryContentAsFun = hasSameBinaryContentAs.lambda val hasSameTextualContentAsFun = hasSameTextualContentAs.lambda diff --git a/translations/de_CH/atrium-translations-de_CH-jvm/src/main/kotlin/ch/tutteli/atrium/translations/DescriptionPathAssertion.kt b/translations/de_CH/atrium-translations-de_CH-jvm/src/main/kotlin/ch/tutteli/atrium/translations/DescriptionPathAssertion.kt index fbb5af7f34..ce16fbe25e 100644 --- a/translations/de_CH/atrium-translations-de_CH-jvm/src/main/kotlin/ch/tutteli/atrium/translations/DescriptionPathAssertion.kt +++ b/translations/de_CH/atrium-translations-de_CH-jvm/src/main/kotlin/ch/tutteli/atrium/translations/DescriptionPathAssertion.kt @@ -13,6 +13,7 @@ import java.nio.file.Path * Contains the [DescriptiveAssertion.description]s of the assertion functions which are applicable to [Path]. */ enum class DescriptionPathAssertion(override val value: String) : StringBasedTranslatable { + ABSOLUTE_PATH("ein absoluter Pfad"), DOES_NOT_HAVE_PARENT("!! hat keinen Elternpfad"), ENDS_NOT_WITH("endet nicht mit"), ENDS_WITH("endet mit"), @@ -44,5 +45,6 @@ enum class DescriptionPathAssertion(override val value: String) : StringBasedTra HINT_CLOSEST_EXISTING_PARENT_DIRECTORY("das nächste, existierende Elternverzeichnis ist %s"), HINT_FOLLOWED_SYMBOLIC_LINK("folgte der symbolischen Verknüpfung %s nach %s"), HAS_SAME_TEXTUAL_CONTENT("hat denselben textlichen Inhalt mit Kodierung %s, %s"), - HAS_SAME_BINARY_CONTENT("hat denselben binären Inhalt") + HAS_SAME_BINARY_CONTENT("hat denselben binären Inhalt"), + RELATIVE_PATH("ein relativer Pfad") } diff --git a/translations/en_GB/atrium-translations-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/translations/DescriptionPathAssertion.kt b/translations/en_GB/atrium-translations-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/translations/DescriptionPathAssertion.kt index 3d8d56fdde..4ae9ed9a87 100644 --- a/translations/en_GB/atrium-translations-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/translations/DescriptionPathAssertion.kt +++ b/translations/en_GB/atrium-translations-en_GB-jvm/src/main/kotlin/ch/tutteli/atrium/translations/DescriptionPathAssertion.kt @@ -8,6 +8,7 @@ package ch.tutteli.atrium.translations import ch.tutteli.atrium.reporting.translating.StringBasedTranslatable enum class DescriptionPathAssertion(override val value: String) : StringBasedTranslatable { + ABSOLUTE_PATH("an absolute path"), DOES_NOT_HAVE_PARENT("!! does not have a parent"), ENDS_NOT_WITH("does not end with"), ENDS_WITH("ends with"), @@ -40,4 +41,5 @@ enum class DescriptionPathAssertion(override val value: String) : StringBasedTra HINT_FOLLOWED_SYMBOLIC_LINK("followed the symbolic link %s to %s"), HAS_SAME_TEXTUAL_CONTENT("has same textual content with encoding %s, %s"), HAS_SAME_BINARY_CONTENT("has same binary content"), + RELATIVE_PATH("a relative path"), }