Commit 6b6232dd authored by Clement Brizard's avatar Clement Brizard
Browse files

Merge branch 'master' into 12-gerer-les-calculs-apres-que-l-utilisateur-a-rempli-ses-parametres

parents 07ea192b 42bbb543
......@@ -89,9 +89,9 @@ const transportationMeanSubCategories = {
* Damage categories for meetings
*/
const meetingCategoryDamage = {
HARDWARE: 'HARDWARE',
SOFTWARE: 'SOFTWARE',
JOURNEY: 'JOURNEY'
HARDWARE: 'hardware',
SOFTWARE: 'software',
JOURNEY: 'journey'
}
const possibleJourneys = [
......
......@@ -20,7 +20,9 @@ class CategoryDamage {
this._category = category
// Create a hashmap that contains components and their id
this._components = this.arrayToMapComponents(components, category)
this._components = (components !== null)
? this.arrayToMapComponents(components, category)
: new Map()
}
// Getters
......
......@@ -247,7 +247,7 @@ class Hardware extends Component {
and add it to composite hardware damage */
Object.values(this.components).forEach(component => {
component.computeDamage({ meetingDuration, bound })
damage.add(component.damage)
damage = damage.add(component.damage)
})
} else {
const operatingVisio = this.computeTypedDamage(hardwareDamageTypes.OPERATING_VISIO, meetingDuration, bound)
......@@ -368,7 +368,7 @@ class Hardware extends Component {
}
const weightEmbodied = Object.assign({}, this.embodied)
Object.keys(weightEmbodied).map(category => {
Object.keys(weightEmbodied).forEach(category => {
weightEmbodied[category] *= boundSpecificWeight
})
......
......@@ -4,7 +4,8 @@ const Damage = require('../shared/Damage')
const Component = require('../shared/Component')
const TransportationMean = require('./TransportationMean')
const {
meetingComponents
meetingComponents,
transportationMeanSubCategories
} = require('../../../constants/meeting')
/**
......@@ -139,6 +140,16 @@ class Journey extends Component {
})
}
/* If the transportation mean is a car, we return the damage only for one participant
(i.e the total damage divided by the number of people travelling in the car).
If two people travelled in the same car, two journeys will have been created, one for
each traveller. */
if (this.mean.subCategory === transportationMeanSubCategories.CAR) {
embodiedDamage.mutate(category => {
embodiedDamage[category] /= this.numberOfPeople
})
}
// Return the journey embodied damage
return embodiedDamage
}
......
......@@ -11,16 +11,16 @@ class MeetingDamage {
* It's composed of a Damage component that represents the total damage caused by the meeting
* and of three CategoryDamage objects that repesent the damages caused by all
* the meeting components gathered by category (hardware, software, transport).
* @param {Object[]} hardwareComponents - An array of JSON objects that contain all necessary data to create the hardware components of the meeting.
* @param {Object[]} softwareComponents - An array of JSON objects that contain all necessary data to create the software components of the meeting.
* @param {Object[]} journeyComponents - An array of JSON objects that contain all necessary data to create the transport components of the meeting.
* @param {Object[]} hardware - An array of JSON objects that contain all necessary data to create the hardware components of the meeting.
* @param {Object[]} software - An array of JSON objects that contain all necessary data to create the software components of the meeting.
* @param {Object[]} journey - An array of JSON objects that contain all necessary data to create the transport components of the meeting.
* @see CategoryDamage
*/
constructor ({ hardwareComponents, softwareComponents, journeyComponents }) {
constructor ({ hardware = null, software = null, journey = null }) {
// Create all the category damages linked to the meeting
this._hardwareDamage = new CategoryDamage({ components: hardwareComponents, category: meetingCategoryDamage.HARDWARE })
this._softwareDamage = new CategoryDamage({ components: softwareComponents, category: meetingCategoryDamage.SOFTWARE })
this._journeyDamage = new CategoryDamage({ components: journeyComponents, category: meetingCategoryDamage.JOURNEY })
this._hardwareDamage = new CategoryDamage({ components: hardware, category: meetingCategoryDamage.HARDWARE })
this._softwareDamage = new CategoryDamage({ components: software, category: meetingCategoryDamage.SOFTWARE })
this._journeyDamage = new CategoryDamage({ components: journey, category: meetingCategoryDamage.JOURNEY })
}
// Getters
......
......@@ -27,11 +27,15 @@ class MeetingScenario extends Scenario {
super(user)
this._meetingDuration = meetingDuration
this._numberOfParticipants = numberOfParticipants
this._damage = new MeetingDamage({
hardwareComponents: payload[meetingCategoryDamage.HARDWARE],
softwareComponents: payload[meetingCategoryDamage.SOFTWARE],
journeyComponents: payload[meetingCategoryDamage.JOURNEY]
const params = {}
Object.values(meetingCategoryDamage).forEach(category => {
if (payload[category]) {
params[category] = payload[category]
}
})
this._damage = new MeetingDamage(params)
}
// Getters
......
......@@ -307,6 +307,8 @@ describe('Hardware class', () => {
)
Object.values(expected).forEach(categoryDamageValue => {
assert.isNotNaN(categoryDamageValue)
assert.isNotNull(categoryDamageValue)
assert.notEqual(0, categoryDamageValue)
})
})
})
......@@ -429,10 +431,11 @@ describe('Hardware class', () => {
)
}).forEach(json => {
const component = new Hardware({ name: json.name })
const damage = component.computeTypedDamage(damageType, meetingDuration)
// Compute expected damage
const expected = new Damage({ component })
assert.deepStrictEqual(expected, component.computeTypedDamage(damageType, meetingDuration))
Object.keys(damage).forEach(category => {
assert.strictEqual(damage[category], 0)
})
})
})
})
......@@ -468,7 +471,13 @@ describe('Hardware class', () => {
})
}
assert.deepStrictEqual(expected, component.computeTypedDamage(damageType, meetingDuration))
const damage = component.computeTypedDamage(damageType, meetingDuration)
Object.keys(damage).forEach(category => {
assert.strictEqual(damage[category], expected[category])
assert.isNotNaN(damage[category])
assert.isNotNull(damage[category])
assert.notEqual(0, damage[category])
})
})
})
})
......@@ -504,34 +513,16 @@ describe('Hardware class', () => {
})
}
assert.deepStrictEqual(expected, component.computeTypedDamage(damageType, meetingDuration))
const damage = component.computeTypedDamage(damageType, meetingDuration)
Object.keys(damage).forEach(category => {
assert.strictEqual(damage[category], expected[category])
assert.isNotNaN(damage[category])
assert.isNotNull(damage[category])
assert.notEqual(0, damage[category])
})
})
})
})
it('should compute assimilated embodied damages', () => {
Object.values(hardwareDatabase)
.filter(json => json.embodiedAssimilatedTo)
.forEach(json => {
const instance = new Hardware({ name: json.name })
const weight = (json.weight.upper && json.weight.lower)
? json.weight.upper
: json.weight
const expected = hardwareDatabase[json.embodiedAssimilatedTo].embodied
Object.keys(expected).map(category => {
expected[category] *= weight
})
assert.deepStrictEqual(
instance.getTypedDamage(hardwareDamageTypes.EMBODIED_VISIO),
expected
)
Object.values(expected).forEach(categoryDamageValue => {
assert.isNotNaN(categoryDamageValue)
})
})
})
it('should compute the damage of a composite hardware', () => {
Object.values(hardwareDamageTypes).forEach(damageType => {
Object.values(hardwareDatabase)
......@@ -589,6 +580,9 @@ describe('Hardware class', () => {
Object.keys(double).forEach(category => {
assert.strictEqual(double[category], simple[category] * 2)
assert.isNotNaN(double[category])
assert.isNotNull(double[category])
assert.notEqual(0, double[category])
})
})
it('the lower bound damage should be lower than the default (upper) damage', () => {
......@@ -605,25 +599,26 @@ describe('Hardware class', () => {
it('should compute the damage of a composite hardware with x instances of the same component (x > 1)', () => {
const json = hardwareDatabase.LOGITECH_KIT
const instance = new Hardware({ name: json.name })
// Compute expected damage
const expected = new Damage()
let expected = new Damage()
for (const [name, quantity] of Object.entries(json.components)) {
const component = new Hardware({ name, quantity: 1 })
component.computeDamage(meetingDuration)
const damage = component.damage
component.computeDamage({ meetingDuration })
component.damage.mutate(category => {
component.damage[category] *= quantity
})
expected.add(damage.mutate(category => {
return damage[category] * quantity
}))
expected = expected.add(component.damage)
}
instance.computeDamage(meetingDuration)
instance.computeDamage({ meetingDuration })
const actual = instance.damage
assert.deepStrictEqual(actual, expected)
Object.values(actual).forEach(categoryDamageValue => {
assert.isNotNaN(categoryDamageValue)
assert.isNotNull(categoryDamageValue)
assert.notEqual(0, categoryDamageValue)
})
})
it('should compute the damage of each composite hardware', () => {
......@@ -636,19 +631,21 @@ describe('Hardware class', () => {
const instance = new Hardware({ name: json.name })
// Compute expected damage
const expected = new Damage()
let expected = new Damage()
for (const [name, quantity] of Object.entries(json.components)) {
const component = new Hardware({ name, quantity })
component.computeDamage(meetingDuration)
expected.add(component.damage)
component.computeDamage({ meetingDuration })
expected = expected.add(component.damage)
}
instance.computeDamage(meetingDuration)
instance.computeDamage({ meetingDuration })
const actual = instance.damage
assert.deepStrictEqual(actual, expected)
Object.values(actual).forEach(categoryDamageValue => {
assert.isNotNaN(categoryDamageValue)
assert.isNotNull(categoryDamageValue)
assert.notEqual(0, categoryDamageValue)
})
})
})
......
'use strict'
const assert = require('assert')
const chai = require('chai')
const assert = chai.assert
const transportDatabase = require('../../../../database/meeting/transportationMean')
const TransportationMean = require('../../../../model/classes/meeting/TransportationMean')
const Journey = require('../../../../model/classes/meeting/Journey')
......@@ -16,12 +17,19 @@ describe('Journey class', () => {
numberOfPeople: 3
})
const embodiedDamage = new Damage({
humanHealth: electricCar.embodied.humanHealth * 100,
ecosystemQuality: electricCar.embodied.ecosystemQuality * 100,
climateChange: electricCar.embodied.climateChange * 100,
resources: electricCar.embodied.resources * 100
humanHealth: electricCar.embodied.humanHealth * 100 / 3,
ecosystemQuality: electricCar.embodied.ecosystemQuality * 100 / 3,
climateChange: electricCar.embodied.climateChange * 100 / 3,
resources: electricCar.embodied.resources * 100 / 3
})
it('the damage of a car journey should be divided by the number of people in the car', () => {
const actual = journeyElectricCar3People.computeEmbodiedDamage()
Object.keys(actual).forEach(category => {
assert.strictEqual(actual[category], embodiedDamage[category])
assert.isNotNaN(actual[category])
})
})
it('should return the damage caused by 3 people in a eletric car for one kilometer ', () => {
assert.deepStrictEqual(
journeyElectricCar3People.computeEmbodiedDamage(),
......@@ -35,11 +43,14 @@ describe('Journey class', () => {
distance: 100,
numberOfPeople: 5
})
it('two journeys with the same kind of car and the same distance should cause the same damage (i.e. the number of people desn\'t matter)', () => {
assert.deepStrictEqual(
journeyElectricCar3People.computeEmbodiedDamage(),
journeyElectricCar5People.computeEmbodiedDamage()
)
it('two identical journeys except for the number of people should cause different damages ', () => {
const threePeople = journeyElectricCar3People.computeEmbodiedDamage()
const fivePeople = journeyElectricCar5People.computeEmbodiedDamage()
Object.keys(threePeople).forEach(category => {
assert.isBelow(fivePeople[category], threePeople[category])
assert.isNotNaN(fivePeople[category])
})
})
const heatCar = new TransportationMean({ name: transportDatabase.CAR_HEAT_ENGINE_ONE_KM.name })
......
......@@ -71,9 +71,9 @@ describe('MeetingDamage class', () => {
// Create the MeetingDamage object thnaks to three arrays of JSON object
const meetingDamage = new MeetingDamage({
hardwareComponents: hardwareJSON,
softwareComponents: softwareJSON,
journeyComponents: journeyJSON
hardware: hardwareJSON,
software: softwareJSON,
journey: journeyJSON
})
// Compute the total damage linked to the MeetingDamage object
const totalDamageJSON = {
......
'use strict'
const assert = require('assert')
const chai = require('chai')
const assert = chai.assert
const MeetingScenario = require('../../../../model/classes/meeting/MeetingScenario')
const MeetingDamage = require('../../../../model/classes/meeting/MeetingDamage')
const hardwareDatabase = require('../../../../database/meeting/hardware')
......@@ -16,9 +17,9 @@ describe('MeetingScenario class', () => {
// The user who creates the meeting
const user = 'vlegauch'
// The meeting duration in minutes
const meetingDuration = 90
const meetingDuration = 120
// Number of participants
const numberOfParticipants = 5
const numberOfParticipants = 4
// The JSON object that enables to creates components linked to the meeting
const payload = {
[meetingCategoryDamage.HARDWARE]: [
......@@ -65,33 +66,64 @@ describe('MeetingScenario class', () => {
}
]
}
// Create the MeetingScenario object
const meetingScenario = new MeetingScenario({ user, meetingDuration, numberOfParticipants, payload })
// Create the JSON object that enables to compute meeting total damage
const damagePayload = {
[meetingCategoryDamage.HARDWARE]: { meetingDuration: 90, bound: bounds.UPPER },
[meetingCategoryDamage.SOFTWARE]: { instancesNumber: 5, bandwithBound: bounds.UPPER, networkBound: bounds.UPPER, meetingDuration: 120 },
[meetingCategoryDamage.JOURNEY]: {}
}
// Create scenario with missing components in a category
const incompletePayload = Object.assign({}, payload)
delete incompletePayload[meetingCategoryDamage.JOURNEY]
const incompleteScenario = new MeetingScenario({ user, meetingDuration, numberOfParticipants, payload: incompletePayload })
// Create the expected MeetingDamage object
const meetingDamage = new MeetingDamage({
hardwareComponents: payload[meetingCategoryDamage.HARDWARE],
softwareComponents: payload[meetingCategoryDamage.SOFTWARE],
journeyComponents: payload[meetingCategoryDamage.JOURNEY]
describe('#constructor()', () => {
it('should create a MeetingScenario without components in all categories', () => {
assert.notStrictEqual(incompleteScenario.damage.softwareDamage.components, new Map())
})
})
// Compute its total damage
meetingDamage.computeDamage(damagePayload)
// Compute meeting total damage
meetingScenario.computeDamage(damagePayload)
describe('#computeDamage()', () => {
// Create the JSON object that enables to compute meeting total damage
const damagePayload = {
[meetingCategoryDamage.HARDWARE]: { meetingDuration: 120, bound: bounds.UPPER },
[meetingCategoryDamage.SOFTWARE]: { instancesNumber: 5, bandwithBound: bounds.UPPER, networkBound: bounds.UPPER, meetingDuration: 120 },
[meetingCategoryDamage.JOURNEY]: {}
}
// Create the expected MeetingDamage object
const meetingDamage = new MeetingDamage({
hardware: payload[meetingCategoryDamage.HARDWARE],
software: payload[meetingCategoryDamage.SOFTWARE],
journey: payload[meetingCategoryDamage.JOURNEY]
})
// Compute its total damage
meetingDamage.computeDamage(damagePayload)
// Compute meeting total damage
meetingScenario.computeDamage(damagePayload)
it('should compute the total damage caused by the meeting', () => {
assert.deepStrictEqual(
meetingScenario.damage.totalDamage,
meetingDamage.totalDamage
)
Object.keys(meetingScenario.damage.totalDamage).forEach(category => {
assert.strictEqual(meetingScenario.damage.totalDamage[category], meetingDamage.totalDamage[category])
assert.isNotNaN(meetingScenario.damage.totalDamage[category])
assert.isNotNull(meetingScenario.damage.totalDamage[category])
assert.notEqual(0, meetingScenario.damage.totalDamage[category])
})
})
it('should compute the damage of an incomplete scenario', () => {
const damagePayload = {
[meetingCategoryDamage.HARDWARE]: { meetingDuration: 120, bound: bounds.UPPER },
[meetingCategoryDamage.SOFTWARE]: { instancesNumber: 5, bandwithBound: bounds.UPPER, networkBound: bounds.UPPER, meetingDuration: 120 },
[meetingCategoryDamage.JOURNEY]: {}
}
incompleteScenario.computeDamage(damagePayload)
const damage = incompleteScenario.damage.totalDamage
const expected = incompleteScenario.damage.hardwareDamage.totalDamage.add(incompleteScenario.damage.softwareDamage.totalDamage)
Object.keys(damage).forEach(category => {
assert.strictEqual(damage[category], expected[category])
assert.isNotNaN(damage[category])
assert.isNotNull(damage[category])
assert.notEqual(0, damage[category])
})
})
})
describe('#generateAlternatives()', () => {
......@@ -115,7 +147,6 @@ describe('MeetingScenario class', () => {
)
})
})
describe('#read()', () => {
it('should read a meetingScenario thanks to its id', () => {
meetingScenarios.forEach(element => {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment