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”).shouldPath.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" ). shouldPath.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( "txtPath.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!!
