Skip to content

Commit

Permalink
Add abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
tgoprince authored Aug 3, 2023
2 parents 290ab14 + a141cf4 commit bfb3fbe
Show file tree
Hide file tree
Showing 5 changed files with 743 additions and 0 deletions.
158 changes: 158 additions & 0 deletions __tests__/libs/abstraction/abstractor.basic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { Project, Diagram } from '@libs/ontouml';
import { Abstractor } from '@libs/abstraction';

describe('Basic clusterization example', () => {
const project = new Project();
const model = project.createModel();

const person = model.createKind('Person');
const woman = model.createSubkind('Woman');
const man = model.createSubkind('Man');
const living = model.createPhase('Living');
const deceased = model.createPhase('Deceased');
const child = model.createPhase('Child');
const teenager = model.createPhase('Teenager');
const adult = model.createPhase('Adult');
const husband = model.createRole('Husband');
const wife = model.createRole('Wife');
const marriage = model.createRelator('Marriage');
const organization = model.createKind('Organization');
const agency = model.createSubkind('Car Agency');
const ownership = model.createRelator('Car Ownership');
const car = model.createKind('Car');
const available = model.createPhase('Available Car');
const underMaintenance = model.createPhase('Under Maintenance Car');
const rentalCar = model.createRole('Rental Car');
const rental = model.createRelator('Car Rental');
const customer = model.createRoleMixin('Customer');
const corporateCustomer = model.createRole('Corporate Customer');
const personalCustomer = model.createRole('Personal Customer');

const genWifeWoman = woman.addChild(wife);
const genHusbandMan = man.addChild(husband);
available.addChild(rentalCar);
adult.addChild(personalCustomer);
organization.addChild(corporateCustomer);
organization.addChild(agency);

model.createPartitionFromClasses(person, [woman, man]);
model.createPartitionFromClasses(person, [living, deceased]);
model.createPartitionFromClasses(living, [child, teenager, adult]);
model.createPartitionFromClasses(car, [available, underMaintenance]);
model.createPartitionFromClasses(customer, [personalCustomer, corporateCustomer]);

const medMarriageWife = model.createMediationRelation(marriage, wife);
const medMarriagHusband = model.createMediationRelation(marriage, husband);
const medRentalCustomer = model.createMediationRelation(rental, customer);
const medRentalRentalCar = model.createMediationRelation(rental, rentalCar);
const medOwnershipAgency = model.createMediationRelation(ownership, agency);
const medOwnershipCar = model.createMediationRelation(ownership, car);

let diagrams: Diagram[] = new Abstractor(project).buildAll();


describe('Relator Abstraction Test', () => {
let diagram: Diagram = diagrams.find(d => d.getName() === 'Relator Abstraction');



it('Should not contain the main relator: Marriage', () => {
expect(diagram.findView(marriage)).toBeFalsy();
});
it('Should not contain the main relator: Car Rental', () => {
expect(diagram.findView(rental)).toBeFalsy();
});
it('Should not contain the main relator: Ownership', () => {
expect(diagram.findView(ownership)).toBeFalsy();
});






it('Should contain the expected classes (19)', () => {
expect(diagram.findView(person)).toBeTruthy();
expect(diagram.findView(woman)).toBeTruthy();
expect(diagram.findView(man)).toBeTruthy();
expect(diagram.findView(husband)).toBeTruthy();
expect(diagram.findView(wife)).toBeTruthy();
expect(diagram.findView(deceased)).toBeTruthy();
expect(diagram.findView(living)).toBeTruthy();
expect(diagram.findView(child)).toBeTruthy();
expect(diagram.findView(adult)).toBeTruthy();
expect(diagram.findView(teenager)).toBeTruthy();
expect(diagram.findView(personalCustomer)).toBeTruthy();
expect(diagram.findView(organization)).toBeTruthy();
expect(diagram.findView(agency)).toBeTruthy();
expect(diagram.findView(car)).toBeTruthy();
expect(diagram.findView(customer)).toBeTruthy();
expect(diagram.findView(underMaintenance)).toBeTruthy();
expect(diagram.findView(available)).toBeTruthy();
expect(diagram.findView(corporateCustomer)).toBeTruthy();
expect(diagram.findView(rentalCar)).toBeTruthy();

expect(diagram.getClassViews()).toHaveLength(19);
});

it('Should not contain the expected relations (6)', () => {
expect(diagram.findView(medMarriageWife)).toBeFalsy();
expect(diagram.findView(medMarriagHusband)).toBeFalsy();
expect(diagram.findView(medRentalRentalCar)).toBeFalsy();
expect(diagram.findView(medRentalCustomer)).toBeFalsy();
expect(diagram.findView(medOwnershipAgency)).toBeFalsy();
expect(diagram.findView(medOwnershipCar)).toBeFalsy();

});


});

describe('Non Sortal Abstraction Test', () => {
let diagram: Diagram = diagrams.find(d => d.getName() === 'Non Sortal Abstraction');

it('Should not contain the main relator: Ownership', () => {
expect(diagram.findView(customer)).toBeFalsy();
});

it('Should not contain the expected relations (1)', () => {
expect(diagram.findView(medRentalCustomer)).toBeFalsy();
});

});


describe('Sortal Abstraction Test', () => {
let diagram: Diagram = diagrams.find(d => d.getName() === 'Sortal Abstraction');

it('Should not contain classes', () => {
expect(diagram.findView(husband)).toBeFalsy();
expect(diagram.findView(wife)).toBeFalsy();
expect(diagram.findView(personalCustomer)).toBeFalsy();
expect(diagram.findView(rentalCar)).toBeFalsy();
expect(diagram.findView(corporateCustomer)).toBeFalsy();


});



});

describe('Subkind And Phase Partitions Abstraction Test', () => {
let diagram: Diagram = diagrams.find(d => d.getName() === 'Subkind And Phase Partitions Abstraction');

it('Should not contain classes', () => {
expect(diagram.findView(child)).toBeFalsy();
expect(diagram.findView(adult)).toBeFalsy();
expect(diagram.findView(teenager)).toBeFalsy();
expect(diagram.findView(available)).toBeFalsy();
expect(diagram.findView(underMaintenance)).toBeFalsy();


});



});
});
90 changes: 90 additions & 0 deletions src/libs/abstraction/abstraction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import {
Package,
Class,
GeneralizationSet,
Generalization,
Relation,
ModelElement,
Diagram
} from '@libs/ontouml';
import { uniqBy } from 'lodash';

export class Abstraction {
name: string;
classes: Class[];
relations: Relation[];
generalizations: Generalization[];
generalizationSets: GeneralizationSet[];

constructor(name: string) {
this.name = name;
this.classes = [];
this.relations = [];
this.generalizations = [];
this.generalizationSets = [];
}

createDiagram(owner: Package): Diagram {
let diagram = new Diagram();
diagram.setName(this.name);
diagram.owner = owner;

let pos: number = 40;
this?.classes.forEach(_class => {
let view = diagram.addClass(_class);
view.setX(pos);
view.setY(40);
pos += 120;
});

diagram.addModelElements(this.relations);
diagram.addModelElements(this.generalizations);
diagram.addModelElements(this.generalizationSets);

return diagram;
}

addClasses(classes: Class[]) {
this.classes = this.classes.concat(classes);
}

containsRelation(relation: Relation): boolean {
return this.relations.findIndex(r => r.id === relation.id) >= 0;
}

addRelations(relations: Relation[]) {
this.relations = this.relations.concat(relations);
}

addGeneralizations(generalizations: Generalization[]) {
this.generalizations = this.generalizations.concat(generalizations);
}

addGeneralizationSets(generalizationSets: GeneralizationSet[]) {
this.generalizationSets = this.generalizationSets.concat(generalizationSets);
}

removeDuplicates() {
this.classes = Abstraction.removeDuplicatesArray(this.classes);
this.relations = Abstraction.removeDuplicatesArray(this.relations);
this.generalizations = Abstraction.removeDuplicatesArray(this.generalizations);
this.generalizationSets = Abstraction.removeDuplicatesArray(this.generalizationSets);
}

static removeDuplicatesArray<T extends ModelElement>(elements: T[]): T[] {
return uniqBy(elements, 'id');
}

addAll(cluster: Abstraction): boolean {
if (!cluster) return false;

this.addClasses(cluster.classes);
this.addRelations(cluster.relations);
this.addGeneralizations(cluster.generalizations);
this.addGeneralizationSets(cluster.generalizationSets);

this.removeDuplicates();
return true;
}
}

Loading

0 comments on commit bfb3fbe

Please sign in to comment.