Add units tests

pull/1496/head
Piero Toffanin 2024-05-08 10:48:29 -04:00
rodzic 9a8013d6ce
commit e0eb7cad7e
5 zmienionych plików z 130 dodań i 36 usunięć

Wyświetl plik

@ -1,4 +1,4 @@
import { _ } from '../classes/gettext';
import { _ } from './gettext';
const units = {
acres: {
@ -47,13 +47,19 @@ 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,
@ -61,36 +67,68 @@ const units = {
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;
@ -98,7 +136,7 @@ class Imperial extends UnitSystem{
}
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;
@ -106,18 +144,21 @@ class Imperial extends UnitSystem{
}
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
};

Wyświetl plik

@ -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 = {
@ -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 = {};

Wyświetl plik

@ -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 = {
@ -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>
);
}

Wyświetl plik

@ -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]);
});
})
});

Wyświetl plik

@ -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();
});