Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Assumptions #79

Merged
merged 1 commit into from
Jan 13, 2024
Merged
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
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