Repository: RichardLitt/generator-standard-readme Branch: master Commit: bf559f9d56ef Files: 25 Total size: 34.4 KB Directory structure: gitextract_rrjuimex/ ├── .gitattributes ├── .github/ │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .travis.yml ├── README.md ├── app/ │ ├── bin.js │ ├── index.js │ └── templates/ │ └── README.md ├── examples/ │ ├── api-readme.md │ ├── background-readme.md │ ├── badges-readme.md │ ├── banner-readme.md │ ├── contributing-file-readme.md │ ├── default-readme.md │ ├── different-license-readme.md │ ├── different-year.md │ ├── maximal-readme.md │ ├── no-badge-readme.md │ ├── no-long-description-readme.md │ ├── prs-readme.md │ └── security-readme.md ├── license ├── package.json ├── test.js └── vitest.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ * text=auto ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: push: branches: ['master'] pull_request: branches: ['master'] jobs: build: runs-on: ubuntu-latest strategy: matrix: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ node-version: [lts/*] steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - run: npm run test ================================================ FILE: .gitignore ================================================ node_modules temp ================================================ FILE: .travis.yml ================================================ sudo: false language: node_js node_js: - 'stable' ================================================ FILE: README.md ================================================ # generator-standard-readme [![Build Status](https://github.com/RichardLitt/generator-standard-readme/actions/workflows/ci.yml/badge.svg)](https://github.com/RichardLitt/generator-standard-readme/actions/workflows/ci.yml) Scaffold out a Standard Readme This generator conforms to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. It creates a minimally compliant standard readme for your cross-language project, with some options. Tip: Use [chalk](https://github.com/sindresorhus/chalk) if you want colors in your CLI. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Fields to fill out](#fields-to-fill-out) - [Contributing](#contributing) - [License](#license) ## Install This generator requires [node](https://nodejs.org), [npm](https://npmjs.com), and [yeoman](http://yeoman.io/). You can install it by running: ```sh npm install --global yo generator-standard-readme ``` ## Usage With [yo](https://github.com/yeoman/yo): ``` $ yo standard-readme ``` This will write a file, `readme.md`, to the local directory. ### Fields to fill out `standard-readme` will ask you a set of questions, which will help it fill out the README. These are: - What do you want to name your module? - What is the description of this module? - Do have a banner image? - Where is the banner image? Ex: \'img/banner.png\' - Do you want a TODO dropped where your badges should be? - Do you want a TODO dropped where your long description should be? - Do you need a prioritized security section? - Do you need a background section? - Do you need an API section? - What is the GitHub handle of the main maintainer? - Do you have a CONTRIBUTING.md file? - Are PRs accepted? - Is an MIT license OK? - What is your license? - Who is the License holder (probably your name)? - Use the current year? - What years would you like to specify? ## Maintainer [@RichardLitt](https://github.com/RichardLitt) ## Contributing Please contribute! [Look at the issues](https://github.com/RichardLitt/generator-standard-readme/issues). ## License MIT © 2016 [Richard Littauer](http://burntfen.com) ================================================ FILE: app/bin.js ================================================ #!/usr/bin/env node import { join } from 'node:path' import { createEnv } from 'yeoman-environment' const env = createEnv() env.register(join(import.meta.dirname, '/index.js'), 'standard-readme:app') await env.run('standard-readme:app') ================================================ FILE: app/index.js ================================================ import Generator from 'yeoman-generator' import _s from 'underscore.string' import fullName from 'fullname' import { usernameSync } from 'username' import { execSync } from 'node:child_process' const domainRegex = /^(((?!-))(xn--|_)?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9][a-z0-9-]{0,60}|[a-z0-9-]{1,30}\.[a-z]{2,})$/ export default class StandardReadmeGenerator extends Generator { /** * @param {string[]} args * @param {import('yeoman-generator').BaseOptions} options * @param {import('yeoman-generator').BaseFeatures?} features */ constructor (args, options, features = {}) { // Suppress log about `package.json` being unchanged. features.customInstallTask = true super(args, options, features) this.props = {} /** @type {import('yeoman-generator').PromptQuestions} */ this.promptQuestions = [ { name: 'moduleName', message: 'What is the name of your module?', default: this.appname.replace(/\s/g, '-'), filter: x => _s.slugify(x) }, { name: 'description', message: 'What is the description of this module?', store: true, validate: x => x.length > 0 ? true : 'You have to provide a module description' }, { name: 'banner', message: 'Do have a banner image?', type: 'confirm', default: false }, { name: 'bannerPath', message: 'Where is the banner image? Ex: \'img/banner.png\'', type: 'input', when: (answers) => answers.banner }, { name: 'badge', message: 'Do you want a standard-readme compliant badge?', type: 'confirm', default: true }, { name: 'badges', message: 'Do you want a TODO dropped where more badges should be?', type: 'confirm', default: false }, { name: 'longDescription', message: 'Do you want a TODO dropped where your long description should be?', type: 'confirm', default: true }, { name: 'security', message: 'Do you need a prioritized security section?', type: 'confirm', default: false }, { name: 'background', message: 'Do you need a background section?', type: 'confirm', default: false }, { name: 'API', message: 'Do you need an API section?', type: 'confirm', default: false }, { name: 'hostedDomain', message: 'Where is the project hosted?', type: 'input', default: 'github.com', validate: (val) => { return domainRegex.test(val) ? true : 'You must enter a domain where the project is hosted.' } }, { name: 'mainMaintainer', message: 'What is the username of the main maintainer?', type: 'input', default: async () => { let defaultMaintainer = usernameSync() ?? '' try { defaultMaintainer = execSync('git config user.name', { encoding: 'utf8' }).trim() } catch (_) {} return defaultMaintainer }, validate: (val) => val.length > 0 ? true : 'You must name a maintainer' }, { name: 'contributingFile', message: 'Do you have a CONTRIBUTING.md file?', type: 'confirm', default: false }, { name: 'prs', message: 'Are PRs accepted?', type: 'confirm', default: true }, { name: 'mit', message: 'Is an MIT license OK?', type: 'confirm', default: true }, { name: 'license', message: 'What is your license?', type: 'input', validate: (val) => { return val.length > 0 ? true : 'You have to provide a license' }, when: x => !x.mit }, { name: 'licensee', message: 'Who is the License holder (probably your name)?', type: 'input', default: async ({ mainMaintainer }) => { return (await fullName()) ?? mainMaintainer }, validate: x => x.length !== 0 ? true : 'You must attribute the license to someone.' }, { name: 'year', message: 'Use the current year?', type: 'confirm', default: true }, { name: 'diffYear', message: 'What years would you like to specify?', type: 'input', validate: (val) => { return val.length > 0 ? true : 'You must provide a year for the license' }, when: x => !x.year } ] } async prompting () { this.props = await this.prompt(this.promptQuestions) } writing () { this.fs.copyTpl( this.templatePath('README.md'), this.destinationPath('README.md'), this.props ) } } ================================================ FILE: app/templates/README.md ================================================ # <%= moduleName %> <% if (banner) { %> ![banner](<%= bannerPath %>) <% } %><% if (badge) { %> [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)<% } %><% if (badges) { %> TODO: Put more badges here.<% } %> <%= description %> <% if (longDescription) { %>TODO: Fill out this long description. <% } %>## Table of Contents <% if (security) { %>- [Security](#security) <% } %><% if (background) { %>- [Background](#background) <% } %>- [Install](#install) - [Usage](#usage) <% if (API) { %>- [API](#api) <% } %><% if (mainMaintainer) { %>- [Maintainers](#maintainers) <% } %>- [Contributing](#contributing) - [License](#license) <% if (security) { %>## Security <% } %><% if (background) { %>## Background <% } %>## Install ```sh ``` ## Usage ```sh ``` <% if (API) { %>## API <% } %>## Maintainers [@<%= mainMaintainer %>](https://<%= hostedDomain %>/<%= mainMaintainer %>) ## Contributing <% if (contributingFile) { %>See [the contributing file](contributing.md)! <% } %><% if (prs) { %>PRs accepted.<% } %> Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License <% if (mit) { %>MIT<% } %><% if (!mit && license) { %><%= license %><% } %> © <% if (year) { %><%= new Date().getFullYear() %><% } else { %><%= diffYear %><% } %> <%= licensee %> ================================================ FILE: examples/api-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [API](#api) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## API ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/background-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Background](#background) - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Background ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/badges-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) TODO: Put more badges here. description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/banner-readme.md ================================================ # module-name ![banner](test/banner.png) [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/contributing-file-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing See [the contributing file](contributing.md)! PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/default-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/different-license-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License CC BY-SA 4.0 © 2018 Richard McRichface ================================================ FILE: examples/different-year.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2016 Richard McRichface ================================================ FILE: examples/maximal-readme.md ================================================ # example ![banner](test) [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) TODO: Put more badges here. description TODO: Fill out this long description. ## Table of Contents - [Security](#security) - [Background](#background) - [Install](#install) - [Usage](#usage) - [API](#api) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Security ## Background ## Install ```sh ``` ## Usage ```sh ``` ## API ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing See [the contributing file](contributing.md)! PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/no-badge-readme.md ================================================ # module-name description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/no-long-description-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/prs-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: examples/security-readme.md ================================================ # module-name [![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) description TODO: Fill out this long description. ## Table of Contents - [Security](#security) - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [License](#license) ## Security ## Install ```sh ``` ## Usage ```sh ``` ## Maintainers [@RichardLitt](https://github.com/RichardLitt) ## Contributing PRs accepted. Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification. ## License MIT © 2018 Richard McRichface ================================================ FILE: license ================================================ The MIT License (MIT) Copyright (c) 2016 Richard Littauer (burntfen.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: package.json ================================================ { "name": "generator-standard-readme", "version": "1.1.0", "description": "Scaffold out a Standard Readme", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/RichardLitt/generator-standard-readme.git" }, "homepage": "https://github.com/RichardLitt/generator-standard-readme", "bugs": "https://github.com/RichardLitt/generator-standard-readme/issues", "author": { "name": "Richard Littauer", "email": "richard.littauer@gmail.com", "url": "burntfen.com" }, "scripts": { "lint": "standard", "test": "standard && vitest run" }, "keywords": [ "yeoman-generator", "plugin", "boilerplate", "template", "scaffold", "readme", "standard" ], "type": "module", "main": "app/index.js", "dependencies": { "fullname": "^5.0.0", "underscore.string": "^3.3.6", "username": "^7.0.0", "yeoman-environment": "^4.4.3", "yeoman-generator": "^7.5.1" }, "devDependencies": { "standard": "^17.1.2", "vitest": "^3.0.9", "yeoman-test": "^10.1.0" }, "packageManager": "npm@11.2.0", "standard": { "ignore": [ "app/templates/" ] }, "coordinates": [ 45.5191807, -73.5789459 ] } ================================================ FILE: test.js ================================================ import fullName from 'fullname' import assert from 'node:assert/strict' import { existsSync, mkdirSync, readFileSync } from 'node:fs' import { join } from 'node:path' import { beforeEach, describe, test } from 'vitest' import helpers, { result } from 'yeoman-test' import Environment from 'yeoman-environment' import StandardReadmeGenerator from './app' // Keeping default answers from generator synced with defaults used in tests. const generator = new StandardReadmeGenerator([], { resolved: '', namespace: '', env: new Environment({ skipInstall: true }), 'skip-install': true }) // [{ name , default, ... }, ...] => { [name]: default, ... } const defaultAnswers = generator.promptQuestions.reduce((acc, curr) => { if (Object.hasOwn(curr, 'default')) { acc[curr.name] = curr.default } return acc }, {}) const testDefaultAnswers = Object.freeze({ ...defaultAnswers, // Default values for the sake of the tests. moduleName: 'module-name', description: 'description', mainMaintainer: 'RichardLitt', licensee: 'Richard McRichface', year: false, diffYear: '2018' }) describe('standard-readme:app', () => { const customTempDir = join(__dirname, './temp') const exampleDir = join(__dirname, './examples') if (!existsSync(customTempDir)) { mkdirSync(customTempDir, { recursive: true }) } /** @type {import('yeoman-test').RunContext} */ let runContext beforeEach(async () => { await helpers .prepareTemporaryDir({ cwd: customTempDir }) runContext = result .create(join(__dirname, './app')) .withAnswers(testDefaultAnswers, { throwOnMissingAnswer: true }) }) test('generates default README (given test defaults)', async () => { await runContext .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')).toString() ) }) test('generates maximal README when all options/sections are included', async () => { await result .create(join(__dirname, './app')) .withAnswers({ moduleName: 'example', description: 'description', banner: true, bannerPath: 'test', badge: true, badges: true, longDescription: true, security: true, background: true, API: true, mainMaintainer: 'RichardLitt', hostedDomain: 'github.com', contributingFile: true, prs: true, mit: true, // license: 'CC BY-SA 4.0', licensee: 'Richard McRichface', year: false, diffYear: '2018' }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'maximal-readme.md')).toString() ) }) describe('moduleName', () => { const newModuleName = 'foo-module-name' test('generates README with fallback value (`generator.appname`) when omitted', async () => { await runContext .withAnswers({ moduleName: undefined }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')).toString() .replace(testDefaultAnswers.moduleName, runContext.generator.appname) ) }) test('generates README with provided moduleName', async () => { await runContext .withAnswers({ moduleName: newModuleName }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')).toString() .replace(testDefaultAnswers.moduleName, newModuleName) ) }) test('generates README using slugified moduleName', async () => { const moduleNames = [ newModuleName.replace('-', ' '), newModuleName.replace('-', '_'), newModuleName.toUpperCase() ] for (const moduleName of moduleNames) { // Need to reset test environment to avoid prompt abort error // on subsequent loops. await helpers.prepareTemporaryDir({ cwd: customTempDir }) runContext = result .create(join(__dirname, './app')) .withAnswers(testDefaultAnswers) await runContext .withAnswers({ moduleName }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')).toString() .replace(testDefaultAnswers.moduleName, newModuleName) ) } }) }) describe('description', () => { test('fails to generate README when answer is omitted', async () => { const promise = runContext .withAnswers({ description: undefined }) .run() await assert.rejects(promise, { message: 'yeoman-test: question description was asked but answer was not provided' }) }) test('generates README with provided description', async () => { const newDescription = 'foo description' await runContext.withAnswers({ description: newDescription }) assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')).toString() .replace(testDefaultAnswers.description, newDescription) ) }) }) describe('banner/bannerPath', () => { test('fails to generate if only banner is true', async () => { const promise = runContext .withAnswers({ banner: true }) .run() await assert.rejects(promise, { message: 'yeoman-test: question bannerPath was asked but answer was not provided' }) }) test('generates default README if only bannerPath is specified', async () => { await runContext .withAnswers({ bannerPath: 'test/banner.png' }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')).toString() ) }) test('generates README with provided banner', async () => { await runContext .withAnswers({ banner: true, bannerPath: 'test/banner.png' }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'banner-readme.md')).toString() ) }) }) describe('badge/badges', () => { test('generates README without badge', async () => { await runContext .withAnswers({ badge: false }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'no-badge-readme.md')).toString() ) }) test('generates README with badges TODO', async () => { await runContext .withAnswers({ badges: true }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'badges-readme.md')).toString() ) }) }) describe('longDescription', () => { test('generates README without TODO for long description', async () => { await runContext .withAnswers({ longDescription: false }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'no-long-description-readme.md')).toString() ) }) }) describe('security', () => { test('generates README with security section', async () => { await runContext .withAnswers({ security: true }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'security-readme.md')).toString() ) }) }) describe('background', () => { test('generates README with background section', async () => { await runContext .withAnswers({ background: true }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'background-readme.md')).toString() ) }) }) describe('API', () => { test('generates README with API section', async () => { await runContext .withAnswers({ API: true }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'api-readme.md')).toString() ) }) }) describe('hostedDomain', () => { test('generates README with specified hosted domain', async () => { await runContext .withAnswers({ hostedDomain: 'gitlab.com' }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')) .toString() .replace( '[@RichardLitt](https://github.com/RichardLitt)', '[@RichardLitt](https://gitlab.com/RichardLitt)' ) ) }) }) describe('mainMaintainer', () => { test('generates README when answer is omitted', async () => { await runContext .withAnswers({ mainMaintainer: undefined }) .run() const expectedMaintainer = await defaultAnswers.mainMaintainer() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')) .toString() .replace( `[@${testDefaultAnswers.mainMaintainer}](https://github.com/${testDefaultAnswers.mainMaintainer})`, `[@${expectedMaintainer}](https://github.com/${expectedMaintainer})` ) ) }) }) describe('contributingFile', () => { test('generates README with contributing file', async () => { await runContext .withAnswers({ contributingFile: true }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'contributing-file-readme.md')).toString() ) }) }) describe('prs', () => { test('generates README when prs is omitted', async () => { await runContext .withAnswers({ prs: false }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'prs-readme.md')).toString() ) }) }) describe('mit/license/licensee', () => { test('fails to generate README when `mit` is false and no other license is specified', async () => { const promise = runContext .withAnswers({ mit: false, license: undefined }) .run() await assert.rejects(promise, { message: 'yeoman-test: question license was asked but answer was not provided' }) }) test('generates README with license different from MIT', async () => { await runContext .withAnswers({ mit: false, license: 'CC BY-SA 4.0' }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'different-license-readme.md')).toString() ) }) test('generates README defaulting to MIT license, even when other license specified', async () => { await runContext .withAnswers({ mit: true, license: 'CC BY-SA 4.0' }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')).toString() ) }) test('generates README with suggested licensee full name', async () => { await runContext .withAnswers({ licensee: undefined }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')) .toString() .replace( 'Richard McRichface', (await fullName()) ?? (await testDefaultAnswers.mainMaintainer) ) ) }) }) describe('year', () => { test('fails to generate README when present year not used and diff year not specified', async () => { const promise = runContext .withAnswers({ year: false, diffYear: undefined }) .run() await assert.rejects(promise, { message: 'yeoman-test: question diffYear was asked but answer was not provided' }) }) test('generates README with provided year', async () => { await runContext .withAnswers({ year: false, diffYear: '2016' }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'different-year.md')).toString() ) }) test('generates README without different year when present year is confirmed', async () => { await runContext .withAnswers({ year: true, diffYear: '2016' }) .run() assert.strictEqual( readFileSync(join(customTempDir, 'README.md')).toString(), readFileSync(join(exampleDir, 'default-readme.md')).toString() .replace('2018', new Date().getFullYear()) ) }) }) }) ================================================ FILE: vitest.config.js ================================================ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { include: ['**/*test.js'], onConsoleLog (log, type) { // Suppress expected stderr messages for test cases w/ missing answers. if ( type === 'stderr' && /yeoman-test: question \w+ was asked but answer was not provided/.test( log ) ) { return false } return true } } })