From 5b38e777084d1e55842cfd17bc71c6dafaf26a6f Mon Sep 17 00:00:00 2001 From: Ken Herring Date: Tue, 29 Oct 2024 20:37:12 -0400 Subject: [PATCH] Gracefully handle rcode compiled with the `MIN-SIZE` option (#222) --- .gitattributes | 2 + resources/ablunit-test-profile.detail.jsonc | 2 + src/ABLDebugLines.ts | 16 ++- src/ABLPropath.ts | 2 +- src/ABLUnitCommon.ts | 6 +- src/ABLUnitRun.ts | 9 +- src/extension.ts | 3 +- src/parse/RCodeParser.ts | 3 +- src/parse/ResultsParser.ts | 24 +++-- test/suites/proj1.test.ts | 97 ++++++++++++++++--- test/testCommon.ts | 97 ++++++++++++++++--- .../ablunit-test-profile.proj1.15.json | 12 +++ test_projects/proj1/.vscode/tasks.json | 32 ++++++ test_projects/proj1/build.xml | 5 +- test_projects/proj1/import_charset.p | 8 +- test_projects/proj1/include_15.i | 3 + test_projects/proj1/test_15.p | 16 +++ 17 files changed, 289 insertions(+), 48 deletions(-) create mode 100644 test_projects/proj1/.vscode/ablunit-test-profile.proj1.15.json create mode 100644 test_projects/proj1/.vscode/tasks.json create mode 100644 test_projects/proj1/include_15.i create mode 100644 test_projects/proj1/test_15.p diff --git a/.gitattributes b/.gitattributes index b21b418c..613beb03 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,3 +8,5 @@ *.i linguist-language=OpenEdge-ABL *.p linguist-language=OpenEdge-ABL *.w linguist-language=OpenEdge-ABL + +test_projects/proj1/import_charset.p text working-tree-encoding=UTF-8 diff --git a/resources/ablunit-test-profile.detail.jsonc b/resources/ablunit-test-profile.detail.jsonc index a08786f9..337d8f02 100644 --- a/resources/ablunit-test-profile.detail.jsonc +++ b/resources/ablunit-test-profile.detail.jsonc @@ -106,6 +106,8 @@ ////# the command line, and the "profiler.options" file will not be created. ////# * When the "profiler" key is set to null the 'profile.options' file will not ////# be created and the `-profile` option will not be passed to the command line. + ////# * When "enabled" is false, the profiler information is not collection and coverage cannot + ////# be reported. This is not recommended. The option is included here for completeness. ////# ////# See the OpenEdge documentation for more information about these values. ////# * https://docs.progress.com/bundle/openedge-startup-and-parameter-reference/page/Profiler-profile.html diff --git a/src/ABLDebugLines.ts b/src/ABLDebugLines.ts index 44af8aba..f45cd4b7 100644 --- a/src/ABLDebugLines.ts +++ b/src/ABLDebugLines.ts @@ -3,15 +3,20 @@ import { log } from './ChannelLogger' import { ISourceMap, getSourceMapFromRCode } from './parse/RCodeParser' import { getSourceMapFromSource } from './parse/SourceParser' -const maps = new Map() export class ABLDebugLines { + private readonly maps = new Map() + private readonly processingMethodMap = new Map() propath: PropathParser constructor (propath: PropathParser) { this.propath = propath } + getProcessingMethod (debugSource: string) { + return this.processingMethodMap.get(debugSource) + } + async getSourceLine (debugSource: string, debugLine: number) { // if (debugSource.startsWith('OpenEdge.') || debugSource.includes('ABLUnitCore')) { // return undefined @@ -26,19 +31,22 @@ export class ABLDebugLines { log.trace('cannot find debug source in propath (' + debugSource + ')') return undefined } - let map = maps.get(debugSource) + + let map = this.maps.get(debugSource) if (!map) { try { map = await getSourceMapFromRCode(this.propath, await this.propath.getRCodeUri(debugSource)) + this.processingMethodMap.set(debugSource, 'rcode') } catch (e) { - log.debug('cannot parse source map from rcode, falling back to source parser (debugSource=' + debugSource + ', e=' + e + ')') + log.warn('cannot parse source map from rcode, falling back to source parser (debugSource=' + debugSource + ', e=' + e + ')') map = await getSourceMapFromSource(this.propath, debugSource) + this.processingMethodMap.set(debugSource, 'parse') } if (!map) { throw new Error('failed to parse source map (' + debugSource + ')') } else { - maps.set(debugSource, map) + this.maps.set(debugSource, map) } } const ret = map.items.find((line) => line.debugLine === debugLine) diff --git a/src/ABLPropath.ts b/src/ABLPropath.ts index 92ea74b4..50376699 100644 --- a/src/ABLPropath.ts +++ b/src/ABLPropath.ts @@ -147,7 +147,7 @@ export class PropathParser { if (file instanceof Uri) { return this.searchUri(file) } - let relativeFile = file + let relativeFile = isRelativePath(file) ? file : workspace.asRelativePath(Uri.file(file), false) if (!relativeFile.endsWith('.cls') && !relativeFile.endsWith('.p') && !relativeFile.endsWith('.w') && !relativeFile.endsWith('.i')) { relativeFile = relativeFile.replace(/\./g, '/') + '.cls' } diff --git a/src/ABLUnitCommon.ts b/src/ABLUnitCommon.ts index b017eec3..4dd66d56 100644 --- a/src/ABLUnitCommon.ts +++ b/src/ABLUnitCommon.ts @@ -36,7 +36,10 @@ export function doesFileExist (uri: Uri) { return false } -export function deleteFile (file: Uri | Uri[]) { +export function deleteFile (file: Uri | Uri[] | undefined) { + if (!file) { + return + } let files: Uri[] if (!Array.isArray(file)) { files = [file] @@ -48,6 +51,7 @@ export function deleteFile (file: Uri | Uri[]) { if (doesFileExist(file)) { fs.rmSync(file.fsPath) } + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (err) { /* do nothing */ } } } diff --git a/src/ABLUnitRun.ts b/src/ABLUnitRun.ts index 14c80336..f840073a 100644 --- a/src/ABLUnitRun.ts +++ b/src/ABLUnitRun.ts @@ -182,6 +182,14 @@ export const ablunitRun = async (options: TestRun, res: ABLResults, cancellation } const runCommand = () => { + deleteFile(res.cfg.ablunitConfig.profFilenameUri) + // deleteFile(res.cfg.ablunitConfig.config_uri) + deleteFile(res.cfg.ablunitConfig.optionsUri.filenameUri) + deleteFile(res.cfg.ablunitConfig.optionsUri.jsonUri) + deleteFile(res.cfg.ablunitConfig.optionsUri.updateUri) + deleteFile(res.cfg.ablunitConfig.profFilenameUri) + // deleteFile(res.cfg.ablunitConfig.profOptsUri) + log.debug('ablunit command dir=\'' + res.cfg.ablunitConfig.workspaceFolder.uri.fsPath + '\'') if (cancellation?.isCancellationRequested) { log.info('cancellation requested - runCommand') @@ -198,7 +206,6 @@ export const ablunitRun = async (options: TestRun, res: ABLResults, cancellation const updateUri = res.cfg.ablunitConfig.optionsUri.updateUri if (updateUri) { - deleteFile(updateUri) updateParserInit() log.info('watching test run update/event file: ' + updateUri.fsPath) watcherUpdate = workspace.createFileSystemWatcher(updateUri.fsPath) diff --git a/src/extension.ts b/src/extension.ts index 45290538..ba315241 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -109,7 +109,6 @@ export async function activate (context: ExtensionContext) { log.info('loadDetailedCoverage uri="' + fileCoverage.uri.fsPath + '", testRun=' + testRun.name) const d = resultData.get(testRun) const det: FileCoverageDetail[] = [] - if (d) { d.flatMap((r) => { const rec = r.coverage.get(fileCoverage.uri.fsPath) @@ -292,7 +291,7 @@ export async function activate (context: ExtensionContext) { for (const res of data) { log.info('res.filecoverage.length=' + res.filecoverage.length) if (res.filecoverage.length === 0) { - log.warn('no coverage data found (profile data path=' + res.cfg.ablunitConfig.profFilenameUri + ')') + log.warn('no coverage data found (profile data path=' + res.cfg.ablunitConfig.profFilenameUri.fsPath + ')') } res.filecoverage.forEach((c) => { run.addCoverage(c) diff --git a/src/parse/RCodeParser.ts b/src/parse/RCodeParser.ts index 5b0fa440..a525c501 100644 --- a/src/parse/RCodeParser.ts +++ b/src/parse/RCodeParser.ts @@ -2,6 +2,7 @@ import { TextDecoder } from 'util' import { Uri, workspace } from 'vscode' import { PropathParser } from '../ABLPropath' import { log } from '../ChannelLogger' +import { isRelativePath } from 'ABLUnitCommon' const headerLength = 68 @@ -240,7 +241,7 @@ export const getSourceMapFromRCode = (propath: PropathParser, uri: Uri) => { if (sourceNum == undefined) { throw new Error('invalid source number: ' + sourceNum + ' ' + sourceName) } - const sourceUri = Uri.joinPath(propath.workspaceFolder.uri, sourceName) + const sourceUri = isRelativePath(sourceName) ? Uri.joinPath(propath.workspaceFolder.uri, sourceName) : Uri.file(sourceName) sources.push({ sourceName: sourceName.replace(/\\/g, '/'), diff --git a/src/parse/ResultsParser.ts b/src/parse/ResultsParser.ts index 3046f79b..cc2e5cbb 100644 --- a/src/parse/ResultsParser.ts +++ b/src/parse/ResultsParser.ts @@ -92,12 +92,20 @@ export class ABLResultsParser { parseXml (xmlData: string): string { let res: string | undefined - parseString(xmlData, function (err: Error | null, resultsRaw: any) { - if (err) { - throw new Error('error parsing XML file: ' + err) + parseString(xmlData, function (e: Error | null, resultsRaw: unknown) { + if (e) { + log.info('error parsing XML file: ' + e) + throw e } - res = resultsRaw - return String(resultsRaw) + if (!resultsRaw) { + throw new Error('malformed results file (2) - could not parse XML - resultsRaw is null') + } + if (typeof resultsRaw === 'object' && resultsRaw !== null) { + res = JSON.stringify(resultsRaw) + return JSON.stringify(resultsRaw) + } + log.error('resultsRaw=' + JSON.stringify(resultsRaw)) + throw new Error('malformed results file (2) - could not parse XML - resultsRaw is not an object') }) if (!res) { throw new Error('malformed results file (2) - could not parse XML') @@ -105,7 +113,11 @@ export class ABLResultsParser { return res } - async parseSuites (res: any) { + async parseSuites (results: string) { + if (!results) { + throw new Error('malformed results file (1) - res is null') + } + let res = JSON.parse(results) if(!res.testsuites) { log.error('malformed results file (1) - could not find top-level \'testsuites\' node') throw new Error('malformed results file (1) - could not find top-level \'testsuites\' node') diff --git a/test/suites/proj1.test.ts b/test/suites/proj1.test.ts index 9dbefefd..60fc2f56 100644 --- a/test/suites/proj1.test.ts +++ b/test/suites/proj1.test.ts @@ -1,6 +1,6 @@ -import { Selection, commands, window } from 'vscode' +import { Selection, commands, tasks, window } from 'vscode' import { after, afterEach, beforeEach } from 'mocha' -import { Uri, assert, getWorkspaceUri, log, runAllTests, sleep, updateConfig, getTestCount, workspace, suiteSetupCommon, getWorkspaceFolders, oeVersion, runTestAtLine, beforeCommon, updateTestProfile, runTestsInFile } from '../testCommon' +import { Uri, assert, getWorkspaceUri, log, runAllTests, sleep, updateConfig, getTestCount, workspace, suiteSetupCommon, getWorkspaceFolders, oeVersion, runTestAtLine, beforeCommon, updateTestProfile, runTestsInFile, deleteFiles } from '../testCommon' import { getOEVersion } from 'parse/OpenedgeProjectParser' import { execSync } from 'child_process' import * as glob from 'glob' @@ -63,27 +63,27 @@ suite('proj1 - Extension Test Suite', () => { }) test('proj1.2 - output files exist 2 - exclude compileError.p', () => { - return workspace.getConfiguration('ablunit').update('files.exclude', [ '.builder/**', 'compileError.p' ]) + const p = workspace.getConfiguration('ablunit').update('files.exclude', [ '.builder/**', 'compileError.p' ]) .then(() => { return runAllTests() }) .then(() => { - assert.tests.count(30) - assert.tests.passed(24) + assert.tests.count(31) + assert.tests.passed(25) assert.tests.failed(2) assert.tests.errored(3) assert.tests.skipped(1) return true - }, (e: unknown) => { throw e }) - + }, + (e: unknown) => { + throw e + }) + return p }) test('proj1.3 - output files exist 3 - exclude compileError.p as string', async () => { // this isn't officially supported and won't syntac check in the settings.json file(s), but it works await updateConfig('ablunit.files.exclude', 'compileError.p') await runAllTests() - - const resultsJson = Uri.joinPath(workspaceUri, 'results.json') - const testCount = await getTestCount(resultsJson) - assert.equal(testCount, 30) + assert.tests.count(31) }) test('proj1.4 - run test case in file', async () => { @@ -159,7 +159,7 @@ suite('proj1 - Extension Test Suite', () => { test('proj1.9 - check startup parmaeters for -y -yx', async () => { await workspace.fs.copy(Uri.joinPath(workspaceUri, 'openedge-project.proj1.9.json'), Uri.joinPath(workspaceUri, 'openedge-project.json'), { overwrite: true }) - await runTestAtLine('import_charset.p', 64) + await runTestAtLine('import_charset.p', 68) .then(() => { log.info('testing.runAtCursor complete') assert.tests.count(1) @@ -210,8 +210,8 @@ suite('proj1 - Extension Test Suite', () => { // run tests and assert test count await runAllTests() .then(() => { - assert.tests.count(29) - assert.tests.passed(23) + assert.tests.count(30) + assert.tests.passed(24) assert.tests.failed(2) assert.tests.errored(3) assert.tests.skipped(1) @@ -258,7 +258,7 @@ suite('proj1 - Extension Test Suite', () => { // default profile passes, but there is an 'ablunit' profile which is used first test('proj1.14 - run profile \'ablunit\'', async () => { - return workspace.fs.copy(Uri.joinPath(workspaceUri, 'openedge-project.proj1.14.json'), Uri.joinPath(workspaceUri, 'openedge-project.json'), { overwrite: true }) + const p = workspace.fs.copy(Uri.joinPath(workspaceUri, 'openedge-project.proj1.14.json'), Uri.joinPath(workspaceUri, 'openedge-project.json'), { overwrite: true }) .then(() => { return runTestsInFile('test_14.p') }) .then(() => { assert.tests.count(1) @@ -271,7 +271,74 @@ suite('proj1 - Extension Test Suite', () => { log.error('e=' + e) throw e }) + return p + }) + test('proj1.15A - compile option without MIN-SIZE without xref', () => { + const p = compileWithTaskAndCoverage('ant build') + .then(() => { + assert.linesExecuted('test_15.p', [9, 10, 13]) + assert.coverageProcessingMethod('test_15.p', 'rcode') + return true + }) + return p + }) + + test('proj1.15B - compile option with MIN-SIZE without xref', () => { + const p = compileWithTaskAndCoverage('ant build min-size') + .then(() => { + assert.linesExecuted('test_15.p', [9, 10, 13]) + assert.coverageProcessingMethod('test_15.p', 'parse') + return true + }) + return p }) }) + +async function compileWithTaskAndCoverage (taskName: string) { + deleteFiles([ + Uri.joinPath(workspaceUri, 'test_15.r'), + Uri.joinPath(workspaceUri, 'openedge-project.json'), + ]) + await workspace.fs.copy(Uri.joinPath(workspaceUri, '.vscode', 'ablunit-test-profile.proj1.15.json'), Uri.joinPath(workspaceUri, '.vscode', 'ablunit-test-profile.json'), { overwrite: true }) + + await tasks.fetchTasks() + .then((r) => { + log.info('fetchTasks complete') + for (const task of r) { + log.info('task.name=' + task.name) + } + const task = r.find((t) => t.name === taskName) + log.info('task=' + task?.name) + if (!task) { + throw new Error('task not found') + } + return tasks.executeTask(task) + }).then((r) => { + log.info('executeTask started (r=' + JSON.stringify(r, null, 2) + ')') + }, (e: unknown) => { + log.error('error=' + e) + throw e + }) + await new Promise((resolve) => { + tasks.onDidEndTask((t) => { + log.info('task complete t.name=' + t.execution.task.name) + setTimeout(() => { resolve(true) }, 500) + }) + }) + + const testRcode = Uri.joinPath(workspaceUri, 'test_15.r') + log.info('testRcode=' + testRcode.fsPath) + assert.fileExists(testRcode) + log.info('compile complete!') + + await runTestsInFile('test_15.p', 1, true) + .then(() => { + assert.tests.count(1) + assert.tests.passed(1) + assert.tests.failed(0) + assert.tests.errored(0) + assert.tests.skipped(0) + }) +} diff --git a/test/testCommon.ts b/test/testCommon.ts index c277ba97..a8914da4 100644 --- a/test/testCommon.ts +++ b/test/testCommon.ts @@ -229,10 +229,34 @@ export function installExtension (extname = 'riversidesoftware.openedge-abl-lsp' } export function deleteFile (file: Uri | string) { - if (typeof file === 'string') { - file = Uri.joinPath(getWorkspaceUri(), file) + deleteFiles(file) +} + +export function deleteFiles (files: Uri | Uri[] | string | string[]) { + const uris: Uri[] = [] + if (files instanceof Array) { + for (const file of files) { + if (file instanceof Uri) { + uris.push(file) + continue + } + if (isRelativePath(file)) { + uris.push(Uri.joinPath(getWorkspaceUri(), file)) + continue + } + uris.push(Uri.file(file)) + } + } else if (files instanceof Uri) { + uris.push(files) + } else if (isRelativePath(files)) { + uris.push(Uri.joinPath(getWorkspaceUri(), files)) + } else { + uris.push(Uri.file(files)) + } + + for (const uri of uris) { + deleteFileCommon(uri) } - deleteFileCommon(file) } export function sleep2 (time = 10, msg?: string | null) { @@ -578,12 +602,15 @@ export function runAllTestsWithCoverage () { return runAllTests(true, true, true) } -export function runTestsInFile (filename: string, len = 1) { +export function runTestsInFile (filename: string, len = 1, coverage = false) { const testpath = toUri(filename) log.info('runnings tests in file ' + testpath.fsPath) return commands.executeCommand('vscode.open', testpath) .then(() => { runTestsDuration = new Duration('runTestsInFile') + if (coverage) { + return commands.executeCommand('testing.coverageCurrentFile') + } return commands.executeCommand('testing.runCurrentFile') }, (e) => { throw e @@ -740,7 +767,7 @@ function getConfigDefaultValue (key: string) { return undefined } -export function updateConfig (key: string, value: unknown, configurationTarget?: boolean | vscode.ConfigurationTarget | null | undefined) { +export function updateConfig (key: string, value: unknown, configurationTarget?: boolean | vscode.ConfigurationTarget | null) { const sectionArr = key.split('.') const section1 = sectionArr.shift() const section2 = sectionArr.join('.') @@ -904,7 +931,7 @@ function getType (item: TestItem | undefined) { } } -export function getTestControllerItemCount (type?: 'ABLTestDir' | 'ABLTestFile' | 'ABLTestCase' | undefined) { +export function getTestControllerItemCount (type?: 'ABLTestDir' | 'ABLTestFile' | 'ABLTestCase') { return getTestController() .then((ctrl) => { const items = gatherAllTestItems(ctrl.items) @@ -1106,7 +1133,7 @@ export const assert = { notStrictEqual: assertParent.notStrictEqual, deepEqual: assertParent.deepEqual, notDeepEqual: assertParent.notDeepEqual, - fail: assertParent.fail, + fail: (message: string) => { assertParent.fail(message) }, ok: (value: unknown) => { assertParent.ok(value) }, @@ -1132,6 +1159,7 @@ export const assert = { return }) } catch (e) { + log.info('exception thrown as expected: ' + e + '. message=' + message) assertParent.ok(true) } }, @@ -1186,7 +1214,47 @@ export const assert = { }, tests: new AssertTestResults(), - linesExecuted (file: Uri | string, lines: number[] | number, notExecuted = false) { + coverageProcessingMethod (debugSourceFile: string, expected: 'rcode' | 'parse') { + log.info('200') + if (! recentResults) { + log.info('201') + assert.fail('recentResults is undefined') + log.info('202') + return + } + + const res = recentResults[recentResults.length - 1].ablResults + if (!res) { + throw new Error('no results found') + } + + const actual = res.debugLines?.getProcessingMethod(debugSourceFile) + assert.equal(actual, expected) + }, + + coveredFiles (expected: number) { + if (!recentResults) { + assert.fail('recentResults is undefined') + return + } + if (recentResults.length == 0) { + assert.fail('recentResults.length is 0') + return + } + + const actual = recentResults[recentResults.length - 1].coverage.size + let msg = 'covered files (' + actual + ') != ' + expected + if (actual != expected) { + msg += '\nfound:' + for (const c of recentResults[recentResults.length - 1].coverage) { + msg += '\n * ' + c[0] + // log.info('covered file: ' + c[0]) + } + } + assert.equal(actual, expected, msg) + }, + + linesExecuted (file: Uri | string, lines: number[] | number, executed = true) { if (!(file instanceof Uri)) { file = toUri(file) } @@ -1202,7 +1270,7 @@ export const assert = { return } - const coverage = recentResults[0].coverage.get(file.fsPath) + const coverage = recentResults[recentResults.length - 1].coverage.get(file.fsPath) if (!coverage) { assert.fail('no coverage found for ' + file.fsPath) return @@ -1217,15 +1285,16 @@ export const assert = { assert.fail('expected number for coverage executed but got boolean (' + lineCoverage.executed + ')') return } - if (notExecuted) { - assert.equal(lineCoverage?.executed, 0, 'line ' + line + ' in ' + file.fsPath + ' was executed') + if (!executed) { + assert.equal(lineCoverage?.executed, 0, 'line ' + line + ' in ' + file.fsPath + ' was executed (lineCoverage.executed=' + lineCoverage?.executed + ')') } else { - assert.greater(lineCoverage?.executed, 0, 'line ' + line + ' in ' + file.fsPath + ' was not executed') + assert.greater(lineCoverage?.executed, 0, 'line ' + line + ' in ' + file.fsPath + ' was not executed (lineCoverage.executed=' + lineCoverage?.executed + ')') } } }, + linesNotExecuted (file: Uri | string, lines: number[] | number) { - assert.linesExecuted(file, lines, true) + assert.linesExecuted(file, lines, false) } } @@ -1249,7 +1318,7 @@ export function beforeProj7 () { return Promise.all(proms) }).then(() => { log.info('beforeProj7 complete!') - return + return true }) } diff --git a/test_projects/proj1/.vscode/ablunit-test-profile.proj1.15.json b/test_projects/proj1/.vscode/ablunit-test-profile.proj1.15.json new file mode 100644 index 00000000..949574bd --- /dev/null +++ b/test_projects/proj1/.vscode/ablunit-test-profile.proj1.15.json @@ -0,0 +1,12 @@ +{ + "configurations": [ + { + "tempDir": "${workspaceFolder}", + "options": { + "output": { + "writeJson": true + } + } + } + ] +} diff --git a/test_projects/proj1/.vscode/tasks.json b/test_projects/proj1/.vscode/tasks.json new file mode 100644 index 00000000..0db88707 --- /dev/null +++ b/test_projects/proj1/.vscode/tasks.json @@ -0,0 +1,32 @@ +{ + "tasks": [ + { + "label": "ant build", + "type": "shell", + "command": "${env:DLC}/ant/bin/ant compile -Dxref=false", + "linux": { + "command": "ant compile -Dxref=false" + }, + "args": [], + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "ant build min-size", + "type": "shell", + "command": "${env:DLC}/ant/bin/ant compile -DminSize=true -Dxref=false", + "linux": { + "command": "ant compile -DminSize=true -Dxref=false" + }, + "args": [], + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + } + ] +} diff --git a/test_projects/proj1/build.xml b/test_projects/proj1/build.xml index a22fdaa3..bc16f01b 100644 --- a/test_projects/proj1/build.xml +++ b/test_projects/proj1/build.xml @@ -26,9 +26,12 @@ + + Compiling... + minSize=${minSize} - + diff --git a/test_projects/proj1/import_charset.p b/test_projects/proj1/import_charset.p index ccb1bff0..a0d036d0 100644 --- a/test_projects/proj1/import_charset.p +++ b/test_projects/proj1/import_charset.p @@ -15,8 +15,8 @@ procedure euro_symbol_out_and_in : define variable testVar as character no-undo. define variable impVal as character no-undo. - message "session:cpinternal=" + session:cpinternal. - message "session:cpstream=" + session:cpstream. + message "1 session:cpinternal=" + session:cpinternal. + message "1 session:cpstream=" + session:cpstream. testVar = "euro symbol: €". @@ -24,6 +24,10 @@ procedure euro_symbol_out_and_in : put stream oStream unformatted testVar. output stream oStream close. + // session:cpstream = session:cpinternal. + message "2 session:cpinternal=" + session:cpinternal. + message "2 session:cpstream=" + session:cpstream. + input stream iStream from "./import_charset.out". import stream iStream unformatted impVal. input stream iStream close. diff --git a/test_projects/proj1/include_15.i b/test_projects/proj1/include_15.i new file mode 100644 index 00000000..39ee348d --- /dev/null +++ b/test_projects/proj1/include_15.i @@ -0,0 +1,3 @@ +message "in include_15.i". +define variable cnt as integer no-undo. +cnt = 1. \ No newline at end of file diff --git a/test_projects/proj1/test_15.p b/test_projects/proj1/test_15.p new file mode 100644 index 00000000..39720b19 --- /dev/null +++ b/test_projects/proj1/test_15.p @@ -0,0 +1,16 @@ +block-level on error undo, throw. +using OpenEdge.Core.Assert. + +message 'test_15.p starting'. + +{include_15.i} + +@Test. +procedure test_A : + if true then + message "in test_A". + else + message "this does not execute". + Assert:isTrue(true). +end procedure. +