Skip to content

Commit

Permalink
Merge pull request #12775 from keymanapp/chore/rename-test-callbacks
Browse files Browse the repository at this point in the history
chore: rename TestCompilerCallbacks.ts
  • Loading branch information
mcdurdin authored Dec 5, 2024
2 parents 88f20d7 + 389ef7f commit 72d0bac
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 239 deletions.
168 changes: 168 additions & 0 deletions developer/src/common/web/test-helpers/TestCompilerCallbacks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import * as fs from 'fs';
import * as path from 'path';
import { CompilerEvent, CompilerCallbacks, CompilerPathCallbacks, CompilerFileSystemCallbacks,
CompilerError, CompilerNetAsyncCallbacks, DefaultCompilerFileSystemAsyncCallbacks,
CompilerFileSystemAsyncCallbacks } from '@keymanapp/developer-utils';
import { fileURLToPath } from 'url';

const { TEST_SAVE_FIXTURES } = process.env;

/**
* A CompilerCallbacks implementation for testing
*/
export class TestCompilerCallbacks implements CompilerCallbacks {
/* TestCompilerCallbacks */

messages: CompilerEvent[] = [];
readonly _net: TestCompilerNetAsyncCallbacks;
readonly _fsAsync: DefaultCompilerFileSystemAsyncCallbacks = new DefaultCompilerFileSystemAsyncCallbacks(this);

constructor(basePath?: string) {
if(basePath) {
this._net = new TestCompilerNetAsyncCallbacks(basePath);
}
}

clear() {
this.messages = [];
}

printMessages() {
if(this.messages.length) {
process.stdout.write(CompilerError.formatEvent(this.messages));
}
}

hasMessage(code: number): boolean {
return this.messages.find((item) => item.code == code) === undefined ? false : true;
}

fileURLToPath(url: string | URL): string {
return fileURLToPath(url);
}

/** true of at least one error */
hasError(): boolean {
return CompilerError.hasError(this.messages);
}

/* CompilerCallbacks */

loadFile(filename: string): Uint8Array {
try {
return fs.readFileSync(filename);
} catch(e) {
if (e.code === 'ENOENT') {
return null;
} else {
throw e;
}
}
}

fileSize(filename: string): number {
return fs.statSync(filename)?.size;
}

isDirectory(filename: string): boolean {
return fs.statSync(filename)?.isDirectory();
}

get path(): CompilerPathCallbacks {
return {
...path,
isAbsolute: path.win32.isAbsolute
};
}

get fs(): CompilerFileSystemCallbacks {
return fs;
}

get net(): CompilerNetAsyncCallbacks {
return this._net;
}

get fsAsync(): CompilerFileSystemAsyncCallbacks {
return this._fsAsync;
}

resolveFilename(baseFilename: string, filename: string): string {
const basePath =
baseFilename.endsWith('/') || baseFilename.endsWith('\\') ?
baseFilename :
path.dirname(baseFilename);
// Transform separators to platform separators -- we are agnostic
// in our use here but path prefers files may use
// either / or \, although older kps files were always \.
if(path.sep == '/') {
filename = filename.replace(/\\/g, '/');
} else {
filename = filename.replace(/\//g, '\\');
}
if(!path.isAbsolute(filename)) {
filename = path.resolve(basePath, filename);
}
return filename;
}

reportMessage(event: CompilerEvent): void {
// console.log(event.message);
this.messages.push(event);
}

debug(msg: string) {
console.debug(msg);
}
};

class TestCompilerNetAsyncCallbacks implements CompilerNetAsyncCallbacks {
constructor(private basePath: string) {
}

urlToPath(url: string): string {
const p = new URL(url);
return path.join(this.basePath, p.hostname, p.pathname.replaceAll(/[^a-z0-9_.!@#$%() -]/ig, '#'));
}

async fetchBlob(url: string): Promise<Uint8Array> {
const p = this.urlToPath(url);

if(TEST_SAVE_FIXTURES) {
// When TEST_SAVE_FIXTURES env variable is set, we will do the actual
// fetch from the origin so that we can build the fixtures easily
console.log(`Downloading file ${url} --> ${p}`);
let response: Response;
try {
response = await fetch(url);
} catch(e) {
console.error(`failed to download ${url}`);
console.error(e);
throw e; // yes, we want to abort the download
}

fs.mkdirSync(path.dirname(p), {recursive: true});
if(!response.ok) {
// We won't save a file, just delete any existing file
if(fs.existsSync(p)) {
fs.rmSync(p);
}
} else {
const data = new Uint8Array(await response.arrayBuffer());
fs.writeFileSync(p, data);
}
}

if(!fs.existsSync(p)) {
// missing file, this is okay
return null;
}
const data: Uint8Array = fs.readFileSync(p);
return data;
}

async fetchJSON(url: string): Promise<any> {
const data = await this.fetchBlob(url);
return data ? JSON.parse(new TextDecoder().decode(data)) : null;
}
}
164 changes: 1 addition & 163 deletions developer/src/common/web/test-helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,164 +1,2 @@
import * as fs from 'fs';
import * as path from 'path';
import { CompilerEvent, CompilerCallbacks, CompilerPathCallbacks, CompilerFileSystemCallbacks, CompilerError, CompilerNetAsyncCallbacks, DefaultCompilerFileSystemAsyncCallbacks, CompilerFileSystemAsyncCallbacks } from '@keymanapp/developer-utils';
import { fileURLToPath } from 'url';
export { verifyCompilerMessagesObject } from './verifyCompilerMessagesObject.js';

const { TEST_SAVE_FIXTURES } = process.env;

class TestCompilerNetAsyncCallbacks implements CompilerNetAsyncCallbacks {
constructor(private basePath: string) {
}

urlToPath(url: string): string {
const p = new URL(url);
return path.join(this.basePath, p.hostname, p.pathname.replaceAll(/[^a-z0-9_.!@#$%() -]/ig, '#'));
}

async fetchBlob(url: string): Promise<Uint8Array> {
const p = this.urlToPath(url);

if(TEST_SAVE_FIXTURES) {
// When TEST_SAVE_FIXTURES env variable is set, we will do the actual
// fetch from the origin so that we can build the fixtures easily
console.log(`Downloading file ${url} --> ${p}`);
let response: Response;
try {
response = await fetch(url);
} catch(e) {
console.error(`failed to download ${url}`);
console.error(e);
throw e; // yes, we want to abort the download
}

fs.mkdirSync(path.dirname(p), {recursive: true});
if(!response.ok) {
// We won't save a file, just delete any existing file
if(fs.existsSync(p)) {
fs.rmSync(p);
}
} else {
const data = new Uint8Array(await response.arrayBuffer());
fs.writeFileSync(p, data);
}
}

if(!fs.existsSync(p)) {
// missing file, this is okay
return null;
}
const data: Uint8Array = fs.readFileSync(p);
return data;
}

async fetchJSON(url: string): Promise<any> {
const data = await this.fetchBlob(url);
return data ? JSON.parse(new TextDecoder().decode(data)) : null;
}
}

/**
* A CompilerCallbacks implementation for testing
*/
export class TestCompilerCallbacks implements CompilerCallbacks {
/* TestCompilerCallbacks */

messages: CompilerEvent[] = [];
readonly _net: TestCompilerNetAsyncCallbacks;
readonly _fsAsync: DefaultCompilerFileSystemAsyncCallbacks = new DefaultCompilerFileSystemAsyncCallbacks(this);

constructor(basePath?: string) {
if(basePath) {
this._net = new TestCompilerNetAsyncCallbacks(basePath);
}
}

clear() {
this.messages = [];
}

printMessages() {
if(this.messages.length) {
process.stdout.write(CompilerError.formatEvent(this.messages));
}
}

hasMessage(code: number): boolean {
return this.messages.find((item) => item.code == code) === undefined ? false : true;
}

fileURLToPath(url: string | URL): string {
return fileURLToPath(url);
}

/** true of at least one error */
hasError(): boolean {
return CompilerError.hasError(this.messages);
}

/* CompilerCallbacks */

loadFile(filename: string): Uint8Array {
try {
return fs.readFileSync(filename);
} catch(e) {
if (e.code === 'ENOENT') {
return null;
} else {
throw e;
}
}
}

fileSize(filename: string): number {
return fs.statSync(filename)?.size;
}

isDirectory(filename: string): boolean {
return fs.statSync(filename)?.isDirectory();
}

get path(): CompilerPathCallbacks {
return path;
}

get fs(): CompilerFileSystemCallbacks {
return fs;
}

get net(): CompilerNetAsyncCallbacks {
return this._net;
}

get fsAsync(): CompilerFileSystemAsyncCallbacks {
return this._fsAsync;
}

resolveFilename(baseFilename: string, filename: string): string {
const basePath =
baseFilename.endsWith('/') || baseFilename.endsWith('\\') ?
baseFilename :
path.dirname(baseFilename);
// Transform separators to platform separators -- we are agnostic
// in our use here but path prefers files may use
// either / or \, although older kps files were always \.
if(path.sep == '/') {
filename = filename.replace(/\\/g, '/');
} else {
filename = filename.replace(/\//g, '\\');
}
if(!path.isAbsolute(filename)) {
filename = path.resolve(basePath, filename);
}
return filename;
}

reportMessage(event: CompilerEvent): void {
// console.log(event.message);
this.messages.push(event);
}

debug(msg: string) {
console.debug(msg);
}
};
export { TestCompilerCallbacks } from './TestCompilerCallbacks.js';
Loading

0 comments on commit 72d0bac

Please sign in to comment.