Best Kotest code snippet using io.kotest.matchers.paths.paths.Path.shouldBeADirectory
WhenDownloadingAwsDeviceFarmArtifacts.kt
Source:WhenDownloadingAwsDeviceFarmArtifacts.kt
1package io.github.ricardorlg.devicefarm.tractor.controller2import arrow.core.Either3import io.github.ricardorlg.devicefarm.tractor.model.*4import io.github.ricardorlg.devicefarm.tractor.stubs.*5import io.github.ricardorlg.devicefarm.tractor.tempFolder6import io.github.ricardorlg.devicefarm.tractor.utils.prettyName7import io.kotest.assertions.arrow.core.shouldBeLeft8import io.kotest.assertions.arrow.core.shouldBeRight9import io.kotest.assertions.fail10import io.kotest.assertions.withClue11import io.kotest.core.spec.style.StringSpec12import io.kotest.engine.spec.tempfile13import io.kotest.extensions.system.captureStandardOut14import io.kotest.inspectors.forAll15import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder16import io.kotest.matchers.paths.shouldBeADirectory17import io.kotest.matchers.paths.shouldContainFile18import io.kotest.matchers.paths.shouldContainNFiles19import io.kotest.matchers.paths.shouldNotContainFile20import io.kotest.matchers.should21import io.kotest.matchers.shouldBe22import io.kotest.matchers.string.shouldStartWith23import io.kotest.matchers.throwable.shouldHaveMessage24import io.kotest.matchers.types.shouldBeInstanceOf25import io.kotest.property.Exhaustive26import io.kotest.property.checkAll27import io.kotest.property.exhaustive.collection28import software.amazon.awssdk.services.devicefarm.model.Artifact29import software.amazon.awssdk.services.devicefarm.model.ArtifactType30import software.amazon.awssdk.services.devicefarm.model.Job31import software.amazon.awssdk.services.devicefarm.model.Run32import java.nio.file.AccessDeniedException33import java.nio.file.Paths34import java.nio.file.attribute.PosixFilePermissions35import kotlin.io.path.createDirectory36import kotlin.io.path.listDirectoryEntries37import kotlin.time.Duration38import kotlin.time.Duration.Companion.milliseconds39class WhenDownloadingAwsDeviceFarmArtifacts : StringSpec({40 val logger = MockedDeviceFarmLogging()41 val deviceFarmProjectsHandler = MockedDeviceFarmProjectsHandler()42 val devicePoolsHandler = MockedDeviceFarmDevicePoolsHandler()43 val uploadArtifactsHandler = MockedDeviceFarmUploadArtifactsHandler()44 val runScheduleHandler = MockedDeviceFarmRunsHandler()45 val commonArtifactsHandler = MockedDeviceFarmArtifactsHandler()46 val deviceName = "nexus 3"47 val artifactType = ArtifactType.CUSTOMER_ARTIFACT48 val downloadableTypes = listOf(ArtifactType.CUSTOMER_ARTIFACT, ArtifactType.VIDEO)49 val validTypes =50 ArtifactType.values().filter { it != ArtifactType.UNKNOWN && it != ArtifactType.UNKNOWN_TO_SDK_VERSION }51 "It should use a pretty name when the artifact type is video or customer artifact"{52 checkAll(Exhaustive.collection(ArtifactType.values().asList())) { type ->53 when (type) {54 ArtifactType.VIDEO -> type.prettyName() shouldBe "Recorded video"55 ArtifactType.CUSTOMER_ARTIFACT -> type.prettyName() shouldBe "Test reports"56 else -> type.prettyName() shouldBe type.name57 }58 }59 }60 "It should return a DeviceFarmTractorErrorIllegalArgumentException if the searched artifact type is not supported"{61 checkAll(Exhaustive.collection(INVALID_ARTIFACT_TYPES)) { type ->62 //GIVEN63 val customerArtifact = tempfile("test_downloadable_${type.name.lowercase()}_", ".zip")64 val destinyFolder = tempFolder("testReports")65 val artifact = Artifact66 .builder()67 .arn("arn:test:artifact")68 .name(customerArtifact.nameWithoutExtension)69 .extension(customerArtifact.extension)70 .type(artifactType)71 .url(customerArtifact.toURI().toASCIIString())72 .build()73 //WHEN74 val response = DefaultDeviceFarmTractorController(75 logger,76 deviceFarmProjectsHandler,77 devicePoolsHandler,78 uploadArtifactsHandler,79 runScheduleHandler,80 commonArtifactsHandler81 ).downloadAWSDeviceFarmArtifacts(82 artifacts = listOf(artifact),83 deviceName = deviceName,84 path = destinyFolder,85 artifactType = type86 )87 //THEN88 response.shouldBeLeft() should {89 it.shouldBeInstanceOf<DeviceFarmTractorErrorIllegalArgumentException>()90 it shouldHaveMessage "$type is not supported"91 }92 destinyFolder shouldNotContainFile customerArtifact.name93 destinyFolder shouldContainNFiles 094 }95 }96 "It should download an AWS Device farm artifact of a job execution depending of its type"{97 checkAll(Exhaustive.collection(validTypes)) { type ->98 //GIVEN99 val customerArtifact = tempfile("test_downloadable_${type.name.lowercase()}_", ".zip")100 val destinyFolder = tempFolder("testReports")101 val artifact = Artifact102 .builder()103 .arn("arn:test:artifact")104 .name(customerArtifact.nameWithoutExtension)105 .extension(customerArtifact.extension)106 .type(type)107 .url(customerArtifact.toURI().toASCIIString())108 .build()109 //WHEN110 val response = DefaultDeviceFarmTractorController(111 logger,112 deviceFarmProjectsHandler,113 devicePoolsHandler,114 uploadArtifactsHandler,115 runScheduleHandler,116 commonArtifactsHandler117 ).downloadAWSDeviceFarmArtifacts(118 artifacts = listOf(artifact),119 deviceName = deviceName,120 path = destinyFolder,121 artifactType = type122 )123 //THEN124 response.shouldBeRight()125 destinyFolder shouldContainFile customerArtifact.name126 destinyFolder shouldContainNFiles 1127 }128 }129 "It should log a message when the searched artifact type is not found in the job artifacts"{130 checkAll(Exhaustive.collection(validTypes)) { type ->131 //GIVEN132 val customerArtifact = tempfile("test_downloadable_${type.name.lowercase()}_", ".zip")133 val destinyFolder = tempFolder("testReports")134 val artifact = Artifact135 .builder()136 .arn("arn:test:artifact")137 .name(customerArtifact.nameWithoutExtension)138 .extension(customerArtifact.extension)139 .type(ArtifactType.UNKNOWN)140 .url(customerArtifact.toURI().toASCIIString())141 .build()142 val expectedLoggedMessage = JOB_DOES_NOT_HAVE_ARTIFACT_OF_TYPE.format(143 type.name,144 deviceName145 )146 //WHEN147 val loggedMessage = captureStandardOut {148 DefaultDeviceFarmTractorController(149 MockedDeviceFarmLogging(true),150 deviceFarmProjectsHandler,151 devicePoolsHandler,152 uploadArtifactsHandler,153 runScheduleHandler,154 commonArtifactsHandler155 ).downloadAWSDeviceFarmArtifacts(156 artifacts = listOf(artifact),157 deviceName = deviceName,158 path = destinyFolder,159 artifactType = type160 ).shouldBeRight()161 }.lines()162 .filter(String::isNotBlank)163 .map(String::trim)164 .last()165 //THEN166 loggedMessage shouldBe expectedLoggedMessage167 destinyFolder shouldNotContainFile customerArtifact.name168 destinyFolder shouldContainNFiles 0169 }170 }171 "It should return an ErrorDownloadingArtifact when there is a problem saving the artifact on disk"{172 //GIVEN173 val onlyReadDestinyFolderPermission = PosixFilePermissions.fromString("r--r--r--")174 val customerArtifact = tempfile("test_downloadable", ".zip")175 val destinyFolder =176 tempFolder("testReports", PosixFilePermissions.asFileAttribute(onlyReadDestinyFolderPermission))177 val artifact = Artifact178 .builder()179 .arn("arn:test:artifact")180 .name(customerArtifact.nameWithoutExtension)181 .extension(customerArtifact.extension)182 .type(ArtifactType.CUSTOMER_ARTIFACT)183 .url(customerArtifact.toURI().toASCIIString())184 .build()185 //WHEN186 val response = DefaultDeviceFarmTractorController(187 logger,188 deviceFarmProjectsHandler,189 devicePoolsHandler,190 uploadArtifactsHandler,191 runScheduleHandler,192 commonArtifactsHandler193 ).downloadAWSDeviceFarmArtifacts(194 artifacts = listOf(artifact),195 deviceName = deviceName,196 path = destinyFolder,197 artifactType = artifactType198 )199 //THEN200 response.shouldBeLeft() should {201 it.shouldBeInstanceOf<ErrorDownloadingArtifact>()202 it.cause.shouldBeInstanceOf<AccessDeniedException>()203 }204 }205 "It should not fail if there is no artifacts to download"{206 //GIVEN207 val customerArtifact = tempfile("test_downloadable", ".zip")208 val destinyFolder = tempFolder("testReports")209 //WHEN210 val response = DefaultDeviceFarmTractorController(211 logger,212 deviceFarmProjectsHandler,213 devicePoolsHandler,214 uploadArtifactsHandler,215 runScheduleHandler,216 commonArtifactsHandler217 ).downloadAWSDeviceFarmArtifacts(218 artifacts = emptyList(),219 deviceName = deviceName,220 path = destinyFolder,221 artifactType = artifactType222 )223 //THEN224 response.shouldBeRight()225 destinyFolder shouldNotContainFile customerArtifact.name226 destinyFolder shouldContainNFiles 0227 }228 "It should download all the test reports and recorded videos associated to the test Run"{229 //GIVEN230 val customerArtifactFile = tempfile("test_downloadable", ".zip")231 val recordedVideoFile = tempfile("test_video", ".mp4")232 val destinyFolder = tempFolder("testReports")233 val run = Run234 .builder()235 .name("test run")236 .arn("arn:test:run")237 .build()238 val jobs = (1..10)239 .map { job ->240 Job241 .builder()242 .arn("arn:test:job:$job")243 .name("test job $job")244 .device {245 it.name("Test device $job")246 .arn("arn:test:device:$job")247 }.build()248 }249 val customerArtifact = Artifact250 .builder()251 .arn("arn:test:customer_artifact")252 .name(customerArtifactFile.nameWithoutExtension)253 .extension(customerArtifactFile.extension)254 .type(ArtifactType.CUSTOMER_ARTIFACT)255 .url(customerArtifactFile.toURI().toASCIIString())256 .build()257 val recordedVideoArtifact = Artifact258 .builder()259 .arn("arn:test:video_artifact")260 .name(recordedVideoFile.nameWithoutExtension)261 .extension(recordedVideoFile.extension)262 .type(ArtifactType.VIDEO)263 .url(recordedVideoFile.toURI().toASCIIString())264 .build()265 val downloadArtifactsHandler = MockedDeviceFarmArtifactsHandler(266 getArtifactsImpl = { Either.Right(listOf(customerArtifact, recordedVideoArtifact)) }267 )268 val runHandler = MockedDeviceFarmRunsHandler(269 getAssociatedJobsImpl = { Either.Right(jobs) }270 )271 val reportDirectoryPath = Paths.get("test_reports_${run.name().lowercase().replace("\\s".toRegex(), "_")}")272 //WHEN273 DefaultDeviceFarmTractorController(274 logger,275 deviceFarmProjectsHandler,276 devicePoolsHandler,277 uploadArtifactsHandler,278 runHandler,279 downloadArtifactsHandler280 ).downloadAllEvidencesOfTestRun(run, destinyFolder, 0.milliseconds)281 //THEN282 destinyFolder shouldContainFile reportDirectoryPath.toFile().name283 destinyFolder shouldContainNFiles 1284 destinyFolder.resolve(reportDirectoryPath).shouldBeADirectory()285 destinyFolder.resolve(reportDirectoryPath) shouldContainNFiles jobs.size286 destinyFolder.resolve(reportDirectoryPath).listDirectoryEntries().forAll {287 it.shouldBeADirectory()288 it shouldContainFile customerArtifactFile.name289 it shouldContainFile recordedVideoFile.name290 it shouldContainNFiles 2291 }292 }293 "It should log an error message when downloading a recorded video or test report fails"{294 checkAll(Exhaustive.collection(downloadableTypes)) { type ->295 //GIVEN296 val testFile = tempfile("test_downloadable_${type.name.lowercase()}", ".zip")297 val destinyFolder = tempFolder("testReports")298 val run = Run299 .builder()300 .name("test run")301 .arn("arn:test:run")302 .build()303 val job = Job304 .builder()305 .arn("arn:test:job")306 .name("test job")307 .device {308 it.name(deviceName)309 .arn("arn:test:device")310 }.build()311 val artifact = Artifact312 .builder()313 .arn("arn:test:artifact")314 .name(testFile.nameWithoutExtension)315 .extension(testFile.extension)316 .type(type)317 .url(testFile.toURI().toASCIIString())318 .build()319 val downloadArtifactsHandler = MockedDeviceFarmArtifactsHandler(320 getArtifactsImpl = { Either.Right(listOf(artifact)) }321 )322 val runHandler = MockedDeviceFarmRunsHandler(323 getAssociatedJobsImpl = { Either.Right(listOf(job)) }324 )325 val reportDirectoryPath =326 Paths.get("test_reports_${run.name().lowercase().replace("\\s".toRegex(), "_")}")327 testFile.setReadable(false)328 //WHEN329 val loggedMessages = captureStandardOut {330 DefaultDeviceFarmTractorController(331 MockedDeviceFarmLogging(true),332 deviceFarmProjectsHandler,333 devicePoolsHandler,334 uploadArtifactsHandler,335 runHandler,336 downloadArtifactsHandler337 ).downloadAllEvidencesOfTestRun(run, destinyFolder, 0.milliseconds)338 }.lineSequence()339 .filter(String::isNotBlank)340 .map(String::trim)341 //THEN342 destinyFolder shouldContainNFiles 1343 destinyFolder shouldContainFile reportDirectoryPath.fileName.toString()344 destinyFolder.resolve(reportDirectoryPath).shouldBeADirectory()345 destinyFolder.resolve(reportDirectoryPath) shouldContainNFiles 0346 withClue("The logged messages should contain an error message related to the error downloading the artifact $type") {347 loggedMessages.any {348 it.startsWith(349 "There was an error downloading the ${350 type.prettyName()351 } of $deviceName test run."352 )353 }354 }355 }356 }357 "It should download all the reports even if any of them fails"{358 //GIVEN359 val expectedReports = (1..10)360 .map {361 tempfile("test_report_${it}_downloadable", ".zip")362 }363 val reportNotReadable = expectedReports.random()364 if (!reportNotReadable.setReadable(false)) fail("An error happens setting up the test")365 val destinyFolder = tempFolder("testReports")366 val run = Run367 .builder()368 .name("test run")369 .arn("arn:test:run")370 .build()371 val jobs = (1..10)372 .map { job ->373 Job374 .builder()375 .arn("arn:test:job:$job")376 .name("test job $job")377 .device {378 it.name("Test device $job")379 .arn("arn:test:device:$job")380 }.build()381 }382 val artifacts = expectedReports383 .mapIndexed { index, associatedReport ->384 Artifact385 .builder()386 .arn("arn:test:artifact:$index")387 .name(associatedReport.nameWithoutExtension)388 .extension(associatedReport.extension)389 .type(ArtifactType.CUSTOMER_ARTIFACT)390 .url(associatedReport.toURI().toASCIIString())391 .build()392 }393 val artifactsProvider = artifacts.iterator()394 val downloadArtifactsHandler = MockedDeviceFarmArtifactsHandler(395 getArtifactsImpl = {396 synchronized(this) {397 Either.Right(listOf(artifactsProvider.next()))398 }399 }400 )401 val runHandler = MockedDeviceFarmRunsHandler(402 getAssociatedJobsImpl = { Either.Right(jobs) }403 )404 val reportDirectoryPath = Paths.get("test_reports_${run.name().lowercase().replace("\\s".toRegex(), "_")}")405 //WHEN406 DefaultDeviceFarmTractorController(407 logger,408 deviceFarmProjectsHandler,409 devicePoolsHandler,410 uploadArtifactsHandler,411 runHandler,412 downloadArtifactsHandler413 ).downloadAllEvidencesOfTestRun(run, destinyFolder, 0.milliseconds)414 //THEN415 destinyFolder shouldContainFile reportDirectoryPath.fileName.toString()416 destinyFolder shouldContainNFiles 1417 destinyFolder.resolve(reportDirectoryPath).shouldBeADirectory()418 destinyFolder.resolve(reportDirectoryPath) shouldContainNFiles jobs.size - 1419 destinyFolder420 .resolve(reportDirectoryPath)421 .listDirectoryEntries()422 .flatMap {423 it.listDirectoryEntries()424 }425 .map { it.fileName }426 .shouldContainExactlyInAnyOrder(427 expectedReports428 .filter { it != reportNotReadable }429 .map { it.toPath().fileName }430 )431 }432 "It should download all the recorded videos even if any of them fails"{433 //GIVEN434 val expectedRecordedVideos = (1..10)435 .map {436 tempfile("recorde_video_${it}_downloadable", ".mp4")437 }438 val recordedVideoNotReadable = expectedRecordedVideos.random()439 if (!recordedVideoNotReadable.setReadable(false)) fail("An error happens setting up the test")440 val destinyFolder = tempFolder("testResults")441 val run = Run442 .builder()443 .name("test run")444 .arn("arn:test:run")445 .build()446 val jobs = (1..10)447 .map { job ->448 Job449 .builder()450 .arn("arn:test:job:$job")451 .name("test job $job")452 .device {453 it.name("Test device $job")454 .arn("arn:test:device:$job")455 }.build()456 }457 val artifacts = expectedRecordedVideos458 .mapIndexed { index, associatedVideo ->459 Artifact460 .builder()461 .arn("arn:test:artifact:$index")462 .name(associatedVideo.nameWithoutExtension)463 .extension(associatedVideo.extension)464 .type(ArtifactType.VIDEO)465 .url(associatedVideo.toURI().toASCIIString())466 .build()467 }468 val artifactsProvider = artifacts.iterator()469 val downloadArtifactsHandler = MockedDeviceFarmArtifactsHandler(470 getArtifactsImpl = {471 synchronized(this) {472 Either.Right(listOf(artifactsProvider.next()))473 }474 }475 )476 val runHandler = MockedDeviceFarmRunsHandler(477 getAssociatedJobsImpl = { Either.Right(jobs) }478 )479 val reportDirectoryPath = Paths.get("test_reports_${run.name().lowercase().replace("\\s".toRegex(), "_")}")480 //WHEN481 DefaultDeviceFarmTractorController(482 logger,483 deviceFarmProjectsHandler,484 devicePoolsHandler,485 uploadArtifactsHandler,486 runHandler,487 downloadArtifactsHandler488 ).downloadAllEvidencesOfTestRun(run, destinyFolder, 0.milliseconds)489 //THEN490 destinyFolder shouldContainFile reportDirectoryPath.fileName.toString()491 destinyFolder shouldContainNFiles 1492 destinyFolder.resolve(reportDirectoryPath).shouldBeADirectory()493 destinyFolder.resolve(reportDirectoryPath) shouldContainNFiles jobs.size - 1494 destinyFolder495 .resolve(reportDirectoryPath)496 .listDirectoryEntries()497 .flatMap {498 it.listDirectoryEntries()499 }500 .map { it.fileName }501 .shouldContainExactlyInAnyOrder(502 expectedRecordedVideos503 .filter { it != recordedVideoNotReadable }504 .map { it.toPath().fileName }505 )506 }507 "It should log an error message when creating the test report directory of an specific device fails"{508 //GIVEN509 val destinyFolder = tempFolder("testReports")510 val run = Run511 .builder()512 .name("test run")513 .arn("arn:test:run")514 .build()515 val job = Job516 .builder()517 .arn("arn:test:job")518 .name("test job")519 .device {520 it.name(deviceName)521 .arn("arn:test:device")522 }.build()523 val downloadArtifactsHandler = MockedDeviceFarmArtifactsHandler(524 getArtifactsImpl = { fail("This should never been called") }525 )526 val runHandler = MockedDeviceFarmRunsHandler(527 getAssociatedJobsImpl = { Either.Right(listOf(job)) }528 )529 val reportDirectoryPath = destinyFolder530 .resolve("test_reports_${run.name().lowercase().replace("\\s".toRegex(), "_")}")531 .createDirectory()532 //WHEN533 val lastOutput = captureStandardOut {534 DefaultDeviceFarmTractorController(535 MockedDeviceFarmLogging(true),536 deviceFarmProjectsHandler,537 devicePoolsHandler,538 uploadArtifactsHandler,539 runHandler,540 downloadArtifactsHandler541 ).downloadAllEvidencesOfTestRun(run, destinyFolder, 0.milliseconds)542 }.lineSequence()543 .filter(String::isNotBlank)544 .map(String::trim)545 .last()546 //THEN547 reportDirectoryPath shouldContainNFiles 0548 lastOutput shouldStartWith "There was a problem creating the folder ${reportDirectoryPath.fileName}"549 }550 "It should log an error message when creating the test reports directory fails"{551 //GIVEN552 val destinyFolder = tempFolder("testReports")553 val run = Run554 .builder()555 .name("test run")556 .arn("arn:test:run")557 .build()558 val job = Job559 .builder()560 .arn("arn:test:job")561 .name("test job")562 .device {563 it.name(deviceName)564 .arn("arn:test:device")565 }.build()566 val downloadArtifactsHandler = MockedDeviceFarmArtifactsHandler(567 getArtifactsImpl = { fail("This should never been called") }568 )569 val runHandler = MockedDeviceFarmRunsHandler(570 getAssociatedJobsImpl = { Either.Right(listOf(job)) }571 )572 val testReportsName = "test_reports_${run.name().lowercase().replace("\\s".toRegex(), "_")}"573 destinyFolder.toFile().setReadOnly()574 //WHEN575 val lastOutput = captureStandardOut {576 DefaultDeviceFarmTractorController(577 MockedDeviceFarmLogging(true),578 deviceFarmProjectsHandler,579 devicePoolsHandler,580 uploadArtifactsHandler,581 runHandler,582 downloadArtifactsHandler583 ).downloadAllEvidencesOfTestRun(run, destinyFolder, 0.milliseconds)584 }.lineSequence()585 .filter(String::isNotBlank)586 .map(String::trim)587 .last()588 //THEN589 destinyFolder shouldContainNFiles 0590 lastOutput shouldStartWith "There was a problem creating the folder $testReportsName"591 }592 "It should not try to download the reports when an error happens fetching the associated jobs of the test run"{593 //GIVEN594 val destinyFolder = tempFolder("testReports")595 val error = DeviceFarmTractorGeneralError(RuntimeException("test error"))596 val run = Run597 .builder()598 .name("test run")599 .arn("arn:test:run")600 .build()601 val downloadArtifactsHandler = MockedDeviceFarmArtifactsHandler(602 getArtifactsImpl = { fail("This should never been called") }603 )604 val runHandler = MockedDeviceFarmRunsHandler(605 getAssociatedJobsImpl = { Either.Left(error) }606 )607 //WHEN608 DefaultDeviceFarmTractorController(609 logger,610 deviceFarmProjectsHandler,611 devicePoolsHandler,612 uploadArtifactsHandler,613 runHandler,614 downloadArtifactsHandler615 ).downloadAllEvidencesOfTestRun(run, destinyFolder, 0.milliseconds)616 //THEN617 destinyFolder shouldContainNFiles 0618 }619 "It should download the recorded videos and test reports even if any of them fails"{620 //GIVEN621 val expectedReports = (1..10)622 .map {623 tempfile("test_report_${it}_downloadable", ".zip")624 }625 val expectedRecordedVideos = (1..10)626 .map {627 tempfile("test_video_${it}_downloadable", ".mp4")628 }629 val reportNotReadable = expectedReports.random()630 val videoNotReadable = expectedRecordedVideos.random()631 if (!reportNotReadable.setReadable(false)) fail("An error happens setting up the test")632 if (!videoNotReadable.setReadable(false)) fail("An error happens setting up the test")633 val destinyFolder = tempFolder("testReports")634 val run = Run635 .builder()636 .name("test run")637 .arn("arn:test:run")638 .build()639 val jobs = (1..10)640 .map { job ->641 Job642 .builder()643 .arn("arn:test:job:$job")644 .name("test job $job")645 .device {646 it.name("Test device $job")647 .arn("arn:test:device:$job")648 }.build()649 }650 val customerArtifacts = expectedReports651 .mapIndexed { index, associatedReport ->652 Artifact653 .builder()654 .arn("arn:test:customer_artifact:$index")655 .name(associatedReport.nameWithoutExtension)656 .extension(associatedReport.extension)657 .type(ArtifactType.CUSTOMER_ARTIFACT)658 .url(associatedReport.toURI().toASCIIString())659 .build()660 }661 val videoArtifacts = expectedRecordedVideos662 .mapIndexed { index, associatedVideo ->663 Artifact664 .builder()665 .arn("arn:test:video_artifact:$index")666 .name(associatedVideo.nameWithoutExtension)667 .extension(associatedVideo.extension)668 .type(ArtifactType.VIDEO)669 .url(associatedVideo.toURI().toASCIIString())670 .build()671 }672 val customerArtifactsProvider = customerArtifacts.iterator()673 val videoArtifactsProvider = videoArtifacts.iterator()674 val downloadArtifactsHandler = MockedDeviceFarmArtifactsHandler(675 getArtifactsImpl = {676 synchronized(this) {677 Either.Right(listOf(customerArtifactsProvider.next(), videoArtifactsProvider.next()))678 }679 }680 )681 val runHandler = MockedDeviceFarmRunsHandler(682 getAssociatedJobsImpl = { Either.Right(jobs) }683 )684 val reportDirectoryPath = Paths.get("test_reports_${run.name().lowercase().replace("\\s".toRegex(), "_")}")685 val expectedFiles = expectedReports686 .filter { it != reportNotReadable }687 .map { it.toPath().fileName } + expectedRecordedVideos688 .filter { it != videoNotReadable }689 .map { it.toPath().fileName }690 val expectedFilesSize =691 if (expectedReports.indexOf(reportNotReadable) == expectedRecordedVideos.indexOf(videoNotReadable)) jobs.size - 1 else jobs.size692 //WHEN693 DefaultDeviceFarmTractorController(694 logger,695 deviceFarmProjectsHandler,696 devicePoolsHandler,697 uploadArtifactsHandler,698 runHandler,699 downloadArtifactsHandler700 ).downloadAllEvidencesOfTestRun(run, destinyFolder, 0.milliseconds)701 //THEN702 destinyFolder shouldContainFile reportDirectoryPath.fileName.toString()703 destinyFolder shouldContainNFiles 1704 destinyFolder.resolve(reportDirectoryPath).shouldBeADirectory()705 destinyFolder.resolve(reportDirectoryPath) shouldContainNFiles expectedFilesSize706 destinyFolder707 .resolve(reportDirectoryPath)708 .listDirectoryEntries()709 .flatMap {710 it.listDirectoryEntries()711 }712 .map { it.fileName }713 .shouldContainExactlyInAnyOrder(expectedFiles)714 }715})...
FileMatchersTest.kt
Source:FileMatchersTest.kt
1package com.sksamuel.kotest.matchers.file2import io.kotest.assertions.throwables.shouldThrow3import io.kotest.core.spec.style.FunSpec4import io.kotest.matchers.file.aDirectory5import io.kotest.matchers.file.aFile6import io.kotest.matchers.file.beAbsolute7import io.kotest.matchers.file.beRelative8import io.kotest.matchers.file.exist9import io.kotest.matchers.file.haveExtension10import io.kotest.matchers.file.shouldBeADirectory11import io.kotest.matchers.file.shouldBeAFile12import io.kotest.matchers.file.shouldBeAbsolute13import io.kotest.matchers.file.shouldBeEmptyDirectory14import io.kotest.matchers.file.shouldBeRelative15import io.kotest.matchers.file.shouldBeSymbolicLink16import io.kotest.matchers.file.shouldExist17import io.kotest.matchers.file.shouldHaveExtension18import io.kotest.matchers.file.shouldHaveParent19import io.kotest.matchers.file.shouldHaveSameStructureAs20import io.kotest.matchers.file.shouldHaveSameStructureAndContentAs21import io.kotest.matchers.file.shouldNotBeADirectory22import io.kotest.matchers.file.shouldNotBeAFile23import io.kotest.matchers.file.shouldNotBeEmptyDirectory24import io.kotest.matchers.file.shouldNotBeSymbolicLink25import io.kotest.matchers.file.shouldNotExist26import io.kotest.matchers.file.shouldNotHaveExtension27import io.kotest.matchers.file.shouldNotHaveParent28import io.kotest.matchers.file.shouldStartWithPath29import io.kotest.matchers.file.startWithPath30import io.kotest.matchers.paths.shouldBeLarger31import io.kotest.matchers.paths.shouldBeSmaller32import io.kotest.matchers.paths.shouldBeSymbolicLink33import io.kotest.matchers.paths.shouldContainFile34import io.kotest.matchers.paths.shouldContainFileDeep35import io.kotest.matchers.paths.shouldContainFiles36import io.kotest.matchers.paths.shouldHaveParent37import io.kotest.matchers.paths.shouldNotBeSymbolicLink38import io.kotest.matchers.paths.shouldNotContainFile39import io.kotest.matchers.paths.shouldNotContainFileDeep40import io.kotest.matchers.paths.shouldNotContainFiles41import io.kotest.matchers.paths.shouldNotHaveParent42import io.kotest.matchers.should43import io.kotest.matchers.shouldBe44import io.kotest.matchers.shouldNot45import io.kotest.matchers.string.shouldEndWith46import io.kotest.matchers.string.shouldMatch47import java.io.File48import java.nio.file.Files49import java.nio.file.Paths50import org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS51@Suppress("BlockingMethodInNonBlockingContext")52class FileMatchersTest : FunSpec() {53 init {54 test("relative() should match only relative files") {55 File("sammy/boy") shouldBe beRelative()56 File("sammy/boy").shouldBeRelative()57 }58 test("absolute() should match only absolute files") {59 val root = if (IS_OS_WINDOWS) "C:/" else "/"60 File("${root}sammy/boy") shouldBe beAbsolute()61 File("${root}sammy/boy").shouldBeAbsolute()62 }63 test("startWithPath() should only match files that start with the given path") {64 File("sammy/boy") should startWithPath("sammy")65 File("sammy/boy") should startWithPath(Paths.get("sammy"))66 File("/sammy/boy") should startWithPath("${File.separator}sammy")67 File("/sammy/boy") should startWithPath(Paths.get("/sammy"))68 File("/sammy/boy").shouldStartWithPath("${File.separator}sammy")69 File("/sammy/boy").shouldStartWithPath(Paths.get("/sammy"))70 }71 test("exist() file matcher") {72 val file = Files.createTempFile("test", "test").toFile()73 file should exist()74 shouldThrow<AssertionError> {75 File("qweqwewqewqewee") should exist()76 }.message shouldBe "File qweqwewqewqewee should exist"77 file.shouldExist()78 shouldThrow<AssertionError> {79 file.shouldNotExist()80 }81 file.delete()82 }83 test("haveExtension") {84 val file = Files.createTempFile("test", ".test").toFile()85 file should haveExtension(".test")86 file shouldNot haveExtension(".wibble")87 shouldThrow<AssertionError> {88 file should haveExtension(".jpeg")89 }.message.shouldEndWith("with one of .jpeg")90 shouldThrow<AssertionError> {91 file.shouldHaveExtension(".jpeg")92 }.message.shouldEndWith("with one of .jpeg")93 file.shouldHaveExtension(".test")94 file.shouldNotHaveExtension(".wibble")95 file.delete()96 }97 test("aFile() file matcher") {98 val file = Files.createTempFile("test", "test").toFile()99 file shouldBe aFile()100 file.shouldBeAFile()101 shouldThrow<AssertionError> {102 file shouldBe aDirectory()103 }104 shouldThrow<AssertionError> {105 file.shouldNotBeAFile()106 }107 shouldThrow<AssertionError> {108 file.shouldBeADirectory()109 }110 file.delete()111 }112 test("aDirectory() file matcher") {113 val dir = Files.createTempDirectory("testdir").toFile()114 dir shouldBe aDirectory()115 dir.shouldBeADirectory()116 shouldThrow<AssertionError> {117 dir shouldBe aFile()118 }119 shouldThrow<AssertionError> {120 dir.shouldNotBeADirectory()121 }122 shouldThrow<AssertionError> {123 dir shouldBe aFile()124 }125 }126 test("directory should be empty (deprecated)") {127 val dir = Files.createTempDirectory("testdir").toFile()128 dir.shouldBeEmptyDirectory()129 dir.resolve("testfile.txt").writeBytes(byteArrayOf(1, 2, 3))130 dir.shouldNotBeEmptyDirectory()131 }132 test("directory should be empty") {133 val dir = Files.createTempDirectory("testdir").toFile()134 dir.shouldBeEmptyDirectory()135 dir.resolve("testfile.txt").writeBytes(byteArrayOf(1, 2, 3))136 dir.shouldNotBeEmptyDirectory()137 }138 test("directory contains file matching predicate") {139 val dir = Files.createTempDirectory("testdir")140 dir.resolve("a").toFile().createNewFile()141 dir.resolve("b").toFile().createNewFile()142 dir.shouldContainFile("a")143 dir.shouldNotContainFile("c")144 shouldThrow<AssertionError> {145 dir.shouldContainFile("c")146 }.message?.shouldMatch("^Directory .+ should contain a file with filename c \\(detected 2 other files\\)$".toRegex())147 }148 test("beSmaller should compare file sizes") {149 val dir = Files.createTempDirectory("testdir")150 Files.write(dir.resolve("a"), byteArrayOf(1, 2))151 Files.write(dir.resolve("b"), byteArrayOf(1, 2, 3))152 dir.resolve("a").shouldBeSmaller(dir.resolve("b"))153 shouldThrow<AssertionError> {154 dir.resolve("b").shouldBeSmaller(dir.resolve("a"))155 }.message shouldBe "Path ${dir.resolve("b")} (3 bytes) should be smaller than ${dir.resolve("a")} (2 bytes)"156 }157 test("beLarger should compare file sizes") {158 val dir = Files.createTempDirectory("testdir")159 Files.write(dir.resolve("a"), byteArrayOf(1, 2, 3))160 Files.write(dir.resolve("b"), byteArrayOf(1, 2))161 dir.resolve("a").shouldBeLarger(dir.resolve("b"))162 shouldThrow<AssertionError> {163 dir.resolve("b").shouldBeLarger(dir.resolve("a"))164 }.message shouldBe "File ${dir.resolve("b")} (2 bytes) should be larger than ${dir.resolve("a")} (3 bytes)"165 }166 test("containsFileDeep should find file deep") {167 val rootFileName = "super_dooper_hyper_file_root"168 val innerFileName = "super_dooper_hyper_file_inner"169 val nonExistentFileName = "super_dooper_hyper_non_existent_file"170 val rootDir = Files.createTempDirectory("testdir")171 val innerDir = Files.createDirectories(rootDir.resolve("innerfolder"))172 Files.write(rootDir.resolve(rootFileName), byteArrayOf(1, 2, 3))173 Files.write(innerDir.resolve(innerFileName), byteArrayOf(1, 2, 3))174 rootDir.shouldContainFileDeep(rootFileName)175 rootDir.shouldContainFileDeep(innerFileName)176 shouldThrow<AssertionError> {177 rootDir.shouldContainFileDeep(nonExistentFileName)178 }.message shouldBe "Path $nonExistentFileName should exist in $rootDir"179 shouldThrow<AssertionError> {180 rootDir.shouldNotContainFileDeep(rootFileName)181 }.message shouldBe "Path $rootFileName should not exist in $rootDir"182 }183 test("shouldContainFiles should check if files exists") {184 val testDir = Files.createTempDirectory("testdir")185 Files.write(testDir.resolve("a.txt"), byteArrayOf(1, 2, 3))186 Files.write(testDir.resolve("b.gif"), byteArrayOf(1, 2, 3))187 Files.write(testDir.resolve("c.doc"), byteArrayOf(1, 2, 3))188 testDir.shouldContainFiles("a.txt", "b.gif", "c.doc")189 testDir.shouldNotContainFiles("d.txt", "e.gif", "f.doc")190 shouldThrow<AssertionError> {191 testDir.shouldContainFiles("d.txt")192 }.message shouldBe "File d.txt should exist in $testDir"193 shouldThrow<AssertionError> {194 testDir.shouldContainFiles("d.txt", "e.gif")195 }.message shouldBe "Files d.txt, e.gif should exist in $testDir"196 shouldThrow<AssertionError> {197 testDir.shouldNotContainFiles("a.txt")198 }.message shouldBe "File a.txt should not exist in $testDir"199 shouldThrow<AssertionError> {200 testDir.shouldNotContainFiles("a.txt", "b.gif")201 }.message shouldBe "Files a.txt, b.gif should not exist in $testDir"202 }203 test("shouldBeSymbolicLink should check if file is symbolic link").config(enabled = isNotWindowsOrIsWindowsElevated()) {204 val testDir = Files.createTempDirectory("testdir")205 val existingFile = Files.write(testDir.resolve("original.txt"), byteArrayOf(1, 2, 3, 4))206 val existingFileAsFile = existingFile.toFile()207 val link = Files.createSymbolicLink(testDir.resolve("a.txt"), existingFile)208 val linkAsFile = link.toFile()209 link.shouldBeSymbolicLink()210 linkAsFile.shouldBeSymbolicLink()211 existingFile.shouldNotBeSymbolicLink()212 existingFileAsFile.shouldNotBeSymbolicLink()213 }214 test("shouldHaveParent should check if file has any parent with given name") {215 val testDir = Files.createTempDirectory("testdir")216 val subdir = Files.createDirectory(testDir.resolve("sub_testdir"))217 val file = Files.write(subdir.resolve("a.txt"), byteArrayOf(1, 2, 3, 4))218 val fileAsFile = file.toFile()219 file.shouldHaveParent(testDir.toFile().name)220 file.shouldHaveParent(subdir.toFile().name)221 file.shouldNotHaveParent("super_hyper_long_random_file_name")222 fileAsFile.shouldHaveParent(testDir.toFile().name)223 fileAsFile.shouldHaveParent(subdir.toFile().name)224 fileAsFile.shouldNotHaveParent("super_hyper_long_random_file_name")225 }226 test("shouldHaveSameStructureAs and shouldHaveSameStructureAndContentAs two file trees") {227 val testDir = Files.createTempDirectory("testdir")228 val expectDir = File("$testDir/expect").apply {229 File("$this/a.txt").createWithContent(byteArrayOf(1, 2, 3))230 File("$this/b.txt").createWithContent(byteArrayOf(1, 2, 3, 4))231 File("$this/subfolder/b.txt").createWithContent(byteArrayOf(1, 2, 3, 4))232 File("$this/subfolder/subfolder-two/c.txt").createWithContent(byteArrayOf(1, 2))233 }234 val actualDir = File("$testDir/actual").apply {235 File("$this/a.txt").createWithContent(byteArrayOf(1, 2, 3))236 File("$this/b.txt").createWithContent(byteArrayOf(1, 2, 3, 4))237 File("$this/subfolder/b.txt").createWithContent(byteArrayOf(1, 2, 3, 4))238 File("$this/subfolder/subfolder-two/c.txt").createWithContent(byteArrayOf(1, 2))239 }240 expectDir shouldHaveSameStructureAs actualDir241 expectDir shouldHaveSameStructureAndContentAs actualDir242 File("$expectDir/z.txt").createWithContent(byteArrayOf(1, 2, 3))243 shouldThrow<AssertionError> { expectDir shouldHaveSameStructureAs actualDir }244 shouldThrow<AssertionError> { expectDir shouldHaveSameStructureAndContentAs actualDir }245 File("$actualDir/z.txt").createWithContent(byteArrayOf(1, 2, 3, 4))246 expectDir shouldHaveSameStructureAs actualDir247 shouldThrow<AssertionError> { expectDir shouldHaveSameStructureAndContentAs actualDir }248 }249 test("shouldHaveSameStructureAs with filter should check if two file trees are the same and files have the same content") {250 val testDir = Files.createTempDirectory("testdir")251 val expectDir = File("$testDir/expect").apply {252 File("$this/a.txt").createWithContent("a/b")253 File("$this/b.txt").createWithContent("b/c")254 File("$this/subfolder/b.txt").createWithContent("b/c")255 File("$this/subfolder/subfolder-two/c.txt").createWithContent("c/d")256 File("$this/z.txt").createWithContent("z")257 }258 val actualDir = File("$testDir/actual").apply {259 File("$this/a.txt").createWithContent("a/b")260 File("$this/b.txt").createWithContent("b/c")261 File("$this/subfolder/b.txt").createWithContent("b/c")262 File("$this/subfolder/subfolder-two/c.txt").createWithContent("c/d")263 File("$this/z.txt").createWithContent("zz")264 }265 expectDir.shouldHaveSameStructureAs(actualDir, filterLhs = { it.name == "z.txt" })266 expectDir.shouldHaveSameStructureAs(actualDir, filterRhs = { it.name == "z.txt" })267 }268 test("shouldHaveSameStructureAndContentAs with compare and filter should check if two file trees are the same and files have the same content") {269 val testDir = Files.createTempDirectory("testdir")270 val expectDir = File("$testDir/expect").apply {271 File("$this/a.txt").createWithContent("a/b")272 File("$this/b.txt").createWithContent("b/c")273 File("$this/subfolder/b.txt").createWithContent("b/c")274 File("$this/subfolder/subfolder-two/c.txt").createWithContent("c/d")275 }276 val actualDir = File("$testDir/actual").apply {277 File("$this/a.txt").createWithContent("a/b")278 File("$this/b.txt").createWithContent("b\\c")279 File("$this/subfolder/b.txt").createWithContent("b\\c")280 File("$this/subfolder/subfolder-two/c.txt").createWithContent("c\\d")281 }282 expectDir.shouldHaveSameStructureAs(actualDir) { a, b ->283 a.isFile && b.isFile && a.readText() == b.readText().replace("\\", "/")284 }285 expectDir.shouldHaveSameStructureAndContentAs(actualDir, filterLhs = { it.name != "a.txt" })286 expectDir.shouldHaveSameStructureAndContentAs(actualDir, filterRhs = { it.name != "a.txt" })287 }288 }289}290private fun File.createWithContent(content: String) {291 this.parentFile.mkdirs()292 createNewFile()293 writeText(content)294}295private fun File.createWithContent(content: ByteArray) {296 this.parentFile.mkdirs()297 createNewFile()298 writeBytes(content)299}300private fun isNotWindowsOrIsWindowsElevated(): Boolean {301 return if (!IS_OS_WINDOWS) {302 true303 } else {304 try {305 val p = Runtime.getRuntime().exec("""reg query "HKU\S-1-5-19"""")306 p.waitFor()307 0 == p.exitValue()308 } catch (ex: Exception) {309 println("Failed to determine if process had elevated permissions, assuming it does not.")310 false311 }312 }313}...
matchers.kt
Source:matchers.kt
1package io.kotest.matchers.file2import io.kotest.matchers.Matcher3import io.kotest.matchers.MatcherResult4import io.kotest.matchers.collections.shouldBeSameSizeAs5import io.kotest.matchers.paths.beSymbolicLink6import io.kotest.matchers.should7import io.kotest.matchers.shouldBe8import io.kotest.matchers.shouldNot9import io.kotest.matchers.shouldNotBe10import java.io.File11import java.io.FileFilter12import java.nio.file.Path13private fun File.safeList(): List<String> = this.list()?.toList() ?: emptyList()14private fun File.safeListFiles(): List<File> = this.listFiles()?.toList() ?: emptyList()15private fun File.safeListFiles(filter: FileFilter): List<File> = this.listFiles(filter)?.toList() ?: emptyList()16fun File.shouldBeEmptyDirectory() = this should beEmptyDirectory()17fun File.shouldNotBeEmptyDirectory() = this shouldNot beEmptyDirectory()18fun beEmptyDirectory(): Matcher<File> = object : Matcher<File> {19 override fun test(value: File): MatcherResult {20 val contents = if (value.isDirectory) value.safeList() else emptyList()21 return MatcherResult(22 contents.isEmpty(),23 { "$value should be an empty directory but contained ${contents.size} file(s) [${contents.joinToString(", ")}]" },24 { "$value should not be a non empty directory" }25 )26 }27}28infix fun File.shouldContainNFiles(n: Int) = this shouldBe containNFiles(n)29infix fun File.shouldNotContainNFiles(n: Int) = this shouldNotBe containNFiles(n)30fun containNFiles(n: Int): Matcher<File> = object : Matcher<File> {31 override fun test(value: File): MatcherResult = MatcherResult(32 value.isDirectory && value.safeList().size == n,33 { "$value should be a directory and contain $n files" },34 { "$value should not be a directory containing $n files" }35 )36}37fun File.shouldBeEmpty() = this shouldBe emptyFile()38fun File.shouldNotBeEmpty() = this shouldNotBe emptyFile()39fun emptyFile(): Matcher<File> = object : Matcher<File> {40 override fun test(value: File): MatcherResult =41 MatcherResult(42 value.length() == 0L,43 { "File $value should be empty" },44 { "File $value should not be empty" }45 )46}47fun File.shouldExist() = this should exist()48fun File.shouldNotExist() = this shouldNot exist()49fun exist() = object : Matcher<File> {50 override fun test(value: File) =51 MatcherResult(52 value.exists(),53 { "File $value should exist" },54 { "File $value should not exist" }55 )56}57infix fun File.shouldContainFile(name: String) = this should containFile(name)58infix fun File.shouldNotContainFile(name: String) = this shouldNot containFile(name)59fun containFile(name: String) = object : Matcher<File> {60 override fun test(value: File): MatcherResult {61 val contents = value.safeList()62 val passed = value.isDirectory && contents.contains(name)63 return MatcherResult(64 passed,65 { "Directory $value should contain a file with filename $name (detected ${contents.size} other files)" },66 { "Directory $value should not contain a file with filename $name" }67 )68 }69}70fun File.shouldBeSymbolicLink() = this.toPath() should beSymbolicLink()71fun File.shouldNotBeSymbolicLink() = this.toPath() shouldNot beSymbolicLink()72infix fun File.shouldHaveParent(name: String) = this should haveParent(name)73infix fun File.shouldNotHaveParent(name: String) = this shouldNot haveParent(name)74fun haveParent(name: String) = object : Matcher<File> {75 private fun isParentEqualExpected(parent: File?): Boolean =76 parent != null && (parent.name == name || isParentEqualExpected(parent.parentFile))77 override fun test(value: File) = MatcherResult(78 isParentEqualExpected(value.parentFile),79 { "File $value should have parent $name" },80 { "File $value should not have parent $name" }81 )82}83fun File.shouldBeADirectory() = this should aDirectory()84fun File.shouldNotBeADirectory() = this shouldNot aDirectory()85fun aDirectory(): Matcher<File> = object : Matcher<File> {86 override fun test(value: File): MatcherResult = MatcherResult(87 value.isDirectory,88 { "File $value should be a directory" },89 { "File $value should not be a directory" }90 )91}92fun File.shouldBeAFile() = this should aFile()93fun File.shouldNotBeAFile() = this shouldNot aFile()94fun aFile(): Matcher<File> = object : Matcher<File> {95 override fun test(value: File): MatcherResult =96 MatcherResult(97 value.isFile,98 { "File $value should be a file" },99 { "File $value should not be a file" })100}101infix fun File.shouldBeSmaller(other: Path) = this should beSmaller(other.toFile())102infix fun File.shouldBeSmaller(other: File) = this should beSmaller(other)103infix fun File.shouldNotBeSmaller(other: Path) = this shouldNot beSmaller(other.toFile())104infix fun File.shouldNotBeSmaller(other: File) = this shouldNot beSmaller(other)105fun beSmaller(other: File): Matcher<File> = object : Matcher<File> {106 override fun test(value: File): MatcherResult {107 val sizea = value.length()108 val sizeb = other.length()109 return MatcherResult(110 value.length() < other.length(),111 { "File $value ($sizea bytes) should be smaller than $other ($sizeb bytes)" },112 { "File $value ($sizea bytes) should not be smaller than $other ($sizeb bytes)" }113 )114 }115}116infix fun File.shouldBeLarger(other: Path) = this should beLarger(other.toFile())117infix fun File.shouldBeLarger(other: File) = this should beLarger(other)118infix fun File.shouldNotBeLarger(other: Path) = this shouldNot beLarger(other.toFile())119infix fun File.shouldNotBeLarger(other: File) = this shouldNot beLarger(other)120fun beLarger(other: File): Matcher<File> = object : Matcher<File> {121 override fun test(value: File): MatcherResult {122 val sizea = value.length()123 val sizeb = other.length()124 return MatcherResult(125 value.length() > other.length(),126 { "File $value ($sizea bytes) should be larger than $other ($sizeb bytes)" },127 { "File $value ($sizea bytes) should not be larger than $other ($sizeb bytes)" }128 )129 }130}131fun File.shouldBeCanonical() = this should beCanonicalPath()132fun File.shouldNotBeCanonical() = this shouldNot beCanonicalPath()133fun beCanonicalPath(): Matcher<File> = object : Matcher<File> {134 override fun test(value: File): MatcherResult = MatcherResult(135 value.canonicalPath == value.path,136 { "File $value should be canonical" },137 { "File $value should not be canonical" }138 )139}140fun File.shouldBeAbsolute() = this should beAbsolute()141fun File.shouldNotBeAbsolute() = this shouldNot beAbsolute()142fun beAbsolute(): Matcher<File> = object : Matcher<File> {143 override fun test(value: File): MatcherResult =144 MatcherResult(145 value.isAbsolute,146 { "File $value should be absolute" },147 { "File $value should not be absolute" })148}149fun File.shouldBeRelative() = this should beRelative()150fun File.shouldNotBeRelative() = this shouldNot beRelative()151fun beRelative(): Matcher<File> = object : Matcher<File> {152 override fun test(value: File): MatcherResult =153 MatcherResult(154 !value.isAbsolute,155 { "File $value should be relative" },156 { "File $value should not be relative" })157}158infix fun File.shouldHaveFileSize(size: Long) = this should haveFileSize(size)159infix fun File.shouldNotHaveFileSize(size: Long) = this shouldNot haveFileSize(size)160fun haveFileSize(size: Long): Matcher<File> = object : Matcher<File> {161 override fun test(value: File): MatcherResult = MatcherResult(162 value.length() == size,163 { "File $value should have size $size" },164 { "File $value should not have size $size" }165 )166}167fun File.shouldBeWriteable() = this should beWriteable()168fun File.shouldNotBeWriteable() = this shouldNot beWriteable()169fun beWriteable(): Matcher<File> = object : Matcher<File> {170 override fun test(value: File): MatcherResult =171 MatcherResult(172 value.canWrite(),173 { "File $value should be writeable" },174 { "File $value should not be writeable" })175}176fun File.shouldBeExecutable() = this should beExecutable()177fun File.shouldNotBeExecutable() = this shouldNot beExecutable()178fun beExecutable(): Matcher<File> = object : Matcher<File> {179 override fun test(value: File): MatcherResult = MatcherResult(180 value.canExecute(),181 { "File $value should be executable" },182 { "File $value should not be executable" }183 )184}185fun File.shouldBeHidden() = this should beHidden()186fun File.shouldNotBeHidden() = this shouldNot beHidden()187fun beHidden(): Matcher<File> = object : Matcher<File> {188 override fun test(value: File): MatcherResult =189 MatcherResult(190 value.isHidden,191 { "File $value should be hidden" },192 { "File $value should not be hidden" })193}194fun File.shouldBeReadable() = this should beReadable()195fun File.shouldNotBeReadable() = this shouldNot beReadable()196fun beReadable(): Matcher<File> = object : Matcher<File> {197 override fun test(value: File): MatcherResult =198 MatcherResult(199 value.canRead(),200 { "File $value should be readable" },201 { "File $value should not be readable" })202}203infix fun File.shouldStartWithPath(path: Path) = this should startWithPath(path)204infix fun File.shouldNotStartWithPath(path: Path) = this shouldNot startWithPath(path)205infix fun File.shouldStartWithPath(prefix: String) = this should startWithPath(prefix)206infix fun File.shouldNotStartWithPath(prefix: String) = this shouldNot startWithPath(prefix)207infix fun File.shouldStartWithPath(file: File) = this should startWithPath(file)208infix fun File.shouldNotStartWithPath(file: File) = this shouldNot startWithPath(file)209infix fun Path.shouldStartWithPath(path: Path) = this.toFile() should startWithPath(path)210infix fun Path.shouldNotStartWithPath(path: Path) = this.toFile() shouldNot startWithPath(path)211fun startWithPath(path: Path) = startWithPath(path.toFile())212fun startWithPath(file: File) = startWithPath(file.toString())213fun startWithPath(prefix: String) = object : Matcher<File> {214 override fun test(value: File): MatcherResult = MatcherResult(215 value.toString().startsWith(prefix),216 { "File $value should start with $prefix" },217 { "File $value should not start with $prefix" }218 )219}220infix fun File.shouldHaveSameStructureAs(file: File) {221 this.shouldHaveSameStructureAs(file) { _, _ -> false }222}223fun File.shouldHaveSameStructureAs(224 file: File,225 compare: (expect: File, actual: File) -> Boolean,226) {227 val expectFiles = this.walkTopDown().toList()228 val actualFiles = file.walkTopDown().toList()229 val expectParentPath = this.path230 val actualParentPath = file.path231 expectFiles shouldBeSameSizeAs actualFiles232 expectFiles.zip(actualFiles) { expect, actual ->233 when {234 compare(expect, actual) -> {}235 expect.isDirectory -> actual.shouldBeADirectory()236 expect.isFile -> {237 expect.path.removePrefix(expectParentPath)238 .shouldBe(actual.path.removePrefix(actualParentPath))239 }240 else -> error("There is an unexpected error analyzing file trees")241 }242 }243}244fun File.shouldHaveSameStructureAs(245 file: File,246 filterLhs: (File) -> Boolean = { false },247 filterRhs: (File) -> Boolean = { false },248) {249 this.shouldHaveSameStructureAs(file) { expect, actual ->250 filterLhs(expect) || filterRhs(actual)251 }252}253infix fun File.shouldHaveSameStructureAndContentAs(file: File) {254 this.shouldHaveSameStructureAndContentAs(file) { _, _ -> false }255}256fun File.shouldHaveSameStructureAndContentAs(257 file: File,258 compare: (expect: File, actual: File) -> Boolean,259) {260 val expectFiles = this.walkTopDown().toList()261 val actualFiles = file.walkTopDown().toList()262 val expectParentPath = this.path263 val actualParentPath = file.path264 expectFiles shouldBeSameSizeAs actualFiles265 expectFiles.zip(actualFiles) { expect, actual ->266 when {267 compare(expect, actual) -> {}268 expect.isDirectory -> actual.shouldBeADirectory()269 expect.isFile -> {270 expect.path.removePrefix(expectParentPath)271 .shouldBe(actual.path.removePrefix(actualParentPath))272 expect.shouldHaveSameContentAs(actual)273 }274 else -> error("There is an unexpected error analyzing file trees")275 }276 }277}278fun File.shouldHaveSameStructureAndContentAs(279 file: File,280 filterLhs: (File) -> Boolean = { false },281 filterRhs: (File) -> Boolean = { false },282) {283 this.shouldHaveSameStructureAndContentAs(file) { expect, actual ->284 filterLhs(expect) || filterRhs(actual)285 }286}...
paths.kt
Source:paths.kt
1package io.kotest.matchers.paths2import io.kotest.matchers.Matcher3import io.kotest.matchers.MatcherResult4import io.kotest.matchers.file.beLarger5import io.kotest.matchers.file.beEmptyDirectory6import io.kotest.matchers.file.containNFiles7import io.kotest.matchers.should8import io.kotest.matchers.shouldBe9import io.kotest.matchers.shouldNot10import io.kotest.matchers.shouldNotBe11import java.io.File12import java.nio.file.Files13import java.nio.file.Path14import kotlin.streams.toList15infix fun Path.shouldStartWithPath(file: File) = this should startWithPath(file)16infix fun Path.shouldNotStartWithPath(file: File) = this shouldNot startWithPath(file)17infix fun Path.shouldStartWithPath(prefix: String) = this should startWithPath(prefix)18infix fun Path.shouldNotStartWithPath(prefix: String) = this shouldNot startWithPath(prefix)19infix fun Path.shouldStartWithPath(path: Path) = this should startWithPath(path)20infix fun Path.shouldNotStartWithPath(path: Path) = this shouldNot startWithPath(path)21fun startWithPath(path: Path) = startWithPath(path.toString())22fun startWithPath(file: File) = startWithPath(file.toPath())23fun startWithPath(prefix: String) = object : Matcher<Path> {24 override fun test(value: Path): MatcherResult = MatcherResult(25 value.toString().startsWith(prefix),26 { "Path $value should start with $prefix" },27 { "Path $value should not start with $prefix" })28}29fun Path.shouldExist() = this should exist()30fun Path.shouldNotExist() = this shouldNot exist()31fun exist() = object : Matcher<Path> {32 override fun test(value: Path) =33 MatcherResult(34 Files.exists(value),35 { "Path $value should exist" },36 { "Path $value should not exist" })37}38infix fun Path.shouldHaveFileSize(size: Long) = this should haveFileSize(size)39infix fun Path.shouldNotHaveFileSize(size: Long) = this shouldNot haveFileSize(size)40fun haveFileSize(size: Long): Matcher<Path> = object : Matcher<Path> {41 override fun test(value: Path): MatcherResult = MatcherResult(42 Files.size(value) == size,43 { "Path $value should have size $size" },44 { "Path $value should not have size $size" })45}46fun Path.shouldBeADirectory() = this should aDirectory()47fun Path.shouldNotBeADirectory() = this shouldNot aDirectory()48fun aDirectory(): Matcher<Path> = object : Matcher<Path> {49 override fun test(value: Path): MatcherResult = MatcherResult(50 Files.isDirectory(value),51 { "File $value should be a directory" },52 { "File $value should not be a directory" })53}54fun Path.shouldBeAFile() = this should aFile()55fun Path.shouldNotBeAFile() = this shouldNot aFile()56fun aFile(): Matcher<Path> = object : Matcher<Path> {57 override fun test(value: Path): MatcherResult = MatcherResult(58 !Files.isDirectory(value),59 { "File $value should be a directory" },60 { "File $value should not be a directory" })61}62fun Path.shouldBeAbsolute() = this should beAbsolute()63fun Path.shouldNotBeAbsolute() = this shouldNot beAbsolute()64fun beAbsolute(): Matcher<Path> = object : Matcher<Path> {65 override fun test(value: Path): MatcherResult =66 MatcherResult(67 value.isAbsolute,68 { "Path $value should be absolute" },69 { "Path $value should not be absolute" })70}71fun Path.shouldBeRelative() = this should beRelative()72fun Path.shouldNotBeRelative() = this shouldNot beRelative()73fun beRelative(): Matcher<Path> = object : Matcher<Path> {74 override fun test(value: Path): MatcherResult =75 MatcherResult(76 !value.isAbsolute,77 { "Path $value should be relative" },78 { "Path $value should not be relative" })79}80fun Path.shouldBeReadable() = this should beReadable()81fun Path.shouldNotBeReadable() = this shouldNot beReadable()82fun beReadable(): Matcher<Path> = object : Matcher<Path> {83 override fun test(value: Path): MatcherResult =84 MatcherResult(85 Files.isReadable(value),86 { "Path $value should be readable" },87 { "Path $value should not be readable" }88 )89}90fun Path.shouldBeWriteable() = this should beWriteable()91fun Path.shouldNotBeWriteable() = this shouldNot beWriteable()92fun beWriteable(): Matcher<Path> = object : Matcher<Path> {93 override fun test(value: Path): MatcherResult =94 MatcherResult(95 Files.isWritable(value),96 { "Path $value should be writeable" },97 { "Path $value should not be writeable" }98 )99}100fun Path.shouldBeExecutable() = this should beExecutable()101fun Path.shouldNotBeExecutable() = this shouldNot beExecutable()102fun beExecutable(): Matcher<Path> = object : Matcher<Path> {103 override fun test(value: Path): MatcherResult = MatcherResult(104 Files.isExecutable(value),105 { "Path $value should be executable" },106 { "Path $value should not be executable" }107 )108}109infix fun Path.shouldContainNFiles(n: Int) = this.toFile() shouldBe containNFiles(n)110infix fun Path.shouldNotContainNFiles(n: Int) = this.toFile() shouldNotBe containNFiles(n)111@Deprecated(message ="checks if a directory is empty. Deprecated since 4.3.", replaceWith = ReplaceWith("shouldBeEmptyDirectory()"))112fun Path.shouldBeNonEmptyDirectory() = this.toFile() shouldNot beEmptyDirectory()113@Deprecated(message ="checks if a directory is not empty. Deprecated since 4.3.", replaceWith = ReplaceWith("shouldBeNonEmptyDirectory()"))114fun Path.shouldNotBeNonEmptyDirectory() = this.toFile() should beEmptyDirectory()115fun Path.shouldBeEmptyDirectory() = this.toFile() should beEmptyDirectory()116fun Path.shouldNotBeEmptyDirectory() = this.toFile() shouldNot beEmptyDirectory()117fun Path.shouldBeHidden() = this should beHidden()118fun Path.shouldNotBeHidden() = this shouldNot beHidden()119fun beHidden(): Matcher<Path> = object : Matcher<Path> {120 override fun test(value: Path): MatcherResult =121 MatcherResult(122 Files.isHidden(value),123 { "Path $value should be hidden" },124 { "Path $value should not be hidden" })125}126fun Path.shouldBeCanonical() = this should beCanonicalPath()127fun Path.shouldNotBeCanonical() = this shouldNot beCanonicalPath()128fun beCanonicalPath(): Matcher<Path> = object : Matcher<Path> {129 override fun test(value: Path): MatcherResult = MatcherResult(130 value.toFile().canonicalPath == value.toFile().path,131 { "File $value should be canonical" },132 { "File $value should not be canonical" })133}134infix fun Path.shouldContainFile(name: String) = this should containFile(name)135infix fun Path.shouldNotContainFile(name: String) = this shouldNot containFile(name)136fun containFile(name: String) = object : Matcher<Path> {137 override fun test(value: Path): MatcherResult {138 val contents = Files.list(value).map { it.fileName.toString() }.toList()139 val passed = Files.isDirectory(value) && contents.contains(name)140 return MatcherResult(141 passed,142 { "Directory $value should contain a file with filename $name (detected ${contents.size} other files)" },143 { "Directory $value should not contain a file with filename $name" })144 }145}146infix fun Path.shouldBeLarger(other: Path) = this.toFile() should beLarger(other.toFile())147infix fun Path.shouldBeLarger(other: File) = this.toFile() should beLarger(other)148infix fun Path.shouldNotBeLarger(other: Path) = this.toFile() shouldNot beLarger(other.toFile())149infix fun Path.shouldNotBeLarger(other: File) = this.toFile() shouldNot beLarger(other)150fun beLarger(other: Path): Matcher<Path> = object : Matcher<Path> {151 override fun test(value: Path): MatcherResult {152 val sizea = Files.size(value)153 val sizeb = Files.size(other)154 return MatcherResult(155 sizea > sizeb,156 { "Path $value ($sizea bytes) should be larger than $other ($sizeb bytes)" },157 { "Path $value ($sizea bytes) should not be larger than $other ($sizeb bytes)"})158 }159}160infix fun Path.shouldBeSmaller(other: Path) = this should beSmaller(other)161infix fun Path.shouldBeSmaller(other: File) = this should beSmaller(other.toPath())162infix fun Path.shouldNotBeSmaller(other: Path) = this shouldNot beSmaller(other)163infix fun Path.shouldNotBeSmaller(other: File) = this shouldNot beSmaller(other.toPath())164fun beSmaller(other: Path): Matcher<Path> = object : Matcher<Path> {165 override fun test(value: Path): MatcherResult {166 val sizea = Files.size(value)167 val sizeb = Files.size(other)168 return MatcherResult(169 sizea < sizeb,170 { "Path $value ($sizea bytes) should be smaller than $other ($sizeb bytes)" },171 { "Path $value ($sizea bytes) should not be smaller than $other ($sizeb bytes)" })172 }173}174infix fun Path.shouldContainFileDeep(name: String) = this should containFileDeep(name)175infix fun Path.shouldNotContainFileDeep(name: String) = this shouldNot containFileDeep(name)176fun containFileDeep(name: String): Matcher<Path> = object : Matcher<Path> {177 private fun fileExists(dir: Path): Boolean {178 val contents = Files.list(dir).toList()179 val (dirs, files) = contents.partition { Files.isDirectory(it) }180 return files.map { it.fileName.toString() }.contains(name) || dirs.any(::fileExists)181 }182 override fun test(value: Path): MatcherResult = MatcherResult(183 fileExists(value),184 { "Path $name should exist in $value" },185 { "Path $name should not exist in $value" }186 )187}188fun Path.shouldContainFiles(vararg files: String) = this should containFiles(files.asList())189fun Path.shouldNotContainFiles(vararg files: String) = this shouldNot containFiles(files.asList())190fun containFiles(names: List<String>) = object : Matcher<Path> {191 override fun test(value: Path): MatcherResult {192 val files = Files.list(value).toList().map { it.fileName.toString() }193 val existingFiles = names.intersect(files)194 val nonExistingFiles = names.subtract(existingFiles)195 return MatcherResult(196 nonExistingFiles.isEmpty(),197 { buildMessage(value, nonExistingFiles, false) },198 {199 buildMessage(value, existingFiles, true)200 })201 }202 private fun buildMessage(path: Path, fileList: Set<String>, isNegative: Boolean): String {203 val fileString = if (fileList.size > 1) "Files" else "File"204 val negativeWord = if (isNegative) " not" else ""205 val filesString = fileList.sorted().joinToString(", ")206 return "$fileString $filesString should$negativeWord exist in $path"207 }208}209fun Path.shouldBeSymbolicLink() = this should beSymbolicLink()210fun Path.shouldNotBeSymbolicLink() = this shouldNot beSymbolicLink()211fun beSymbolicLink() = object : Matcher<Path> {212 override fun test(value: Path) = MatcherResult(213 Files.isSymbolicLink(value),214 { "Path $value should be a symbolic link" },215 { "Path $value should not be a symbolic link" }216 )217}218infix fun Path.shouldHaveParent(name: String) = this should haveParent(name)219infix fun Path.shouldNotHaveParent(name: String) = this shouldNot haveParent(name)220fun haveParent(name: String) = object : Matcher<Path> {221 private fun isParentEqualExpected(parent: Path?): Boolean {222 if (parent == null) return false223 return parent.fileName?.toString() == name || isParentEqualExpected(parent.parent)224 }225 override fun test(value: Path) = MatcherResult(226 isParentEqualExpected(value.parent),227 { "Path $value should have parent $name" },228 { "Path $value should not have parent $name" }229 )230}...
IOSpec.kt
Source:IOSpec.kt
1package com.github.rougsig.core2import io.kotest.core.datatest.forAll3import io.kotest.core.spec.style.FunSpec4import io.kotest.matchers.file.shouldBeADirectory5import io.kotest.matchers.file.shouldBeAFile6import io.kotest.matchers.file.shouldExist7import io.kotest.matchers.shouldBe8import kotlinx.coroutines.runBlocking9import java.io.ByteArrayInputStream10import java.io.ByteArrayOutputStream11import java.io.File12import java.io.PrintStream13import java.nio.file.Paths14abstract class IOSpec(15 private val resourcesPath: String,16 private val testFun: IOEnvironment.() -> Unit17) : FunSpec({18 val projectRoot = File(".").absoluteFile.parent19 val resourcesDir = Paths.get(projectRoot, "src/test/resources", resourcesPath).toFile()20 context("File IO tests") {21 val inputDir = File("${resourcesDir.absoluteFile}/input")22 inputDir.shouldExist()23 inputDir.shouldBeADirectory()24 val outputDir = File("${resourcesDir.absoluteFile}/output")25 outputDir.shouldExist()26 val testNames = inputDir.listFiles()27 .map { it.nameWithoutExtension.removePrefix("input") }28 forAll(testNames) { testName: String ->29 val input = File("${inputDir.absoluteFile}/input${testName}.txt")30 input.shouldExist()31 input.shouldBeAFile()32 val output = File("${outputDir.absoluteFile}/output${testName}.txt")33 output.shouldExist()34 output.shouldBeAFile()35 val baos = ByteArrayOutputStream()36 runBlocking {37 // Set the same as hackerrank timeout limit38 // https://www.hackerrank.com/environment/languages39 withTimeoutOrInterrupt(4000L) {40 IOEnvironment(ByteArrayInputStream(input.readBytes()), PrintStream(baos)).testFun()41 }42 }43 val actual = baos.toString().trim().trimIndent()44 val expected = output.readText().trim().trimIndent()45 actual.shouldBe(expected)46 }47 }48})...
ScenarioTest.kt
Source:ScenarioTest.kt
1package uk.nhs.riskscore2import io.kotest.core.spec.style.StringSpec3import io.kotest.matchers.doubles.shouldBeLessThan4import io.kotest.matchers.paths.*5import uk.nhs.riskscore.RiskScoreCalculatorConfiguration.Companion.exampleConfiguration6import uk.nhs.support.InstanceName7import uk.nhs.support.RiskScoreResultsCSVDecoder8import uk.nhs.support.ScanInstanceCSVDecoder9import java.nio.file.Paths10import kotlin.math.abs11internal class ScenarioTest: StringSpec({12 "computed riskscores are within 5% of the python computed riskscores" {13 val rootPath = Paths.get("src","test","resources", "TestData").toAbsolutePath()14 val expectedRiskScoresPath = rootPath.resolve("pythonRiskScores.csv")15 expectedRiskScoresPath.shouldBeAFile()16 val scanInstanceDirectoryPath = Paths.get(rootPath.toString(), "ScanInstances")17 scanInstanceDirectoryPath.shouldBeADirectory()18 val calculator = RiskScoreCalculator(exampleConfiguration)19 val expectedScores = RiskScoreResultsCSVDecoder.decode(expectedRiskScoresPath.toFile().path)20 scanInstanceDirectoryPath.toFile().listFiles()!!.forEach { scanInstanceFile ->21 val instances = ScanInstanceCSVDecoder.decode(scanInstanceFile.path)22 val actualScore = calculator.calculate(instances)23 val expectedScore = expectedScores[InstanceName(scanInstanceFile.name)]!!.score24 abs(expectedScore - actualScore) shouldBeLessThan (actualScore * 0.05)25 }26 }27})...
Path.shouldBeADirectory
Using AI Code Generation
1val path = Path("path/to/directory")2path.shouldBeADirectory()3val path = Path("path/to/file")4path.shouldBeAFile()5val path = Path("/path/to/file")6path.shouldBeAbsolute()7val path = Path("path/to/file")8path.shouldBeRelative()9val path = Path("path/to/file")10path.shouldBeReadable()11val path = Path("path/to/file")12path.shouldBeWritable()13val path = Path("path/to/file")14path.shouldBeExecutable()15val path = Path("path/to/.file")16path.shouldBeHidden()17val path = Path("path/to/file")18path.shouldBeReadable()19val path = Path("path/to/file")20path.shouldBeSymbolicLink()21val path = Path("path/to/file")22path.shouldBeRegularFile()23val path = Path("path/to/directory")24path.shouldBeDirectory()25val path = Path("path/to/file")26path.shouldBeSameAs(path)27val path = Path("path/to/file")28path.shouldBeSamePathAs(path)
Path.shouldBeADirectory
Using AI Code Generation
1Path(“/tmp”).shouldBeADirectory()2Path(“/tmp/file.txt”).shouldBeARegularFile()3Path(“/tmp/file.txt”).shouldBeReadable()4Path(“/tmp/file.txt”).shouldBeWritable()5Path(“/tmp/file.txt”).shouldBeExecutable()6Path(“/tmp/file.txt”).shouldHaveParent(“/tmp”)7Path(“/tmp/file.txt”).shouldHaveSibling(“/tmp/file2.txt”)8Path(“/tmp/file.txt”).shouldHaveExtension(“txt”)9Path(“/tmp/file.txt”).shouldHaveFileName(“file.txt”)10Path(“/tmp/file.txt”).shouldHaveName(“file”)11Path(“/tmp/file.txt”).shouldHaveName(“file”)12Path(“/tmp/file.txt”).shouldBeAbsolute()13Path(“file.txt”).shouldBeRelative()14Path(“/tmp/file.txt”).shouldHaveSameTextualContentAs(“file2.txt”)15Path(“/tmp/file.txt”).should
Path.shouldBeADirectory
Using AI Code Generation
1Path ( "src/test/resources" ). shouldBeADirectory ()2Path ( "src/test/resources/test.txt" ). shouldBeAFile ()3Path ( "src/test/resources/test.txt" ). shouldBeReadable ()4Path ( "src/test/resources/test.txt" ). shouldBeWritable ()5Path ( "src/test/resources/test.txt" ). shouldBeExecutable ()6Path ( "src/test/resources/test.txt" ). shouldBeRelative ()7Path ( "src/test/resources/test.txt" ). shouldBeAbsolute ()8Path ( "src/test/resources/test.txt" ). shouldBeHidden ()9Path ( "src/test/resources/test.txt" ). shouldBeRegularFile ()10Path ( "src/test/resources/test.txt" ). shouldBeSymbolicLink ()11Path ( "src/test/resources/test.txt" ). shouldBeSamePathAs ( "src/test/resources/test.txt" )12Path ( "src/test/resources/test.txt" ). shouldHaveTheSameTextualContentAs ( "src/test/resources/test.txt" )13Path ( "src/test/resources/test.txt" ). shouldHaveTheSameBinaryContentAs ( "src/test/resources/test.txt" )14Path ( "src/test/resources/test.txt" ). should
Path.shouldBeADirectory
Using AI Code Generation
1val path = Paths.get("src/test/resources")2path.shouldBeADirectory()3val path = Paths.get("src/test/resources/test.txt")4path.shouldBeAFile()5val path = Paths.get("src/test/resources/test.txt")6path.shouldBeReadable()7val path = Paths.get("src/test/resources/test.txt")8path.shouldBeWritable()9val path = Paths.get("src/test/resources/test.txt")10path.shouldBeRelative()11val path = Paths.get("src/test/resources/test.txt")12path.shouldBeAbsolute()13val path = Paths.get("src/test/resources/test.txt")14path.shouldBeRelative()15val path = Paths.get("src/test/resources/test.txt")16path.shouldBeAbsolute()17val path = Paths.get("src/test/resources/test.txt")18path.shouldBeRelative()19val path = Paths.get("src/test/resources/test.txt")20path.shouldBeAbsolute()21val path = Paths.get("src/test/resources/test.txt")22path.shouldBeRelative()23val path = Paths.get("src/test/resources/test.txt")24path.shouldBeAbsolute()25val path = Paths.get("src/test/resources/test.txt")26path.shouldBeRelative()27val path = Paths.get("src/test/resources/test.txt")
Path.shouldBeADirectory
Using AI Code Generation
1Path( "src/main/resources" ).shouldBeADirectory()2Path( "src/main/resources" ).shouldBeAFile()3Path( "src/main/resources" ).shouldBeExecutable()4Path( "src/main/resources" ).shouldBeReadable()5Path( "src/main/resources" ).shouldBeRelative()6Path( "src/main/resources" ).shouldBeSymbolicLink()7Path( "src/main/resources" ).shouldBeWritable()8Path( "src/main/resources" ).shouldContainFile( "test.txt" )9Path( "src/main/resources" ).shouldContainFiles( "test.txt" , "test1.txt" )10Path( "src/main/resources" ).shouldContainFilesInOrder( "test.txt" , "test1.txt" )11Path( "src/main/resources" ).shouldContainOnlyFiles( "test.txt" , "test1.txt" )12Path( "src/main/resources" ).shouldContainSubDirectories( "test.txt" , "test1.txt" )13Path( "src/main/resources" ).shouldHaveChildren( "test.txt" , "test1.txt" )14Path( "src/main/resources" ).shouldHaveExtension( "txt
Path.shouldBeADirectory
Using AI Code Generation
1Path( "C:/Users/" ).shouldBeADirectory()2Path( "C:/Users/abc.txt" ).shouldBeARegularFile()3Path( "C:/Users/abc.txt" ).shouldBeAHiddenFile()4Path( "C:/Users/abc.txt" ).shouldBeReadable()5Path( "C:/Users/abc.txt" ).shouldBeWritable()6Path( "C:/Users/abc.txt" ).shouldBeExecutable()7Path( "C:/Users/abc.txt" ).shouldBeAbsolute()8Path( "C:/Users/abc.txt" ).shouldBeRelative()9Path( "C:/Users/abc.txt" ).shouldBeSymbolicLink()10Path( "C:/Users/abc.txt" ).shouldBeAbsolute()11Path( "C:/Users/abc.txt" ).shouldBeRelative()12Path( "C:/Users/abc.txt" ).shouldBeSymbolicLink()13Path( "C:/Users/abc.txt" ).shouldHaveFileName( "abc.txt" )14Path( "C:/Users/abc.txt" ).shouldHaveParent( "C:/Users" )
Path.shouldBeADirectory
Using AI Code Generation
1import io.kotest.matchers.paths.shouldBeADirectory2val path = Paths.get("C:\\Users\\user\\Desktop")3path.shouldBeADirectory()4import io.kotest.matchers.paths.shouldBeARegularFile5val path = Paths.get("C:\\Users\\user\\Desktop\\kotest.txt")6path.shouldBeARegularFile()7import io.kotest.matchers.paths.shouldBeAHidden8val path = Paths.get("C:\\Users\\user\\Desktop\\.kotest.txt")9path.shouldBeAHidden()10import io.kotest.matchers.paths.shouldBeReadable11val path = Paths.get("C:\\Users\\user\\Desktop\\kotest.txt")12path.shouldBeReadable()13import io.kotest.matchers.paths.shouldBeWritable14val path = Paths.get("C:\\Users\\user\\Desktop\\kotest.txt")15path.shouldBeWritable()16import io.kotest.matchers.paths.shouldBeExecutable17val path = Paths.get("C:\\Users\\user\\Desktop\\kotest.txt")18path.shouldBeExecutable()19import io.kotest.matchers.paths.shouldBeRelative20val path = Paths.get("C:\\Users\\user\\Desktop\\kotest.txt")21path.shouldBeRelative()22import io.kotest.matchers.paths.shouldBeAbsolute23val path = Paths.get("C:\\Users\\user\\Desktop\\kotest.txt")24path.shouldBeAbsolute()25import io.kotest.matchers.paths.shouldBeSymbolicLink26val path = Paths.get("C:\\Users\\user\\Desktop\\kotest.txt")27path.shouldBeSymbolicLink()
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!