From 6e6dd93c460f447375cc738eb3e8a87244735698 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Thu, 23 Nov 2023 20:45:09 -0300 Subject: [PATCH] Add test for simple program --- .../run-examples/basic-example/example.wlk | 5 ++ .../basic-example/mainExample.wpgm | 14 +++++ src/commands/run.ts | 21 +++++--- test/run.test.ts | 52 ++++++++++++------- 4 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 examples/run-examples/basic-example/mainExample.wpgm diff --git a/examples/run-examples/basic-example/example.wlk b/examples/run-examples/basic-example/example.wlk index cd96e18..4be5144 100644 --- a/examples/run-examples/basic-example/example.wlk +++ b/examples/run-examples/basic-example/example.wlk @@ -3,7 +3,12 @@ object pepita { method energy() = energy + method eat(grams) { + energy = energy + grams * 10 + } + method fly(minutes) { energy = energy - minutes * 3 } + } \ No newline at end of file diff --git a/examples/run-examples/basic-example/mainExample.wpgm b/examples/run-examples/basic-example/mainExample.wpgm new file mode 100644 index 0000000..dc75868 --- /dev/null +++ b/examples/run-examples/basic-example/mainExample.wpgm @@ -0,0 +1,14 @@ +import example.pepita + +program PepitaProgram { + + pepita.fly(10) + console.println("Pepita empieza con " + pepita.energy()) + console.println("Vuela") + pepita.fly(10) + console.println(pepita.energy()) + console.println("Come") + pepita.eat(25) + console.println(pepita.energy()) + +} \ No newline at end of file diff --git a/src/commands/run.ts b/src/commands/run.ts index b14e63a..21c02a1 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -16,15 +16,17 @@ const { time, timeEnd } = console type Options = { project: string - assets: string | undefined + assets?: string skipValidations: boolean - port: string + port?: string game: boolean } // TODO: Decouple io from getInterpreter let timer = 0 +const DEFAULT_PORT = '3000' + export default async function (programFQN: Name, { project, assets, skipValidations, port, game }: Options): Promise { try { logger.info(`Running ${valueDescription(programFQN)} ${game ? 'as a game' : 'as a program'} on ${valueDescription(project)}`) @@ -34,17 +36,21 @@ export default async function (programFQN: Name, { project, assets, skipValidati logger.info(`Assets folder ${join(project, assetsFolder)}`) } - const environment = link([drawDefinition()], await buildEnvironmentForProject(project)) + let environment = await buildEnvironmentForProject(project) + if (game) { + environment = link([drawDefinition()], environment) + } validateEnvironment(environment, skipValidations) logger.info(`Running ${valueDescription(programFQN)}...${ENTER}`) const debug = logger.getLevel() <= logger.levels.DEBUG + // ??? -> no es otra la descripción if (debug) time(successDescription('Run finalized successfully')) let io: Server | undefined = undefined if (game) { - io = initializeGameClient({ project, assetsFolder, port }) + io = initializeGameClient({ project, assetsFolder, port: port ?? DEFAULT_PORT }) } const interpreter = game ? getGameInterpreter(environment, io!) : interpret(environment, { ...natives }) @@ -56,6 +62,7 @@ export default async function (programFQN: Name, { project, assets, skipValidati if (debug) timeEnd(successDescription('Run finalized successfully')) + if (!game) process.exit(0) } catch (error: any) { handleError(error) if (!game) process.exit(21) @@ -86,8 +93,9 @@ export const getGameInterpreter = (environment: Environment, io: Server): Interp ]) io.emit('updateSound', { soundInstances: mappedSounds }) } catch (error: any) { - if (error instanceof WollokException) logger.error(failureDescription(error.message)) - // TODO: si no es WollokException igual deberíamos loguear un error más general + logger.error(failureDescription(error instanceof WollokException ? error.message : 'Exception while executing the program')) + const debug = logger.getLevel() <= logger.levels.DEBUG + if (debug) logger.error(error) interpreter.send('stop', gameSingleton) } }, @@ -115,7 +123,6 @@ export const initializeGameClient = ({ project, assetsFolder, port }: { project: express.static(assetsFolder ?? project, { maxAge: '1d' })) const soundsFolder = getSoundsFolder(project, assetsFolder) - // TODO: testear que no esté pisando if (soundsFolder !== assetsFolder) { app.use(cors({ allowedHeaders: '*' }), express.static(soundsFolder, { maxAge: '1d' })) } diff --git a/test/run.test.ts b/test/run.test.ts index 6850ed1..c713d87 100644 --- a/test/run.test.ts +++ b/test/run.test.ts @@ -1,33 +1,17 @@ import chai from 'chai' import { join } from 'path' -import { getSoundsFolder, getAssetsFolder } from '../src/commands/run' +import run, { getSoundsFolder, getAssetsFolder } from '../src/commands/run' import { mkdirSync, rmdirSync } from 'fs' +import sinon from 'sinon' +import { spyCalledWithSubstring } from './assertions' chai.should() const expect = chai.expect const project = join('examples', 'run-examples', 'basic-example') -// const baseOptions: Options = { -// project, -// noCI: false, -// noTest: false, -// game: false, -// } - describe('testing run', () => { - // let processExitSpy: sinon.SinonStub - - // beforeEach(() => { - // processExitSpy = sinon.stub(process, 'exit') - // }) - - // afterEach(() => { - // rmSync(project, { recursive: true, force: true }) - // sinon.restore() - // }) - describe('getAssetsPath', () => { it('should return assets folder from options if it exists', () => { expect(getAssetsFolder(project, 'myAssets')).to.equal('myAssets') @@ -67,4 +51,34 @@ describe('testing run', () => { }) + describe('run a simple program', () => { + + let processExitSpy: sinon.SinonStub + let consoleLogSpy: sinon.SinonStub + + beforeEach(() => { + processExitSpy = sinon.stub(process, 'exit') + consoleLogSpy = sinon.stub(console, 'log') + }) + + afterEach(() => { + sinon.restore() + }) + + + it ('should work if program has no errors', async () => { + await run('mainExample.PepitaProgram', { + project: join('examples', 'run-examples', 'basic-example'), + skipValidations: false, + game: false, + }) + expect(spyCalledWithSubstring(consoleLogSpy, 'Pepita empieza con 70')).to.be.true + expect(spyCalledWithSubstring(consoleLogSpy, 'Vuela')).to.be.true + expect(spyCalledWithSubstring(consoleLogSpy, '40')).to.be.true + expect(spyCalledWithSubstring(consoleLogSpy, 'Come')).to.be.true + expect(spyCalledWithSubstring(consoleLogSpy, '290')).to.be.true + expect(processExitSpy.calledWith(0)).to.be.true + }) + }) + }) \ No newline at end of file