Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Path.isExecutable #592

Merged
merged 5 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fun <T : Path> Expect<T>.endsNotWith(expected: Path): Expect<T> =
* Expects that the subject of the assertion (a [Path]) exists;
* meaning that there is a file system entry at the location the [Path] points to.
*
* This matcher _resolves_ symbolic links. Therefore, if a symbolic link exists at the location the subject points to,
* This assertion _resolves_ symbolic links. Therefore, if a symbolic link exists at the location the subject points to,
* then the search will continue at that location.
*
* @return An [Expect] for the current subject of the assertion.
Expand All @@ -74,7 +74,7 @@ fun <T : Path> Expect<T>.exists(): Expect<T> =
* Expects that the subject of the assertion (a [Path]) does not exist;
* meaning that there is no file system entry at the location the [Path] points to.
*
* This matcher _resolves_ symbolic links. Therefore, if a symbolic link exists at the location the subject points to,
* This assertion _resolves_ symbolic links. Therefore, if a symbolic link exists at the location the subject points to,
* then the search will continue at that location.
*
* @return An [Expect] for the current subject of the assertion.
Expand Down Expand Up @@ -191,7 +191,7 @@ fun <T : Path> Expect<T>.resolve(other: String, assertionCreator: Expect<Path>.(
* meaning that there is a file system entry at the location the [Path] points to and
* that the current thread has the permission to read from it.
*
* This matcher _resolves_ symbolic links.
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to,
* search will continue at the location the link points at.
*
Expand All @@ -212,7 +212,7 @@ fun <T : Path> Expect<T>.isReadable(): Expect<T> =
* meaning that there is a file system entry at the location the [Path] points to and
* that the current thread has the permission to write to it.
*
* This matcher _resolves_ symbolic links.
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to, search will continue
* at the location the link points at.
*
Expand All @@ -224,11 +224,33 @@ fun <T : Path> Expect<T>.isReadable(): Expect<T> =
fun <T : Path> Expect<T>.isWritable(): Expect<T> =
_logicAppend { isWritable() }


/**
* Expects that the subject of the assertion (a [Path]) is executable;
* meaning that there is a file system entry at the location the [Path] points to and
* that the current thread has the permission to execute it.
*
* The semantics of “permission to execute it” may differ when checking access to a directory. For example, on UNIX
* systems, it means that the Java virtual machine has permission to search the directory in order to access file or
* subdirectories.
*
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to, search will continue
* at the location the link points at.
*
* @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 <T : Path> Expect<T>.isExecutable(): Expect<T> =
_logicAppend { isExecutable() }

/**
* Expects that the subject of the assertion (a [Path]) is a file;
* meaning that there is a file system entry at the location the [Path] points to and that is a regular file.
*
* This matcher _resolves_ symbolic links.
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to, search will continue
* at the location the link points at.
*
Expand All @@ -248,7 +270,7 @@ fun <T : Path> Expect<T>.isRegularFile(): Expect<T> =
* Expects that the subject of the assertion (a [Path]) is a directory;
* meaning that there is a file system entry at the location the [Path] points to and that is a directory.
*
* This matcher _resolves_ symbolic links.
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to, search will continue
* at the location the link points at.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe
fun1(Expect<Path>::endsNotWith),
fun0(Expect<Path>::isReadable),
fun0(Expect<Path>::isWritable),
fun0(Expect<Path>::isExecutable),
fun0(Expect<Path>::isRegularFile),
fun0(Expect<Path>::isDirectory),
fun1(Expect<Path>::hasSameBinaryContentAs),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,9 @@ object success : Keyword
* It can be used for a parameterless function so that it has one parameter and thus can be used as infix function.
*/
object writable : Keyword

/**
* A helper construct to allow expressing assertions about a path being executable.
* It can be used for a parameterless function so that it has one parameter and thus can be used as infix function.
*/
object executable : Keyword
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

package ch.tutteli.atrium.api.infix.en_GB

import ch.tutteli.atrium.api.infix.en_GB.creating.path.PathWithEncoding
import ch.tutteli.atrium.api.infix.en_GB.creating.path.PathWithCreator
import ch.tutteli.atrium.api.infix.en_GB.creating.path.PathWithEncoding
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.logic.*
import java.nio.charset.Charset
Expand Down Expand Up @@ -61,7 +61,7 @@ infix fun <T : Path> Expect<T>.endsNotWith(expected: Path): Expect<T> =
* Expects that the subject of the assertion (a [Path]) exists;
* meaning that there is a file system entry at the location the [Path] points to.
*
* This matcher _resolves_ symbolic links. Therefore, if a symbolic link exists at the location the subject points to,
* This assertion _resolves_ symbolic links. Therefore, if a symbolic link exists at the location the subject points to,
* then the search will continue at that location.
*
* @return An [Expect] for the current subject of the assertion.
Expand All @@ -76,7 +76,7 @@ infix fun <T : Path> Expect<T>.toBe(@Suppress("UNUSED_PARAMETER") existing: exis
* Expects that the subject of the assertion (a [Path]) does not exist;
* meaning that there is no file system entry at the location the [Path] points to.
*
* This matcher _resolves_ symbolic links. Therefore, if a symbolic link exists at the location the subject points to,
* This assertion _resolves_ symbolic links. Therefore, if a symbolic link exists at the location the subject points to,
* then the search will continue at that location.
*
* @return An [Expect] for the current subject of the assertion.
Expand Down Expand Up @@ -202,7 +202,7 @@ fun <E> path(path: String, assertionCreator: Expect<E>.() -> Unit): PathWithCrea
* meaning that there is a file system entry at the location the [Path] points to and
* that the current thread has the permission to read from it.
*
* This matcher _resolves_ symbolic links.
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to,
* search will continue at the location the link points at.
*
Expand All @@ -223,7 +223,7 @@ infix fun <T : Path> Expect<T>.toBe(@Suppress("UNUSED_PARAMETER") readable: read
* meaning that there is a file system entry at the location the [Path] points to and
* that the current thread has the permission to write to it.
*
* This matcher _resolves_ symbolic links.
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to, search will continue
* at the location the link points at.
*
Expand All @@ -235,11 +235,32 @@ infix fun <T : Path> Expect<T>.toBe(@Suppress("UNUSED_PARAMETER") readable: read
infix fun <T : Path> Expect<T>.toBe(@Suppress("UNUSED_PARAMETER") writable: writable): Expect<T> =
_logicAppend { isWritable() }

/**
* Expects that the subject of the assertion (a [Path]) is executable;
* meaning that there is a file system entry at the location the [Path] points to and
* that the current thread has the permission to execute it.
*
* The semantics of “permission to execute it” may differ when checking access to a directory. For example, on UNIX
* systems, it means that the Java virtual machine has permission to search the directory in order to access file or
* subdirectories.
*
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to, search will continue
* at the location the link points at.
*
* @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 <T : Path> Expect<T>.toBe(@Suppress("UNUSED_PARAMETER") executable: executable): Expect<T> =
_logicAppend { isExecutable() }

/**
* Expects that the subject of the assertion (a [Path]) is a file;
* meaning that there is a file system entry at the location the [Path] points to and that is a regular file.
*
* This matcher _resolves_ symbolic links.
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to, search will continue
* at the location the link points at.
*
Expand All @@ -259,7 +280,7 @@ infix fun <T : Path> Expect<T>.toBe(@Suppress("UNUSED_PARAMETER") aRegularFile:
* Expects that the subject of the assertion (a [Path]) is a directory;
* meaning that there is a file system entry at the location the [Path] points to and that is a directory.
*
* This matcher _resolves_ symbolic links.
* This assertion _resolves_ symbolic links.
* Therefore, if a symbolic link exists at the location the subject points to, search will continue
* at the location the link points at.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe
fun1(Expect<Path>::endsNotWith),
"toBe ${readable::class.simpleName}" to Companion::isReadable,
"toBe ${writable::class.simpleName}" to Companion::isWritable,
"toBe ${executable::class.simpleName}" to Companion::isExecutable,
"toBe ${aRegularFile::class.simpleName}" to Companion::isRegularFile,
"toBe ${aDirectory::class.simpleName}" to Companion::isDirectory,
fun1(Expect<Path>::hasSameBinaryContentAs),
Expand All @@ -30,6 +31,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe
private fun existsNot(expect: Expect<Path>) = expect notToBe existing
private fun isReadable(expect: Expect<Path>) = expect toBe readable
private fun isWritable(expect: Expect<Path>) = expect toBe writable
private fun isExecutable(expect: Expect<Path>) = expect toBe executable
private fun isRegularFile(expect: Expect<Path>) = expect toBe aRegularFile
private fun isDirectory(expect: Expect<Path>) = expect toBe aDirectory

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import ch.tutteli.atrium.creating.AssertionContainer
import ch.tutteli.atrium.domain.creating.changers.ExtractedFeaturePostStep
import java.nio.charset.Charset
import java.nio.file.Path
import java.util.*

fun <T : Path> AssertionContainer<T>.startsWith(expected: Path): Assertion = _pathImpl.startsWith(this, expected)
fun <T : Path> AssertionContainer<T>.startsNotWith(expected: Path): Assertion = _pathImpl.startsNotWith(this, expected)
Expand All @@ -28,6 +27,7 @@ fun <T : Path> AssertionContainer<T>.existsNot(): Assertion = _pathImpl.existsNo

fun <T : Path> AssertionContainer<T>.isReadable(): Assertion = _pathImpl.isReadable(this)
fun <T : Path> AssertionContainer<T>.isWritable(): Assertion = _pathImpl.isWritable(this)
fun <T : Path> AssertionContainer<T>.isExecutable(): Assertion = _pathImpl.isExecutable(this)
fun <T : Path> AssertionContainer<T>.isRegularFile(): Assertion = _pathImpl.isRegularFile(this)
fun <T : Path> AssertionContainer<T>.isDirectory(): Assertion = _pathImpl.isDirectory(this)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import ch.tutteli.atrium.creating.AssertionContainer
import ch.tutteli.atrium.domain.creating.changers.ExtractedFeaturePostStep
import java.nio.charset.Charset
import java.nio.file.Path
import java.util.*

/**
* Collection of assertion functions and builders which are applicable to subjects with a [Path] type.
Expand All @@ -26,6 +25,7 @@ interface PathAssertions {

fun <T : Path> isReadable(container: AssertionContainer<T>): Assertion
fun <T : Path> isWritable(container: AssertionContainer<T>): Assertion
fun <T : Path> isExecutable(container: AssertionContainer<T>): Assertion
fun <T : Path> isRegularFile(container: AssertionContainer<T>): Assertion
fun <T : Path> isDirectory(container: AssertionContainer<T>): Assertion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class DefaultPathAssertions : PathAssertions {
override fun <T : Path> isWritable(container: AssertionContainer<T>): Assertion =
filePermissionAssertion(container, WRITABLE, AccessMode.WRITE)

override fun <T : Path> isExecutable(container: AssertionContainer<T>): Assertion =
filePermissionAssertion(container, EXECUTABLE, AccessMode.EXECUTE)

override fun <T : Path> isRegularFile(container: AssertionContainer<T>): Assertion =
fileTypeAssertion(container, A_FILE) { it.isRegularFile }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

package ch.tutteli.atrium.api.fluent.en_GB.jdk8

import ch.tutteli.atrium.api.fluent.en_GB.isExecutable
import ch.tutteli.atrium.creating.Expect
import ch.tutteli.atrium.specs.fun0
import ch.tutteli.atrium.specs.fun1
Expand All @@ -20,6 +21,7 @@ class PathAssertionsSpec : ch.tutteli.atrium.specs.integration.PathAssertionsSpe
fun1(Expect<Path>::endsNotWith),
fun0(Expect<Path>::isReadable),
fun0(Expect<Path>::isWritable),
fun0(Expect<Path>::isExecutable), // checks the new function from fluent-jvm because it is not implemented in fluent-jkd8
fun0(Expect<Path>::isRegularFile),
fun0(Expect<Path>::isDirectory),
fun1(Expect<Path>::hasSameBinaryContentAs),
Expand Down
Loading