Skip to content

Commit

Permalink
Add units tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pierotofy committed May 8, 2024
1 parent 9a8013d commit e0eb7ca
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 36 deletions.
91 changes: 66 additions & 25 deletions app/static/app/js/classes/Units.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { _ } from '../classes/gettext';
import { _ } from './gettext';

const units = {
acres: {
Expand Down Expand Up @@ -47,77 +47,118 @@ const units = {
factor: 10.7639,
label: _('Square Feet'),
abbr: 'ft²',
round: 2,
round: 2
},
sqmeters: {
factor: 1,
label: _('Square Meters'),
abbr: 'm²',
round: 2,
round: 2
},
sqmeters: {
factor: 0.000001,
label: _('Square Kilometers'),
abbr: 'km²',
round: 5
},
sqmiles: {
factor: 0.000000386102,
label: _('Square Miles'),
abbr: 'mi²',
round: 5
}
};
};

class ValueUnit{
constructor(val, unit){
this.val = val;
this.unit = unit;
}

toString(){
const mul = Math.pow(10, this.unit.round);
const rounded = (Math.round(this.val * mul) / mul).toString();

let withCommas = "";
let parts = rounded.split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
withCommas = parts.join(".");

return `${withCommas} ${this.unit.abbr}`;
}
}

class UnitSystem{
lengthUnit(meters){ throw new Error("Not implemented"); }
areaUnit(sqmeters){ throw new Error("Not implemented"); }
getName(){ throw new Error("Not implemented"); }

area(meters){

area(sqmeters){
const unit = this.areaUnit(sqmeters);
const val = unit.factor * sqmeters;
return new ValueUnit(val, unit);
}

length(sqmeters){
const unit = this.lengthUnit(sqmeters);
const v = unit.factor * sqmeters;
return {v, s: `{v.toLocaleString()}` };
length(meters){
const unit = this.lengthUnit(meters);
const val = unit.factor * meters;
return new ValueUnit(val, unit);
}
};

class Metric extends UnitSystem{
class MetricSystem extends UnitSystem{
getName(){
return _("Metric");
}

lengthUnit(meters){
if (meters < 100) return units.centimeters;
if (meters < 1) return units.centimeters;
else if (meters >= 1000) return units.kilometers;
else return units.meters;
}

areaUnit(sqmeters){
return units.sqmeters; // TODO
if (sqmeters >= 10000 && sqmeters < 1000000) return units.hectares;
else if (sqmeters >= 1000000) return units.sqkilometers;
return units.sqmeters;
}
}

class Imperial extends UnitSystem{
class ImperialSystem extends UnitSystem{
getName(){
return _("Imperial");
}

lengthUnit(meters){
const feet = units.feet.factor * meters;
if (feet >= 5280) return units.miles;
else return units.feet;
}

areaUnit(sqmeters){
const sqfeet = units.sqfeet.factor * meters;
const sqfeet = units.sqfeet.factor * sqmeters;
if (sqfeet >= 43560 && sqfeet < 27878400) return units.acres;
else if (sqfeet >= 27878400) return units.sqmiles;
else return units.sqfeet;
}
}

const systems = {
metric: new Metric(),


// TODO
metric: new MetricSystem(),
imperial: new ImperialSystem()
}

let a = 100;
let S = systems.metric;

// Expose to allow every part of the app to access this information
function getPreferredUnitSystem(){
return localStorage.getItem("preferred_unit_system") || "metric";
}
function setPreferredUnitSystem(system){
localStorage.setItem("preferred_unit_system", system);
}

export default {
// to be used on individual strings

export {
systems,
getPreferredUnitSystem,
setPreferredUnitSystem
};

16 changes: 16 additions & 0 deletions app/static/app/js/components/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import '../vendor/leaflet/Leaflet.Ajax';
import 'rbush';
import '../vendor/leaflet/leaflet-markers-canvas';
import { _ } from '../classes/gettext';
import UnitSelector from './UnitSelector';

class Map extends React.Component {
static defaultProps = {
Expand Down Expand Up @@ -404,6 +405,21 @@ class Map extends React.Component {
position:'bottomleft'
}).addTo(this.map);

const UnitsCtrl = Leaflet.Control.extend({
options: {
position: 'bottomleft'
},

onAdd: function () {
this.container = Leaflet.DomUtil.create('div', 'leaflet-control-units-selection leaflet-control');
Leaflet.DomEvent.disableClickPropagation(this.container);
ReactDOM.render(<UnitSelector />, this.container);
return this.container;
}
});
new UnitsCtrl().addTo(this.map);


if (showBackground) {
this.basemaps = {};

Expand Down
10 changes: 7 additions & 3 deletions app/static/app/js/components/UnitSelector.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { systems, getPreferredUnitSystem, setPreferredUnitSystem } from '../classes/Units';

class UnitSelector extends React.Component {
static propTypes = {
Expand All @@ -9,19 +10,22 @@ class UnitSelector extends React.Component {
super(props);

this.state = {
system: window.getPreferredUnitSystem()
system: getPreferredUnitSystem()
}

// console.log(systems.metric.length(1.01).toString());
}

handleChange = e => {
this.setState({system: e.target.value});
window.setPreferredUnitSystem(e.target.value);
setPreferredUnitSystem(e.target.value);
};

render() {
return (
<select value={this.state.system} onChange={this.handleChange}>
<option value="metric" key={}></option>
{Object.keys(systems).map(k =>
<option value={k} key={k}>{systems[k].getName()}</option>)}
</select>
);
}
Expand Down
41 changes: 41 additions & 0 deletions app/static/app/js/components/tests/Units.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { systems } from '../../classes/Units';

describe('Metric system', () => {
it('it should display units properly', () => {

const { metric } = systems;

const lengths = [
[1, "1 m"],
[0.01, "1 cm"],
[0.0154, "1.5 cm"],
[0.99, "99 cm"],
[0.995555, "99.6 cm"],
[1.01, "1.01 m"],
[999, "999 m"],
[1000, "1 km"],
[1001, "1.001 km"],
[1000010, "1,000.01 km"],
[1000012.349, "1,000.01235 km"],
];

lengths.forEach(l => {
expect(metric.length(l[0]).toString()).toBe(l[1]);
});

const areas = [
[1, "1 m²"],
[9999, "9,999 m²"],
[10000, "1 ha"],
[11005, "1.1005 ha"],
[11005, "1.1005 ha"],
[999999, "99.9999 ha"],
[1000000, "1 km²"],
[1000000000, "1,000 km²"]
];

areas.forEach(a => {
expect(metric.area(a[0]).toString()).toBe(a[1]);
});
})
});
8 changes: 0 additions & 8 deletions app/static/app/js/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ window.React = React;
// Expose set locale function globally
window.setLocale = setLocale;

// Expose to allow every part of the app to access this information
window.getPreferredUnitSystem = () => {
return localStorage.getItem("preferred_unit_system") || "metric";
};
window.setPreferredUnitSystem = (system) => {
localStorage.setItem("preferred_unit_system", system);
};

$(function(){
PluginsAPI.App.triggerReady();
});
Expand Down

0 comments on commit e0eb7ca

Please sign in to comment.