From d5c405ad44a15d57348e7a2df222c35d4eff67b4 Mon Sep 17 00:00:00 2001 From: nmigueles Date: Fri, 20 Sep 2024 22:57:03 -0300 Subject: [PATCH] init:folder-argument --- src/commands/init.ts | 6 ++-- src/index.ts | 5 +-- src/utils.ts | 6 ++-- test/assertions.ts | 32 +++++++++++++----- test/init.test.ts | 78 ++++++++++++++++++++++++++------------------ 5 files changed, 81 insertions(+), 46 deletions(-) diff --git a/src/commands/init.ts b/src/commands/init.ts index a954396..8919c28 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -14,7 +14,9 @@ export type Options = { game: boolean, } -export default function ({ project, name, noTest = false, noCI = false, game = false }: Options): void { +export default function (folder: string | undefined, { project: _project, name, noTest = false, noCI = false, game = false }: Options): void { + const project = join(_project, folder ?? '') + // Initialization if (existsSync(join(project, 'package.json'))) { logger.info(yellow(bold(`🚨 There is already a project inside ${project} folder`))) @@ -97,7 +99,7 @@ describe "group of tests for pepita" { }` -const gameDefinition = (exampleName: string) => `import wollok.game.* +const gameDefinition = (exampleName: string) => `import wollok.game.* import ${exampleName}.pepita diff --git a/src/index.ts b/src/index.ts index 07e9f20..150f8db 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,14 +5,14 @@ import run from './commands/run' import test from './commands/test' import init from './commands/init' import logger from 'loglevel' -import { version } from '../package.json' +import { version } from '../package.json' import { cyan } from 'chalk' const program = new Command() .name('wollok') .description('Wollok Language command line interpreter tool') .version(cyan(version)) - .hook('preAction', (thisCommand, actionCommand) => { + .hook('preAction', (thisCommand, actionCommand) => { actionCommand.opts().verbose ? logger.setLevel('DEBUG') : logger.setLevel('INFO') }) @@ -55,6 +55,7 @@ program.command('repl') program.command('init') .description('Create a new Wollok project') + .argument('[folder]', 'folder name, if not provided, the current folder will be used') .option('-p, --project [filter]', 'path to project', process.cwd()) .option('-n, --name [name]', 'name of the example', undefined) .option('-g, --game', 'adds a game program to the project', false) diff --git a/src/utils.ts b/src/utils.ts index da8007d..cd56dea 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -39,7 +39,7 @@ export type FileContent = { export const createFolderIfNotExists = (folder: string): void => { if (!existsSync(folder)) { - mkdirSync(folder) + mkdirSync(folder, { recursive: true }) } } @@ -67,10 +67,10 @@ export const validateEnvironment = (environment: Environment, skipValidations: b try { const problems = validate(environment) problems.forEach(problem => logger.info(problemDescription(problem))) - if(!problems.length) { + if (!problems.length) { logger.info(successDescription('No problems found building the environment!')) } - else if(problems.some(_ => _.level === 'error')) { + else if (problems.some(_ => _.level === 'error')) { throw new Error('Aborting run due to validation errors!') } } catch (error: any) { diff --git a/test/assertions.ts b/test/assertions.ts index 8c5145c..331d762 100644 --- a/test/assertions.ts +++ b/test/assertions.ts @@ -1,17 +1,33 @@ import { ElementDefinition } from 'cytoscape' +import { existsSync } from 'fs' type ElementDefinitionQuery = Partial declare global { - export namespace Chai { - interface Assertion { // TODO: split into the separate modules - connect: (label: string, sourceLabel: string, targetLabel: string, width?: number, style?: string ) => Assertion - } + export namespace Chai { + interface Assertion { // TODO: split into the separate modules + connect: (label: string, sourceLabel: string, targetLabel: string, width?: number, style?: string) => Assertion + pathExists(path: string): Assertion + } - interface Include { - nodeWith: (query: ElementDefinitionQuery) => Assertion - } + interface Include { + nodeWith: (query: ElementDefinitionQuery) => Assertion } + } +} + +export const pathAssertions: Chai.ChaiPlugin = (chai) => { + const { Assertion } = chai + + Assertion.addMethod('pathExists', function (path) { + const exists = existsSync(path) + this.assert( + exists, + 'expected path #{this} to exist', + 'expected path #{this} to not exist', + path + ) + }) } export const diagramAssertions: Chai.ChaiPlugin = (chai) => { @@ -34,7 +50,7 @@ export const diagramAssertions: Chai.ChaiPlugin = (chai) => { new Assertion(diagram).to.deep.contain(query) }) - Assertion.addMethod('connect', function ( label: string, source: string, target: string, width = 1, style = 'solid') { + Assertion.addMethod('connect', function (label: string, source: string, target: string, width = 1, style = 'solid') { const { data: { id: sourceId } } = this._obj.find(({ data }: any) => data.label === source) const { data: { id: targetId } } = this._obj.find(({ data }: any) => data.label === target) const connection = { diff --git a/test/init.test.ts b/test/init.test.ts index adc585b..cbe13c6 100644 --- a/test/init.test.ts +++ b/test/init.test.ts @@ -1,14 +1,19 @@ -import chai from 'chai' +import chai, { use } from 'chai' import { join } from 'path' -import { existsSync, readFileSync, rmSync } from 'fs' +import { readFileSync, rmSync } from 'fs' import sinon from 'sinon' import init, { Options } from '../src/commands/init' import test from '../src/commands/test' +import { pathAssertions } from './assertions' chai.should() + const expect = chai.expect +use(pathAssertions) const project = join('examples', 'init-examples', 'basic-example') +const customFolderName = 'custom-folder' +const customFolderProject = join(project, customFolderName) const GITHUB_FOLDER = join('.github', 'workflows') const baseOptions: Options = { @@ -28,19 +33,20 @@ describe('testing init', () => { afterEach(() => { rmSync(project, { recursive: true, force: true }) + rmSync(customFolderProject, { recursive: true, force: true }) sinon.restore() }) it('should create files successfully for default values: ci, no game & example name', async () => { - init(baseOptions) - - expect(existsSync(join(project, 'example.wlk'))).to.be.true - expect(existsSync(join(project, 'testExample.wtest'))).to.be.true - expect(existsSync(join(project, 'package.json'))).to.be.true - expect(existsSync(join(project, GITHUB_FOLDER, 'ci.yml'))).to.be.true - expect(existsSync(join(project, 'README.md'))).to.be.true - expect(existsSync(join(project, '.gitignore'))).to.be.true - expect(existsSync(join(project, 'mainExample.wpgm'))).to.be.false + init(undefined, baseOptions) + + expect(join(project, 'example.wlk')).to.pathExists + expect(join(project, 'testExample.wtest')).to.pathExists + expect(join(project, 'package.json')).to.pathExists + expect(join(project, GITHUB_FOLDER, 'ci.yml')).to.pathExists + expect(join(project, 'README.md')).to.pathExists + expect(join(project, '.gitignore')).to.pathExists + expect(join(project, 'mainExample.wpgm')).to.pathExists expect(getResourceFolder()).to.be.undefined await test(undefined, { @@ -54,53 +60,63 @@ describe('testing init', () => { }) it('should create files successfully for game project with ci & custom example name', () => { - init({ + init(undefined, { ...baseOptions, game: true, name: 'pepita', }) - expect(existsSync(join(project, 'pepita.wlk'))).to.be.true - expect(existsSync(join(project, 'testPepita.wtest'))).to.be.true - expect(existsSync(join(project, 'mainPepita.wpgm'))).to.be.true - expect(existsSync(join(project, 'package.json'))).to.be.true - expect(existsSync(join(project, GITHUB_FOLDER, 'ci.yml'))).to.be.true - expect(existsSync(join(project, '.gitignore'))).to.be.true - expect(existsSync(join(project, 'README.md'))).to.be.true + expect(join(project, 'pepita.wlk')).to.pathExists + expect(join(project, 'testPepita.wtest')).to.pathExists + expect(join(project, 'mainPepita.wpgm')).to.pathExists + expect(join(project, 'package.json')).to.pathExists + expect(join(project, GITHUB_FOLDER, 'ci.yml')).to.pathExists + expect(join(project, 'README.md')).to.pathExists + expect(join(project, '.gitignore')).to.pathExists expect(getResourceFolder()).to.be.equal('assets') }) it('should create files successfully for game project with no ci & no test custom example name', async () => { - init({ + init(undefined, { ...baseOptions, noCI: true, noTest: true, name: 'pepita', }) - expect(existsSync(join(project, 'pepita.wlk'))).to.be.true - expect(existsSync(join(project, 'testPepita.wtest'))).to.be.false - expect(existsSync(join(project, 'package.json'))).to.be.true - expect(existsSync(join(project, 'mainPepita.wpgm'))).to.be.false - expect(existsSync(join(project, GITHUB_FOLDER, 'ci.yml'))).to.be.false - expect(existsSync(join(project, '.gitignore'))).to.be.true - expect(existsSync(join(project, 'README.md'))).to.be.true + expect(join(project, 'pepita.wlk')).to.pathExists + expect(join(project, 'testPepita.wtest')).to.pathExists + expect(join(project, 'package.json')).to.pathExists + expect(join(project, 'mainPepita.wpgm')).to.pathExists + expect(join(project, GITHUB_FOLDER, 'ci.yml')).to.pathExists + expect(join(project, '.gitignore')).to.pathExists + expect(join(project, 'README.md')).to.pathExists + }) + + it('should create files successfully with an argument for the folder name working in combination with project option', async () => { + init(customFolderName, baseOptions) + + expect(join(customFolderProject, 'pepita.wlk')).to.pathExists + expect(join(customFolderProject, 'testPepita.wtest')).to.pathExists + expect(join(customFolderProject, 'mainPepita.wpgm')).to.pathExists + expect(join(customFolderProject, 'package.json')).to.pathExists + expect(join(customFolderProject, GITHUB_FOLDER, 'ci.yml')).to.pathExists + expect(join(customFolderProject, 'README.md')).to.pathExists + expect(join(customFolderProject, '.gitignore')).to.pathExists }) it('should exit with code 1 if folder already exists', () => { - init({ + init(undefined, { ...baseOptions, project: join('examples', 'init-examples', 'existing-folder'), }) expect(processExitSpy.calledWith(1)).to.be.true }) - - }) const getResourceFolder = () => { - const packageJson = readFileSync(join(project, 'package.json'), 'utf8') + const packageJson = readFileSync(join(project, 'package.json'), 'utf8') const { resourceFolder } = JSON.parse(packageJson) return resourceFolder } \ No newline at end of file