Path: blob/trunk/javascript/selenium-webdriver/test/io/io_test.js
2885 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the5// "License"); you may not use this file except in compliance6// with the License. You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing,11// software distributed under the License is distributed on an12// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13// KIND, either express or implied. See the License for the14// specific language governing permissions and limitations15// under the License.1617'use strict'1819const assert = require('node:assert'),20fs = require('node:fs'),21path = require('node:path')2223const io = require('selenium-webdriver/io')2425describe('io', function () {26describe('copy', function () {27let tmpDir2829before(function () {30return io.tmpDir().then(function (d) {31tmpDir = d3233fs.writeFileSync(path.join(d, 'foo'), 'Hello, world')34})35})3637it('can copy one file to another', function () {38return io.tmpFile().then(function (f) {39return io.copy(path.join(tmpDir, 'foo'), f).then(function (p) {40assert.strictEqual(p, f)41assert.strictEqual('Hello, world', fs.readFileSync(p, 'utf-8'))42})43})44})4546it('can copy symlink to destination', function () {47if (process.platform === 'win32') {48return // No symlinks on windows.49}50fs.symlinkSync(path.join(tmpDir, 'foo'), path.join(tmpDir, 'symlinked-foo'))51return io.tmpFile().then(function (f) {52return io.copy(path.join(tmpDir, 'symlinked-foo'), f).then(function (p) {53assert.strictEqual(p, f)54assert.strictEqual('Hello, world', fs.readFileSync(p, 'utf-8'))55})56})57})5859it('fails if given a directory as a source', function () {60return io61.tmpFile()62.then(function (f) {63return io.copy(tmpDir, f)64})65.then(66function () {67throw Error('Should have failed with a type error')68},69function () {70// Do nothing; expected.71},72)73})74})7576describe('copyDir', function () {77it('copies recursively', function () {78return io.tmpDir().then(function (dir) {79fs.writeFileSync(path.join(dir, 'file1'), 'hello')80fs.mkdirSync(path.join(dir, 'sub'))81fs.mkdirSync(path.join(dir, 'sub/folder'))82fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye')8384return io.tmpDir().then(function (dst) {85return io.copyDir(dir, dst).then(function (ret) {86assert.strictEqual(dst, ret)8788assert.strictEqual('hello', fs.readFileSync(path.join(dst, 'file1'), 'utf-8'))89assert.strictEqual('goodbye', fs.readFileSync(path.join(dst, 'sub/folder/file2'), 'utf-8'))90})91})92})93})9495it('creates destination dir if necessary', function () {96return io97.tmpDir()98.then(function (srcDir) {99fs.writeFileSync(path.join(srcDir, 'foo'), 'hi')100return io.tmpDir().then(function (dstDir) {101return io.copyDir(srcDir, path.join(dstDir, 'sub'))102})103})104.then(function (p) {105assert.strictEqual('sub', path.basename(p))106assert.strictEqual('hi', fs.readFileSync(path.join(p, 'foo'), 'utf-8'))107})108})109110it('supports regex exclusion filter', function () {111return io112.tmpDir()113.then(function (src) {114fs.writeFileSync(path.join(src, 'foo'), 'a')115fs.writeFileSync(path.join(src, 'bar'), 'b')116fs.writeFileSync(path.join(src, 'baz'), 'c')117fs.mkdirSync(path.join(src, 'sub'))118fs.writeFileSync(path.join(src, 'sub/quux'), 'd')119fs.writeFileSync(path.join(src, 'sub/quot'), 'e')120121return io.tmpDir().then(function (dst) {122return io.copyDir(src, dst, /(bar|quux)/)123})124})125.then(function (dir) {126assert.strictEqual('a', fs.readFileSync(path.join(dir, 'foo'), 'utf-8'))127assert.strictEqual('c', fs.readFileSync(path.join(dir, 'baz'), 'utf-8'))128assert.strictEqual('e', fs.readFileSync(path.join(dir, 'sub/quot'), 'utf-8'))129130assert.ok(!fs.existsSync(path.join(dir, 'bar')))131assert.ok(!fs.existsSync(path.join(dir, 'sub/quux')))132})133})134135it('supports exclusion filter function', function () {136return io137.tmpDir()138.then(function (src) {139fs.writeFileSync(path.join(src, 'foo'), 'a')140fs.writeFileSync(path.join(src, 'bar'), 'b')141fs.writeFileSync(path.join(src, 'baz'), 'c')142fs.mkdirSync(path.join(src, 'sub'))143fs.writeFileSync(path.join(src, 'sub/quux'), 'd')144fs.writeFileSync(path.join(src, 'sub/quot'), 'e')145146return io.tmpDir().then(function (dst) {147return io.copyDir(src, dst, function (f) {148return f !== path.join(src, 'foo') && f !== path.join(src, 'sub/quot')149})150})151})152.then(function (dir) {153assert.strictEqual('b', fs.readFileSync(path.join(dir, 'bar'), 'utf-8'))154assert.strictEqual('c', fs.readFileSync(path.join(dir, 'baz'), 'utf-8'))155assert.strictEqual('d', fs.readFileSync(path.join(dir, 'sub/quux'), 'utf-8'))156157assert.ok(!fs.existsSync(path.join(dir, 'foo')))158assert.ok(!fs.existsSync(path.join(dir, 'sub/quot')))159})160})161})162163describe('exists', function () {164var dir165166before(function () {167return io.tmpDir().then(function (d) {168dir = d169})170})171172it('returns a rejected promise if input value is invalid', function () {173return io.exists(undefined).then(174() => assert.fail('should have failed'),175(e) => assert.ok(e instanceof TypeError),176)177})178179it('works for directories', function () {180return io.exists(dir).then(assert.ok)181})182183it('works for files', function () {184var file = path.join(dir, 'foo')185fs.writeFileSync(file, '')186return io.exists(file).then(assert.ok)187})188189it('does not return a rejected promise if file does not exist', function () {190return io.exists(path.join(dir, 'not-there')).then(function (exists) {191assert.ok(!exists)192})193})194})195196describe('unlink', function () {197let dir198199before(function () {200return io.tmpDir().then(function (d) {201dir = d202})203})204205it('silently succeeds if the path does not exist', function () {206return io.unlink(path.join(dir, 'not-there'))207})208209it('deletes files', function () {210const file = path.join(dir, 'foo')211fs.writeFileSync(file, '')212return io213.exists(file)214.then(assert.ok)215.then(function () {216return io.unlink(file)217})218.then(function () {219return io.exists(file)220})221.then(function (exists) {222return assert.ok(!exists)223})224})225})226227describe('rmDir', function () {228it('succeeds if the designated directory does not exist', function () {229return io.tmpDir().then(function (d) {230return io.rmDir(path.join(d, 'i/do/not/exist'))231})232})233234it('deletes recursively', function () {235return io.tmpDir().then(function (dir) {236fs.writeFileSync(path.join(dir, 'file1'), 'hello')237fs.mkdirSync(path.join(dir, 'sub'))238fs.mkdirSync(path.join(dir, 'sub/folder'))239fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye')240241return io.rmDir(dir).then(function () {242assert.ok(!fs.existsSync(dir))243assert.ok(!fs.existsSync(path.join(dir, 'sub/folder/file2')))244})245})246})247})248249describe('findInPath', function () {250const savedPathEnv = process.env['PATH']251afterEach(() => (process.env['PATH'] = savedPathEnv))252253const cwd = process.cwd254afterEach(() => (process.cwd = cwd))255256let dirs257beforeEach(() => {258return Promise.all([io.tmpDir(), io.tmpDir(), io.tmpDir()]).then((arr) => {259dirs = arr260process.env['PATH'] = arr.join(path.delimiter)261})262})263264it('returns null if file cannot be found', () => {265assert.strictEqual(io.findInPath('foo.txt'), null)266})267268it('can find file on path', () => {269let filePath = path.join(dirs[1], 'foo.txt')270fs.writeFileSync(filePath, 'hi')271272assert.strictEqual(io.findInPath('foo.txt'), filePath)273})274275it('returns null if file is in a subdir of a directory on the path', () => {276let subDir = path.join(dirs[2], 'sub')277fs.mkdirSync(subDir)278279let filePath = path.join(subDir, 'foo.txt')280fs.writeFileSync(filePath, 'hi')281282assert.strictEqual(io.findInPath('foo.txt'), null)283})284285it('does not match on directories', () => {286fs.mkdirSync(path.join(dirs[2], 'sub'))287assert.strictEqual(io.findInPath('sub'), null)288})289290it('will look in cwd first if requested', () => {291return io.tmpDir().then((fakeCwd) => {292process.cwd = () => fakeCwd293294let theFile = path.join(fakeCwd, 'foo.txt')295296fs.writeFileSync(path.join(dirs[1], 'foo.txt'), 'hi')297fs.writeFileSync(theFile, 'bye')298299assert.strictEqual(io.findInPath('foo.txt', true), theFile)300})301})302})303304describe('read', function () {305let tmpDir306307before(function () {308return io.tmpDir().then(function (d) {309tmpDir = d310311fs.writeFileSync(path.join(d, 'foo'), 'Hello, world')312})313})314315it('can read a file', function () {316return io.read(path.join(tmpDir, 'foo')).then((buff) => {317assert.ok(buff instanceof Buffer)318assert.strictEqual('Hello, world', buff.toString())319})320})321322it('catches errors from invalid input', function () {323return io.read({}).then(324() => assert.fail('should have failed'),325(e) => assert.ok(e instanceof TypeError),326)327})328329it('rejects returned promise if file does not exist', function () {330return io.read(path.join(tmpDir, 'not-there')).then(331() => assert.fail('should have failed'),332(e) => assert.strictEqual('ENOENT', e.code),333)334})335})336337describe('mkdirp', function () {338it('recursively creates entire directory path', function () {339return io.tmpDir().then((root) => {340let dst = path.join(root, 'foo/bar/baz')341return io.mkdirp(dst).then((d) => {342assert.strictEqual(d, dst)343return io.stat(d).then((stats) => {344assert.ok(stats.isDirectory())345})346})347})348})349350it('does nothing if the directory already exists', function () {351return io.tmpDir().then((dir) => io.mkdirp(dir).then((d) => assert.strictEqual(d, dir)))352})353})354355describe('walkDir', function () {356it('walk directory', async function () {357let dir = await io.tmpDir()358359fs.writeFileSync(path.join(dir, 'file1'), 'hello')360fs.mkdirSync(path.join(dir, 'sub'))361fs.mkdirSync(path.join(dir, 'sub/folder'))362fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye')363364let seen = await io.walkDir(dir)365seen.sort((a, b) => {366if (a.path < b.path) return -1367if (a.path > b.path) return 1368return 0369})370assert.deepStrictEqual(seen, [371{ path: 'file1', dir: false },372{ path: 'sub', dir: true },373{ path: path.join('sub', 'folder'), dir: true },374{ path: path.join('sub', 'folder', 'file2'), dir: false },375])376})377})378})379380381