JSPM

  • Created
  • Published
  • Downloads 180737
  • Score
    100M100P100Q158070F
  • License MIT

test helpers for oclif components

Package Exports

  • @oclif/test
  • @oclif/test/lib/index.js
  • @oclif/test/lib/load-config
  • @oclif/test/lib/load-config.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@oclif/test) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@oclif/test

test helpers for oclif CLIs

Version Known Vulnerabilities Downloads/week License

Usage

@oclif/test is an extension of fancy-test. Please see the fancy-test documentation for all the features that are available.

The following are the features that @oclif/test adds to fancy-test.

.loadConfig()

.loadConfig() creates and returns a new Config instance. This instance will be available on the ctx variable that's provided in the callback.

import {join} from 'node:path'
import {expect, test} from '@oclif/test'

const root = join(__dirname, 'fixtures/test-cli')
test
  .loadConfig({root})
  .stdout()
  .command(['foo:bar'])
  .it('should run the command from the given directory', (ctx) => {
    expect(ctx.stdout).to.equal('hello world!\n')
    expect(ctx.config.root).to.equal(root)
    const {name} = ctx.returned as {name: string}
    expect(name).to.equal('world')
  })

If you would like to run the same test without using @oclif/test:

import {Config, ux} from '@oclif/core'
import {expect} from 'chai'
import {join} from 'node:path'
import {SinonSandbox, SinonStub, createSandbox} from 'sinon'

const root = join(__dirname, 'fixtures/test-cli')
describe('non-fancy test', () => {
  let sandbox: SinonSandbox
  let config: Config
  let stdoutStub: SinonStub

  beforeEach(async () => {
    sandbox = createSandbox()
    stdoutStub = sandbox.stub(ux.write, 'stdout')
    config = await Config.load({root})
  })

  afterEach(async () => {
    sandbox.restore()
  })

  it('should run command from the given directory', async () => {
    const {name} = await config.runCommand<{name: string}>('foo:bar')
    expect(stdoutStub.calledWith('hello world!\n')).to.be.true
    expect(config.root).to.equal(root)
    expect(name).to.equal('world')
  })
})

.command()

.command() let's you run a command from your CLI.

import {expect, test} from '@oclif/test'

describe('hello world', () => {
  test
    .stdout()
    .command(['hello:world'])
    .it('runs hello world cmd', (ctx) => {
      expect(ctx.stdout).to.contain('hello world!')
    })
})

For a single command cli you would provide '.' as the command. For instance:

import {expect, test} from '@oclif/test'

describe('hello world', () => {
  test
    .stdout()
    .command(['.'])
    .it('runs hello world cmd', (ctx) => {
      expect(ctx.stdout).to.contain('hello world!')
    })
})

If you would like to run the same test without using @oclif/test:

import {Config, ux} from '@oclif/core'
import {expect} from 'chai'
import {SinonSandbox, SinonStub, createSandbox} from 'sinon'

describe('non-fancy test', () => {
  let sandbox: SinonSandbox
  let config: Config
  let stdoutStub: SinonStub

  beforeEach(async () => {
    sandbox = createSandbox()
    stdoutStub = sandbox.stub(ux.write, 'stdout')
    config = await Config.load({root: process.cwd()})
  })

  afterEach(async () => {
    sandbox.restore()
  })

  it('should run command', async () => {
    // use '.' for a single command CLI
    const {name} = await config.runCommand<{name: string}>('hello:world')
    expect(stdoutStub.calledWith('hello world!\n')).to.be.true
    expect(name).to.equal('world')
  })
})

.exit()

.exit() let's you test that a command exited with a certain exit code.

import {join} from 'node:path'
import {expect, test} from '@oclif/test'

describe('exit', () => {
  test
    .loadConfig()
    .stdout()
    .command(['hello:world', '--code=101'])
    .exit(101)
    .do((output) => expect(output.stdout).to.equal('exiting with code 101\n'))
    .it('should exit with code 101')
})

If you would like to run the same test without using @oclif/test:

import {Config, Errors, ux} from '@oclif/core'
import {expect} from 'chai'
import {SinonSandbox, createSandbox} from 'sinon'

describe('non-fancy test', () => {
  let sandbox: SinonSandbox
  let config: Config

  beforeEach(async () => {
    sandbox = createSandbox()
    sandbox.stub(ux.write, 'stdout')
    config = await Config.load({root: process.cwd()})
  })

  afterEach(async () => {
    sandbox.restore()
  })

  it('should run command from the given directory', async () => {
    try {
      await config.runCommand('.')
      throw new Error('Expected CLIError to be thrown')
    } catch (error) {
      if (error instanceof Errors.CLIError) {
        expect(error.oclif.exit).to.equal(101)
      } else {
        throw error
      }
    }
  })
})

.hook()

.hook() let's you test a hook in your CLI.

import {join} from 'node:path'

import {expect, test} from '@oclif/test'

const root = join(__dirname, 'fixtures/test-cli')

describe('hooks', () => {
  test
    .loadConfig({root})
    .stdout()
    .hook('foo', {argv: ['arg']}, {root})
    .do((output) => expect(output.stdout).to.equal('foo hook args: arg\n'))
    .it('should run hook')
})

If you would like to run the same test without using @oclif/test:

import {Config, ux} from '@oclif/core'
import {expect} from 'chai'
import {SinonSandbox, SinonStub, createSandbox} from 'sinon'

describe('non-fancy test', () => {
  let sandbox: SinonSandbox
  let config: Config
  let stdoutStub: SinonStub

  beforeEach(async () => {
    sandbox = createSandbox()
    stdoutStub = sandbox.stub(ux.write, 'stdout')
    config = await Config.load({root: process.cwd()})
  })

  afterEach(async () => {
    sandbox.restore()
  })

  it('should run hook', async () => {
    const {name} = await config.runHook('foo', {argv: ['arg']})
    expect(stdoutStub.calledWith('foo hook args: arg\n')).to.be.true
  })
})