Skip to content

Commit

Permalink
Implemented Assumptions (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlhaufe authored Jan 13, 2024
1 parent d2b7a20 commit 0021017
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 3 deletions.
11 changes: 11 additions & 0 deletions src/data/AssumptionRepository.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Assumption from '~/domain/Assumption.mjs';
import StorageRepository from './StorageRepository.mjs';
import pkg from '~/../package.json' with { type: 'json' };
import type { SemVerString } from '~/lib/SemVer.mjs';
import AssumptionToJsonMapper from '~/mappers/AssumptionToJsonMapper.mjs';

export default class AssumptionRepository extends StorageRepository<Assumption> {
constructor(storage: Storage) {
super('assumption', storage, new AssumptionToJsonMapper(pkg.version as SemVerString));
}
}
8 changes: 8 additions & 0 deletions src/domain/Assumption.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Requirement from './Requirement.mjs';

/**
* An assumption is a property of the environment that is assumed to be true.
* Assumptions are used to simplify the problem and to make it more tractable.
* An example of an assumption would be: "Screen resolutions will not change during the execution of the program."
*/
export default class Assumption extends Requirement { }
2 changes: 2 additions & 0 deletions src/domain/Environment.mts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ export default class Environment extends Entity {
glossaryIds: Uuid[];
constraintIds: Uuid[];
invariantIds: Uuid[];
assumptionIds: Uuid[];

constructor(options: Properties<Environment>) {
super(options);
this.glossaryIds = options.glossaryIds;
this.constraintIds = options.constraintIds;
this.invariantIds = options.invariantIds;
this.assumptionIds = options.assumptionIds;
}
}
20 changes: 20 additions & 0 deletions src/mappers/AssumptionToJsonMapper.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import RequirementToJsonMapper, { type RequirementJson } from './RequirementToJsonMapper.mjs';
import SemVer from '~/lib/SemVer.mjs';
import Assumption from '~/domain/Assumption.mjs';

export interface AssumptionJson extends RequirementJson { }

export default class AssumptionToJsonMapper extends RequirementToJsonMapper {
override mapFrom(target: AssumptionJson): Assumption {
const version = new SemVer(target.serializationVersion);

if (version.gte('0.4.0'))
return new Assumption(target);

throw new Error(`Unsupported serialization version: ${version}`);
}

override mapTo(source: Assumption): AssumptionJson {
return super.mapTo(source);
}
}
7 changes: 5 additions & 2 deletions src/mappers/EnvironmentToJsonMapper.mts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface EnvironmentJson extends EntityJson {
glossaryIds: Uuid[];
constraintIds: Uuid[];
invariantIds: Uuid[];
assumptionIds: Uuid[];
}

export default class EnvironmentToJsonMapper extends EntityToJsonMapper {
Expand All @@ -17,7 +18,8 @@ export default class EnvironmentToJsonMapper extends EntityToJsonMapper {
return new Environment({
...target,
constraintIds: target.constraintIds ?? [],
invariantIds: target.invariantIds ?? []
invariantIds: target.invariantIds ?? [],
assumptionIds: target.assumptionIds ?? []
});

throw new Error(`Unsupported serialization version: ${version}`);
Expand All @@ -28,7 +30,8 @@ export default class EnvironmentToJsonMapper extends EntityToJsonMapper {
...super.mapTo(source),
glossaryIds: source.glossaryIds,
constraintIds: source.constraintIds,
invariantIds: source.invariantIds
invariantIds: source.invariantIds,
assumptionIds: source.assumptionIds
};
}
}
1 change: 1 addition & 0 deletions src/presentation/Application.mts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export default class Application extends Container {
(await import('./pages/solution/environment/GlossaryPage.mjs')).default,
(await import('./pages/solution/environment/ConstraintsPage.mjs')).default,
(await import('./pages/solution/environment/InvariantsPage.mjs')).default,
(await import('./pages/solution/environment/AssumptionsPage.mjs')).default,
(await import('./pages/solution/goals/GoalsIndexPage.mjs')).default,
(await import('./pages/solution/goals/RationalePage.mjs')).default,
(await import('./pages/solution/goals/FunctionalityPage.mjs')).default,
Expand Down
1 change: 1 addition & 0 deletions src/presentation/pages/solution/NewSolutionPage.mts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export default class NewSolutionPage extends Page {
glossaryIds: [],
constraintIds: [],
invariantIds: [],
assumptionIds: []
}),
goals = new Goals({
id: solution.goalsId,
Expand Down
79 changes: 79 additions & 0 deletions src/presentation/pages/solution/environment/AssumptionsPage.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type { Uuid } from '~/types/Uuid.mjs';
import type Environment from '~/domain/Environment.mjs';
import Assumption from '~/domain/Assumption.mjs';
import SolutionRepository from '~/data/SolutionRepository.mjs';
import EnvironmentRepository from '~/data/EnvironmentRepository.mjs';
import AssumptionRepository from '~/data/AssumptionRepository.mjs';
import Page from '~/presentation/pages/Page.mjs';
import { DataTable } from '~/presentation/components/DataTable.mjs';
import html from '~/presentation/lib/html.mjs';

const { p } = html;

export default class AssumptionPage extends Page {
static override route = '/:solution/environment/assumptions';
static {
customElements.define('x-page-assumtptions', this);
}

#solutionRepository = new SolutionRepository(localStorage);
#environmentRepository = new EnvironmentRepository(localStorage);
#assumptionRepository = new AssumptionRepository(localStorage);
#environment?: Environment;

constructor() {
super({ title: 'Assumptions' }, []);

const dataTable = new DataTable<Assumption>({
columns: {
id: { headerText: 'ID', readonly: true, formType: 'hidden', unique: true },
statement: { headerText: 'Statement', required: true, formType: 'text', unique: true }
},
select: async () => {
if (!this.#environment)
return [];

return await this.#assumptionRepository.getAll(t => this.#environment!.assumptionIds.includes(t.id));
},
onCreate: async item => {
const assumption = new Assumption({ ...item, id: self.crypto.randomUUID() });
this.#environment!.assumptionIds.push(assumption.id);
await Promise.all([
this.#assumptionRepository.add(assumption),
this.#environmentRepository.update(this.#environment!)
]);
},
onUpdate: async item => {
await this.#assumptionRepository.update(new Assumption({
...item
}));
},
onDelete: async id => {
this.#environment!.assumptionIds = this.#environment!.assumptionIds.filter(x => x !== id);
await Promise.all([
this.#assumptionRepository.delete(id),
this.#environmentRepository.update(this.#environment!)
]);
}
});

this.append(
p(`
An assumption is a property of the environment that is assumed to be true.
Assumptions are used to simplify the problem and to make it more tractable.
An example of an assumption would be: "Screen resolution will not change during the execution of the program".
`),
dataTable
);

this.#environmentRepository.addEventListener('update', () => dataTable.renderData());
this.#assumptionRepository.addEventListener('update', () => dataTable.renderData());
const solutionId = this.urlParams['solution'] as Uuid;
this.#solutionRepository.getBySlug(solutionId).then(solution => {
this.#environmentRepository.get(solution!.environmentId).then(environment => {
this.#environment = environment;
dataTable.renderData();
});
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@ export default class EnvironmentsIndexPage extends Page {
title: 'Invariants',
icon: 'lock',
href: `${location.pathname}/invariants`
})
}),
new MiniCard({
title: 'Assumptions',
// There is no icon for assumptions, so might as well use this one.
// "As sure as the sun rises in the east"
// https://en.wikipedia.org/wiki/Sunrise_problem
icon: 'sunrise',
href: `${location.pathname}/assumptions`
}),
])
);
}
Expand Down

0 comments on commit 0021017

Please sign in to comment.