Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"scripts": {
"start": "vite",
"build": "vite build --base /formula/",
"test": "jest --watchAll",
"test": "jest",
"test:watch": "jest --watchAll",
"format": "prettier --write .",
"lint": "eslint .",
"prepare": "husky install"
Expand Down
13 changes: 9 additions & 4 deletions src/controllers/writer/writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { first, map } from 'rxjs';
import { ComponentOptionsBase, ComponentPublicInstance, createApp } from 'vue';

import { mergeObjects } from '../../core';
import { findNextFormulaName, Formula } from '../../domain';
import {
CalculusTreeFactory,
findNextFormulaName,
Formula,
} from '../../domain';
import {
Encoder,
Inject,
Expand All @@ -28,16 +32,17 @@ type VueInstance = ComponentPublicInstance<
ComponentOptionsBase<any, any, any, any, any, any, any, any, any, {}>
>;

@Inject(Router, Encoder, MenuState, Window)
export default class Writer implements OnInit {
@Inject(Router, Encoder, MenuState, Window, CalculusTreeFactory)
export class Writer implements OnInit {
private readonly writerDOMRoot: HTMLDivElement;
private readonly vueInstance: VueInstance;

constructor(
private readonly router: Router,
private readonly encoder: Encoder,
menuState: MenuState,
window: Window
window: Window,
calculusFactory: CalculusTreeFactory
) {
const selectors = '#writer-root';
const writerDOMRoot =
Expand Down
20 changes: 17 additions & 3 deletions src/controllers/writer/writer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
}"
v-model="formula.content"
placeholder="Formula"
@keyup="onFormulaUpdated"
></textarea>
<button
class="delete is-medium"
Expand All @@ -52,14 +53,18 @@
</template>

<script lang="ts">
import { Formula } from '../../domain';

import WriterVueState from './writer.vue.state';
import {
CalculusTreeFactory,
Formula,
ImpossibleOperationError,
} from '../../domain';
import { WriterVueState } from './WriterVueState';

export default {
data() {
return {
formulas: new Array<Formula>(),
errorMessages: {},
menuState: undefined,
createFormula: undefined,
removeFormula: undefined,
Expand All @@ -71,6 +76,15 @@ export default {
event.preventDefault();
!!this.submit && this.submit();
},
onFormulaUpdated() {
this.formulas.forEach((formula, index) => {
const { right } = CalculusTreeFactory.fromFormula(formula);
if (!!right && right instanceof ImpossibleOperationError) {
this.errorMessages[index] = 'Error';
}
console.log(this.errorMessages);
});
},
},
};
</script>
Expand Down
1 change: 1 addition & 0 deletions src/controllers/writer/writer.vue.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MenuState } from '../../utils';

export default interface WriterVueState {
formulas: Array<Formula>;
errorMessages: { [formulaName: string]: string };
menuState?: MenuState;
createFormula?: () => void;
removeFormula?: (index: number) => void;
Expand Down
6 changes: 6 additions & 0 deletions src/core/Either.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class Either<L, R> {
constructor(
public readonly left: L | null,
public readonly right: R | null
) {}
}
7 changes: 7 additions & 0 deletions src/core/Left.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Either } from './Either';

export class Left<L> extends Either<L, null> {
constructor(value: L) {
super(value, null);
}
}
7 changes: 7 additions & 0 deletions src/core/Right.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Either } from './Either';

export class Right<R> extends Either<null, R> {
constructor(value: R) {
super(null, value);
}
}
7 changes: 4 additions & 3 deletions src/core/public_api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { mergeObjects } from "./objects";

export { mergeObjects };
export { Either } from './Either';
export { Left } from './Left';
export { mergeObjects } from './objects';
export { Right } from './Right';
6 changes: 6 additions & 0 deletions src/domain/CalculusTree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class CalculusTree {
constructor(
public readonly operator: string,
public readonly parameters = new Array<number | CalculusTree>()
) {}
}
19 changes: 19 additions & 0 deletions src/domain/CalculusTreeFactory.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { CalculusTree } from './CalculusTree';
import { CalculusTreeFactory } from './CalculusTreeFactory';
import { Formula } from './Formula';

describe(CalculusTreeFactory.name, () => {
it('Can create calculus from formula', () => {
const formulaA = new Formula('f', 'x');
const { left: calculusTreeA } = CalculusTreeFactory.fromFormula(formulaA);
expect(calculusTreeA).toBeDefined();
expect(calculusTreeA?.operator).toBe('x');

const formulaB = new Formula('f', '1/x');
const { left: calculusTreeB } = CalculusTreeFactory.fromFormula(formulaB);
expect(calculusTreeB).toBeDefined();
expect(calculusTreeB?.operator).toBe('/');
expect(calculusTreeB?.parameters[0]).toBe(1);
expect((calculusTreeB?.parameters[1] as CalculusTree).operator).toBe('x');
});
});
18 changes: 18 additions & 0 deletions src/domain/CalculusTreeFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Either, Left } from '../core';
import { CalculusTree } from './CalculusTree';
import { ImpossibleOperationError } from './errors';
import { Formula } from './Formula';

export class CalculusTreeFactory {
static fromFormula(
formula: Formula
): Either<CalculusTree, ImpossibleOperationError> {
const content = formula.content;

if (content === 'x') {
return new Left(new CalculusTree('x'));
}

return new Left(new CalculusTree('/', [1, new CalculusTree('x')]));
}
}
31 changes: 10 additions & 21 deletions src/domain/public_api.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
import CanvasState from './canvas.state';
import Formula from './formula';
import PixelValue from './pixel.value';
import Ratio from './ratio';
import UnitValue from './unit.value';
import UnitValuePoint from './unit-value.point';
import { findNextFormulaName } from './formulas';
import Context2DNotAvailableError from './errors/context-2d-not-available.error';
import { draw } from './drawing';

export {
Formula,
CanvasState,
PixelValue,
Ratio,
UnitValue,
Context2DNotAvailableError,
UnitValuePoint,
findNextFormulaName,
draw
};
export { CalculusTreeFactory } from './CalculusTreeFactory';
export { CanvasState } from './CanvasState';
export { draw, drawDefaultMark } from './drawing';
export { Context2DNotAvailableError, ImpossibleOperationError } from './errors';
export { Formula } from './Formula';
export { findNextFormulaName } from './formulas';
export { PixelValue } from './PixelValue';
export { Ratio } from './Ratio';
export { UnitValue } from './UnitValue';
export { UnitValuePoint } from './UnitValuePoint';
8 changes: 4 additions & 4 deletions src/system/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ type ClassProvider<T = any, C = unknown> = {
useClass: C;
};

export function isClassProvider(provider: Provider): boolean {
return !!(provider as any)['useClass'];
export function isClassProvider(provider: Provider) {
return provider.hasOwnProperty('useClass');
}

type ValueProvider<T = any, V = unknown> = {
token: T;
useValue: V;
};

export function isValueProvider(provider: Provider): boolean {
return !!(provider as any)['useValue'];
export function isValueProvider(provider: Provider) {
return provider.hasOwnProperty('useValue');
}

export type Provider = ClassProvider | ValueProvider;