Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanThatOneKid committed Nov 28, 2021
1 parent 538081b commit 6fca6dc
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 107 deletions.
198 changes: 184 additions & 14 deletions lib/cartridge/cartridge.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
import { assertEquals } from "../../deps/std/testing.ts";
import { Cartridge } from "./cartridge.ts";
import { CartridgeEvent } from "./cartridge_event.ts";
import { Cartridge, CartridgeEvent } from "./cartridge.ts";
import { CodeBlock } from "../code_block/mod.ts";

/**
* @todo @ethanthatonekid write tests that reflect cartridge api design/usage
*/
Deno.test("hello world", () => {
const cartridge = new Cartridge();
cartridge.on(CartridgeEvent.Load, (event) => {
event.data;
});
cartridge.on(CartridgeEvent.FileStart, console.log);
assertEquals(1, 1);
});
// import { Lexicon, T } from "../tokenize/mod.ts";

Deno.test("event 'file_start' makes a successful dispatch", async () => {
const cartridge = new Cartridge();
Expand All @@ -31,3 +19,185 @@ Deno.test("event 'file_start' makes a successful dispatch", async () => {
});
assertEquals(result, "ABC");
});

Deno.test("event 'inline_comment' makes a successful dispatch", async () => {
const cartridge = new Cartridge();
cartridge.on(
CartridgeEvent.InlineComment,
(event) => {
assertEquals(
event.type,
CartridgeEvent.InlineComment,
"matches event name",
);
assertEquals(event.data.comments.length, 1, "expects 1 comment");
return event.data.comments.map((comment) => `// ${comment}`).join("\n");
},
);
const expectation = "// ABC";
const reality = await cartridge.dispatch(CartridgeEvent.InlineComment, {
type: CartridgeEvent.InlineComment,
code: new CodeBlock(),
data: { comments: ["ABC"] },
tokens: [],
});
assertEquals(expectation, reality);
});

Deno.test("event 'multiline_comment' makes a successful dispatch", async () => {
const cartridge = new Cartridge();
cartridge.on(
CartridgeEvent.MultilineComment,
(event) => {
assertEquals(
event.type,
CartridgeEvent.MultilineComment,
"matches event name",
);
assertEquals(event.data.comments.length, 3, "expects 3 comment lines");
return event.data.comments.map((comment) => `// ${comment}`).join("\n");
},
);
const expectation = `// ABC
// DEF
// GEH`;
const reality = await cartridge.dispatch(CartridgeEvent.MultilineComment, {
type: CartridgeEvent.MultilineComment,
code: new CodeBlock(),
data: { comments: ["ABC", "DEF", "GEH"] },
tokens: [],
});
assertEquals(expectation, reality);
});

Deno.test("event 'load' makes a successful dispatch", async () => {
const cartridge = new Cartridge();
cartridge.on(
CartridgeEvent.Load,
(event) => {
assertEquals(
event.type,
CartridgeEvent.Load,
"matches event name",
);
assertEquals(event.data.source, "example.fart", "matches source");
assertEquals(event.data.dependencies, [
"Example1",
"Example2",
"Example3",
]);
return `import { ${
event.data.dependencies.join(", ")
} } from "${event.data.source}";`;
},
);
const expectation =
`import { Example1, Example2, Example3 } from "example.fart";`;
const reality = await cartridge.dispatch(CartridgeEvent.Load, {
type: CartridgeEvent.Load,
code: new CodeBlock(),
data: {
comments: [],
source: "example.fart",
dependencies: ["Example1", "Example2", "Example3"],
},
tokens: [],
});
assertEquals(expectation, reality);
});

Deno.test("event 'struct_open' makes a successful dispatch (with comment)", async () => {
const cartridge = new Cartridge();
cartridge.on(
CartridgeEvent.StructOpen,
(event) => {
assertEquals(
event.type,
CartridgeEvent.StructOpen,
"matches event name",
);
assertEquals(event.data.name, "Example", "matches name");
assertEquals(event.data.comments.length, 1, "expects 1 comment");
return `// ${event.data.comments[0]}
interface ${event.data.name} {`;
},
);
const expectation = `// ABC
interface Example {`;
const reality = await cartridge.dispatch(CartridgeEvent.StructOpen, {
type: CartridgeEvent.StructOpen,
code: new CodeBlock(),
data: { name: "Example", comments: ["ABC"] },
tokens: [],
});
assertEquals(expectation, reality);
});

Deno.test("event 'set_property' makes a successful dispatch", async () => {
const cartridge = new Cartridge();
cartridge.on(
CartridgeEvent.SetProperty,
(event) => {
assertEquals(
event.type,
CartridgeEvent.SetProperty,
"matches event name",
);
return `${event.data.name}: ${event.data.definition.value};`;
},
);
const expectation = `example: string;`;
const reality = await cartridge.dispatch(CartridgeEvent.SetProperty, {
type: CartridgeEvent.SetProperty,
code: new CodeBlock(),
data: { name: "example", definition: { value: "string" }, comments: [] },
tokens: [],
});
assertEquals(expectation, reality);
});

Deno.test("event 'struct_close' makes a successful dispatch", async () => {
const cartridge = new Cartridge();
cartridge.on(
CartridgeEvent.StructClose,
(event) => {
assertEquals(
event.type,
CartridgeEvent.StructClose,
"matches event name",
);
return "}";
},
);
const expectation = `}`;
const reality = await cartridge.dispatch(CartridgeEvent.StructClose, {
type: CartridgeEvent.StructClose,
code: new CodeBlock(),
data: null,
tokens: [],
});
assertEquals(expectation, reality);
});

Deno.test("event 'file_end' makes a successful dispatch", async () => {
const cartridge = new Cartridge();
cartridge.on(
CartridgeEvent.FileEnd,
(event) => {
assertEquals(
event.type,
CartridgeEvent.FileEnd,
"matches event name",
);
return `XYZ`;
},
);
const expectation = `XYZ`;
const reality = await cartridge.dispatch(CartridgeEvent.FileEnd, {
type: CartridgeEvent.FileEnd,
code: new CodeBlock(),
data: null,
tokens: [],
});
assertEquals(expectation, reality);
});
83 changes: 77 additions & 6 deletions lib/cartridge/cartridge.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,76 @@
import { CartridgeEvent, CartridgeEventReturnType } from "./cartridge_event.ts";
import type {
CartridgeEventContext,
CartridgeHandler,
CartridgeHandlerMap,
} from "./cartridge_event.ts";
import type { Token } from "../tokenize/mod.ts";

export enum CartridgeEvent {
FileStart = "file_start",
InlineComment = "inline_comment",
MultilineComment = "multiline_comment",
Load = "load",
StructOpen = "struct_open",
SetProperty = "set_property",
StructClose = "struct_close",
FileEnd = "file_end",
}

export type CartridgeEventReturnType = (
| void
| Promise<void>
| string
| Promise<string>
| null
);

export interface PropertyDefinition {
optional?: boolean;
modifier?: string;
struct?: Record<string, PropertyDefinition>;
tuple?: Array<{
label?: string;
value: PropertyDefinition;
}>;
value?: string;
}

export interface CartridgeEventContext<T extends CartridgeEvent> {
type: T;
code: { append: (code: string) => CartridgeEventReturnType };
tokens: Token[];
data: T extends CartridgeEvent.InlineComment ? { comments: string[] }
: T extends CartridgeEvent.MultilineComment ? { comments: string[] }
: T extends CartridgeEvent.Load
? { comments: string[]; dependencies: string[]; source: string }
: T extends CartridgeEvent.StructOpen
? { comments: string[]; name?: string } // undefined name implies anonymous struct
: T extends CartridgeEvent.SetProperty ? ({
comments: string[];
name: string;
definition: PropertyDefinition;
})
: null;
}

/**
* If a code generation function returns null, that means that the
* target language omits the requested generated code. A null return
* value will prevent the requested line from being appended to the result.
*/
export type CartridgeHandler<T extends CartridgeEvent> = (
event: CartridgeEventContext<T>,
) => CartridgeEventReturnType;

export interface CartridgeHandlerMap {
[CartridgeEvent.FileStart]?: CartridgeHandler<CartridgeEvent.FileStart>;
[CartridgeEvent.InlineComment]?: CartridgeHandler<
CartridgeEvent.InlineComment
>;
[CartridgeEvent.MultilineComment]?: CartridgeHandler<
CartridgeEvent.MultilineComment
>;
[CartridgeEvent.Load]?: CartridgeHandler<CartridgeEvent.Load>;
[CartridgeEvent.StructOpen]?: CartridgeHandler<CartridgeEvent.StructOpen>;
[CartridgeEvent.SetProperty]?: CartridgeHandler<CartridgeEvent.SetProperty>;
[CartridgeEvent.StructClose]?: CartridgeHandler<CartridgeEvent.StructClose>;
[CartridgeEvent.FileEnd]?: CartridgeHandler<CartridgeEvent.FileEnd>;
}

/**
* @todo @ethanthatonekid pass all tests in ./cartridge.test.ts
Expand Down Expand Up @@ -36,6 +103,10 @@ export class Cartridge {
): void;
public addEventListener(
name: CartridgeEvent.SetProperty,
handler: CartridgeHandler<CartridgeEvent.SetProperty>,
): void;
public addEventListener(
name: CartridgeEvent.StructClose,
handler: CartridgeHandler<CartridgeEvent.StructClose>,
): void;
public addEventListener(
Expand Down
71 changes: 0 additions & 71 deletions lib/cartridge/cartridge_event.ts

This file was deleted.

5 changes: 2 additions & 3 deletions lib/cartridge/mod.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
export { Cartridge } from "./cartridge.ts";
export { CartridgeEvent } from "./cartridge_event.ts";
export { Cartridge, CartridgeEvent } from "./cartridge.ts";
export type {
CartridgeEventContext,
CartridgeHandler,
CartridgeHandlerMap,
PropertyDefinition,
} from "./cartridge_event.ts";
} from "./cartridge.ts";
Loading

1 comment on commit 6fca6dc

@deno-deploy
Copy link

@deno-deploy deno-deploy bot commented on 6fca6dc Nov 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failed to deploy:

failed to fetch 'https://raw.githubusercontent.com/EthanThatOneKid/fart/6fca6dcd96b3b020553953dff74ec8d16397c45c/std/server/worker.ts': HTTP status client error (404 Not Found) for url (https://raw.githubusercontent.com/EthanThatOneKid/fart/6fca6dcd96b3b020553953dff74ec8d16397c45c/std/server/worker.ts)

Please sign in to comment.