More test cleanup

This commit is contained in:
pietervdvn 2022-03-21 02:00:50 +01:00
parent b67e108056
commit 3ab373f6ec
9 changed files with 179 additions and 370 deletions

View file

@ -32,6 +32,32 @@ export class OH {
return Utils.TwoDigits(h) + ":" + Utils.TwoDigits(m);
}
/**
* const rules = [{weekday: 6,endHour: 17,endMinutes: 0,startHour: 13,startMinutes: 0},
* {weekday: 1,endHour: 12,endMinutes: 0,startHour: 10,startMinutes: 0}]
* OH.ToString(rules) // => "Tu 10:00-12:00; Su 13:00-17:00"
*
* const rules = [{weekday: 3,endHour: 17,endMinutes: 0,startHour: 13,startMinutes: 0}, {weekday: 1,endHour: 12,endMinutes: 0,startHour: 10,startMinutes: 0}]
* OH.ToString(rules) // => "Tu 10:00-12:00; Th 13:00-17:00"
*
* const rules = [ { weekday: 1, endHour: 17, endMinutes: 0, startHour: 13, startMinutes: 0 }, { weekday: 1, endHour: 12, endMinutes: 0, startHour: 10, startMinutes: 0 }]);
* OH.ToString(rules) // => "Tu 10:00-12:00, 13:00-17:00"
*
* const rules = [ { weekday: 0, endHour: 12, endMinutes: 0, startHour: 10, startMinutes: 0 }, { weekday: 0, endHour: 17, endMinutes: 0, startHour: 13, startMinutes: 0}, { weekday: 1, endHour: 17, endMinutes: 0, startHour: 13, startMinutes: 0 }, { weekday: 1, endHour: 12, endMinutes: 0, startHour: 10, startMinutes: 0 }];
* OH.ToString(rules) // => "Mo-Tu 10:00-12:00, 13:00-17:00"
*
* // should merge overlapping opening hours
* const timerange0 = {weekday: 1, endHour: 23, endMinutes: 30, startHour: 23, startMinutes: 0 }
* const touchingTimeRange = { weekday: 1, endHour: 0, endMinutes: 0, startHour: 23, startMinutes: 30 }
* OH.ToString(OH.MergeTimes([timerange0, touchingTimeRange])) // => "Tu 23:00-00:00"
*
* // should merge touching opening hours
* const timerange0 = {weekday: 1, endHour: 23, endMinutes: 30, startHour: 23, startMinutes: 0 }
* const overlappingTimeRange = { weekday: 1, endHour: 24, endMinutes: 0, startHour: 23, startMinutes: 30 }
* OH.ToString(OH.MergeTimes([timerange0, overlappingTimeRange])) // => "Tu 23:00-00:00"
*
*/
public static ToString(ohs: OpeningHour[]) {
if (ohs.length == 0) {
return "";
@ -86,8 +112,16 @@ export class OH {
/**
* Merge duplicate opening-hour element in place.
* Returns true if something changed
* @param ohs
* @constructor
*
* // should merge overlapping opening hours
* const oh1: OpeningHour = { weekday: 0, startHour: 10, startMinutes: 0, endHour: 11, endMinutes: 0 };
* const oh0: OpeningHour = { weekday: 0, startHour: 10, startMinutes: 30, endHour: 12, endMinutes: 0 };
* OH.MergeTimes([oh0, oh1]) // => [{ weekday: 0, startHour: 10, startMinutes: 0, endHour: 12, endMinutes: 0 }]
*
* // should merge touching opening hours
* const oh1: OpeningHour = { weekday: 0, startHour: 10, startMinutes: 0, endHour: 11, endMinutes: 0 };
* const oh0: OpeningHour = { weekday: 0, startHour: 11, startMinutes: 0, endHour: 12, endMinutes: 0 };
* OH.MergeTimes([oh0, oh1]) // => [{ weekday: 0, startHour: 10, startMinutes: 0, endHour: 12, endMinutes: 0 }]
*/
public static MergeTimes(ohs: OpeningHour[]): OpeningHour[] {
const queue = ohs.map(oh => {
@ -248,6 +282,7 @@ export class OH {
* rules[0].weekday // => 0
* rules[0].startHour // => 11
* rules[3].endHour // => 19
*
*/
public static ParseRule(rule: string): OpeningHour[] {
try {

View file

@ -209,6 +209,13 @@ export class Translation extends BaseUIElement {
return new Translation(tr);
}
/**
* Extracts all images (including HTML-images) from all the embedded translations
*
* // should detect sources of <img>
* const tr = new Translation({en: "XYZ <img src='a.svg'/> XYZ <img src=\"some image.svg\"></img> XYZ <img src=b.svg/>"})
* new Set<string>(tr.ExtractImages(false)) // new Set(["a.svg", "b.svg", "some image.svg"])
*/
public ExtractImages(isIcon = false): string[] {
const allIcons: string[] = []
for (const key in this.translations) {

View file

@ -1,45 +0,0 @@
import {equal} from "assert";
import T from "./TestHelper";
import {Translation} from "../UI/i18n/Translation";
import * as cyclofix from "../assets/generated/themes/cyclofix.json"
import {ExtractImages} from "../Models/ThemeConfig/Conversion/FixImages";
export default class ImageAttributionSpec extends T {
constructor() {
super([
[
"Should find all the images",
() => {
const images = new Set(new ExtractImages(true, new Map<string, any>()).convertStrict(<any> cyclofix, "test"))
const expectedValues = [
'./assets/layers/bike_repair_station/repair_station.svg',
'./assets/layers/bike_repair_station/repair_station_pump.svg',
'./assets/layers/bike_repair_station/broken_pump.svg',
'./assets/layers/bike_repair_station/pump.svg',
'./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg',
'./assets/layers/bike_repair_station/pump_example_manual.jpg',
'./assets/layers/bike_repair_station/pump_example.png',
'./assets/layers/bike_repair_station/pump_example_round.jpg',
'./assets/layers/bike_repair_station/repair_station_example_2.jpg',
'close']
for (const expected of expectedValues) {
T.isTrue(images.has(expected), expected + " not found")
}
}
],
[
"Test image discovery regex",
() => {
const tr = new Translation({en: "XYZ <img src='a.svg'/> XYZ <img src=\"some image.svg\"></img> XYZ <img src=b.svg/>"})
const images = new Set<string>(tr.ExtractImages(false));
equal(3, images.size)
T.isTrue(images.has("a.svg"), "a.svg not found")
T.isTrue(images.has("b.svg"), "b.svg not found")
T.isTrue(images.has("some image.svg"), "some image.svg not found")
}
]
]);
}
}

View file

@ -1,297 +0,0 @@
import {equal} from "assert";
import T from "./TestHelper";
import Locale from "../UI/i18n/Locale";
import {OH, OpeningHour} from "../UI/OpeningHours/OpeningHours";
import {Tag} from "../Logic/Tags/Tag";
import {And} from "../Logic/Tags/And";
import {TagUtils} from "../Logic/Tags/TagUtils";
import TagRenderingConfig from "../Models/ThemeConfig/TagRenderingConfig";
import {RegexTag} from "../Logic/Tags/RegexTag";
export default class TagSpec extends T {
constructor() {
super([
["Parse tag rendering", (() => {
Locale.language.setData("nl");
const tr = new TagRenderingConfig({
render: ({"en": "Name is {name}", "nl": "Ook een {name}"} as any),
question: "Wat is de naam van dit object?",
freeform: {
key: "name",
},
mappings: [
{
if: "noname=yes",
"then": "Has no name"
}
],
condition: "x="
}, "Tests");
equal(undefined, tr.GetRenderValue({"foo": "bar"}));
equal("Has no name", tr.GetRenderValue({"noname": "yes"})?.txt);
equal("Ook een {name}", tr.GetRenderValue({"name": "xyz"})?.txt);
equal(undefined, tr.GetRenderValue({"foo": "bar"}));
})],
[
"Merge touching opening hours",
() => {
const oh1: OpeningHour = {
weekday: 0,
startHour: 10,
startMinutes: 0,
endHour: 11,
endMinutes: 0
};
const oh0: OpeningHour = {
weekday: 0,
startHour: 11,
startMinutes: 0,
endHour: 12,
endMinutes: 0
};
const merged = OH.MergeTimes([oh0, oh1]);
const r = merged[0];
equal(merged.length, 1);
equal(r.startHour, 10);
equal(r.endHour, 12)
}
],
[
"Merge overlapping opening hours",
() => {
const oh1: OpeningHour = {
weekday: 0,
startHour: 10,
startMinutes: 0,
endHour: 11,
endMinutes: 0
};
const oh0: OpeningHour = {
weekday: 0,
startHour: 10,
startMinutes: 30,
endHour: 12,
endMinutes: 0
};
const merged = OH.MergeTimes([oh0, oh1]);
const r = merged[0];
equal(merged.length, 1);
equal(r.startHour, 10);
equal(r.endHour, 12)
}],
["JOIN OH 1", () => {
const rules = OH.ToString([
{
weekday: 0,
endHour: 12,
endMinutes: 0,
startHour: 10,
startMinutes: 0
},
{
weekday: 0,
endHour: 17,
endMinutes: 0,
startHour: 13,
startMinutes: 0
},
{
weekday: 1,
endHour: 17,
endMinutes: 0,
startHour: 13,
startMinutes: 0
}, {
weekday: 1,
endHour: 12,
endMinutes: 0,
startHour: 10,
startMinutes: 0
},
]);
equal(rules, "Mo-Tu 10:00-12:00, 13:00-17:00");
}],
["JOIN OH 2", () => {
const rules = OH.ToString([
{
weekday: 1,
endHour: 17,
endMinutes: 0,
startHour: 13,
startMinutes: 0
}, {
weekday: 1,
endHour: 12,
endMinutes: 0,
startHour: 10,
startMinutes: 0
},
]);
equal(rules, "Tu 10:00-12:00, 13:00-17:00");
}],
["JOIN OH 3", () => {
const rules = OH.ToString([
{
weekday: 3,
endHour: 17,
endMinutes: 0,
startHour: 13,
startMinutes: 0
}, {
weekday: 1,
endHour: 12,
endMinutes: 0,
startHour: 10,
startMinutes: 0
},
]);
equal(rules, "Tu 10:00-12:00; Th 13:00-17:00");
}],
["JOIN OH 3", () => {
const rules = OH.ToString([
{
weekday: 6,
endHour: 17,
endMinutes: 0,
startHour: 13,
startMinutes: 0
}, {
weekday: 1,
endHour: 12,
endMinutes: 0,
startHour: 10,
startMinutes: 0
},
]);
equal(rules, "Tu 10:00-12:00; Su 13:00-17:00");
}],
["JOIN OH with end hours", () => {
const rules = OH.ToString(
OH.MergeTimes([
{
weekday: 1,
endHour: 23,
endMinutes: 30,
startHour: 23,
startMinutes: 0
}, {
weekday: 1,
endHour: 24,
endMinutes: 0,
startHour: 23,
startMinutes: 30
},
]));
equal(rules, "Tu 23:00-00:00");
}],
["JOIN OH with overflowed hours", () => {
const rules = OH.ToString(
OH.MergeTimes([
{
weekday: 1,
endHour: 23,
endMinutes: 30,
startHour: 23,
startMinutes: 0
}, {
weekday: 1,
endHour: 0,
endMinutes: 0,
startHour: 23,
startMinutes: 30
},
]));
equal(rules, "Tu 23:00-00:00");
}],
["Regression", () => {
const config = {
"#": "Bottle refill",
"question": {
"en": "How easy is it to fill water bottles?",
"nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?",
"de": "Wie einfach ist es, Wasserflaschen zu füllen?"
},
"mappings": [
{
"if": "bottle=yes",
"then": {
"en": "It is easy to refill water bottles",
"nl": "Een drinkbus bijvullen gaat makkelijk",
"de": "Es ist einfach, Wasserflaschen nachzufüllen"
}
},
{
"if": "bottle=no",
"then": {
"en": "Water bottles may not fit",
"nl": "Een drinkbus past moeilijk",
"de": "Wasserflaschen passen möglicherweise nicht"
}
}
]
};
const tagRendering = new TagRenderingConfig(config, "test");
equal(true, tagRendering.IsKnown({bottle: "yes"}))
equal(false, tagRendering.IsKnown({}))
}],
[
"Tag matches a lazy property",
() => {
const properties = {}
const key = "_key"
Object.defineProperty(properties, key, {
configurable: true,
get: function () {
delete properties[key]
properties[key] = "yes"
return "yes"
}
})
const filter = new Tag("_key", "yes")
T.isTrue(filter.matchesProperties(properties), "Lazy value not matched")
}
],
[
"RegextTag matches a lazy property",
() => {
const properties = {}
const key = "_key"
Object.defineProperty(properties, key, {
configurable: true,
get: function () {
delete properties[key]
properties[key] = "yes"
return "yes"
}
})
const filter = TagUtils.Tag("_key~*")
T.isTrue(filter.matchesProperties(properties), "Lazy value not matched")
}
]]);
}
}

View file

@ -1,50 +1,32 @@
import TagSpec from "./Tag.spec";
import ImageAttributionSpec from "./ImageAttribution.spec";
import GeoOperationsSpec from "./GeoOperations.spec";
import ThemeSpec from "./Theme.spec";
import UtilsSpec from "./Utils.spec";
import OsmObjectSpec from "./OsmObject.spec";
import ScriptUtils from "../scripts/ScriptUtils";
import UnitsSpec from "./Units.spec";
import RelationSplitHandlerSpec from "./RelationSplitHandler.spec";
import SplitActionSpec from "./SplitAction.spec";
import {Utils} from "../Utils";
import TileFreshnessCalculatorSpec from "./TileFreshnessCalculator.spec";
import ImageProviderSpec from "./ImageProvider.spec";
import ActorsSpec from "./Actors.spec";
import ReplaceGeometrySpec from "./ReplaceGeometry.spec";
import LegacyThemeLoaderSpec from "./LegacyThemeLoader.spec";
import T from "./TestHelper";
import CreateNoteImportLayerSpec from "./CreateNoteImportLayer.spec";
import CreateCacheSpec from "./CreateCache.spec";
import CodeQualitySpec from "./CodeQuality.spec";
import ImportMultiPolygonSpec from "./ImportMultiPolygon.spec";
import ChangesetHandlerSpec from "./ChangesetHandler.spec";
import ChangesSpec from "./Changes.spec";
async function main() {
const allTests: T[] = [
new ChangesSpec(),
new ChangesetHandlerSpec(),
new OsmObjectSpec(),
new TagSpec(),
new ImageAttributionSpec(),
new GeoOperationsSpec(),
new ThemeSpec(),
new UtilsSpec(),
new UnitsSpec(),
new RelationSplitHandlerSpec(),
new SplitActionSpec(),
new TileFreshnessCalculatorSpec(),
new ImageProviderSpec(),
new ActorsSpec(),
new ReplaceGeometrySpec(),
new LegacyThemeLoaderSpec(),
new CreateNoteImportLayerSpec(),
new CreateCacheSpec(),
new CodeQualitySpec(),
new ImportMultiPolygonSpec(),
]
ScriptUtils.fixUtils();

View file

@ -8,12 +8,6 @@ export default class T {
this._tests = tests;
}
static assertContains(needle: string, actual: string) {
if (actual.indexOf(needle) < 0) {
throw `The substring ${needle} was not found`
}
}
static isTrue(b: boolean, msg: string) {
if (!b) {
throw "Expected true, but got false: " + msg

View file

@ -0,0 +1,41 @@
import {describe} from 'mocha'
import {expect} from 'chai'
import {TagUtils} from "../../../Logic/Tags/TagUtils";
import T from "../../../testLegacy/TestHelper";
import {Tag} from "../../../Logic/Tags/Tag";
describe("Lazy object properties", () => {
it("should be matche by a normal tag", () => {
const properties = {}
const key = "_key"
Object.defineProperty(properties, key, {
configurable: true,
get: function () {
delete properties[key]
properties[key] = "yes"
return "yes"
}
})
const filter = new Tag("_key", "yes")
expect(filter.matchesProperties(properties)).true
})
it("should be matched by a RegexTag", () => {
const properties = {}
const key = "_key"
Object.defineProperty(properties, key, {
configurable: true,
get: function () {
delete properties[key]
properties[key] = "yes"
return "yes"
}
})
const filter = TagUtils.Tag("_key~*")
expect(filter.matchesProperties(properties)).true;
})
})

View file

@ -1,14 +1,14 @@
import {describe} from 'mocha'
import {expect} from 'chai'
import {LayoutConfigJson} from "../../../../Models/ThemeConfig/Json/LayoutConfigJson";
import Constants from "../../../../Models/Constants";
import {LayerConfigJson} from "../../../../Models/ThemeConfig/Json/LayerConfigJson";
import {PrepareTheme} from "../../../../Models/ThemeConfig/Conversion/PrepareTheme";
import {TagRenderingConfigJson} from "../../../../Models/ThemeConfig/Json/TagRenderingConfigJson";
import LayoutConfig from "../../../../Models/ThemeConfig/LayoutConfig";
import assert from "assert";
import * as bookcaseLayer from "../../../../assets/generated/layers/public_bookcase.json"
import LayerConfig from "../../../../Models/ThemeConfig/LayerConfig";
import {ExtractImages} from "../../../../Models/ThemeConfig/Conversion/FixImages";
import * as cyclofix from "../../../../assets/generated/themes/cyclofix.json"
const themeConfigJson: LayoutConfigJson = {
@ -52,3 +52,24 @@ describe("PrepareTheme", () => {
})
})
describe("ExtractImages", () => {
it("should find all images in a themefile", () => {
const images = new Set(new ExtractImages(true, new Map<string, any>()).convertStrict(<any> cyclofix, "test"))
const expectedValues = [
'./assets/layers/bike_repair_station/repair_station.svg',
'./assets/layers/bike_repair_station/repair_station_pump.svg',
'./assets/layers/bike_repair_station/broken_pump.svg',
'./assets/layers/bike_repair_station/pump.svg',
'./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg',
'./assets/layers/bike_repair_station/pump_example_manual.jpg',
'./assets/layers/bike_repair_station/pump_example.png',
'./assets/layers/bike_repair_station/pump_example_round.jpg',
'./assets/layers/bike_repair_station/repair_station_example_2.jpg',
'close']
for (const expected of expectedValues) {
expect(images).contains(expected)
}
})
})

View file

@ -0,0 +1,71 @@
import {describe} from 'mocha'
import {expect} from 'chai'
import TagRenderingConfig from "../../../Models/ThemeConfig/TagRenderingConfig";
import Locale from "../../../UI/i18n/Locale";
describe("TagRenderingConfig", () => {
describe("isKnown", () => {
it("should give correct render values", () => {
Locale.language.setData("nl");
const tr = new TagRenderingConfig({
render: ({"en": "Name is {name}", "nl": "Ook een {name}"} as any),
question: "Wat is de naam van dit object?",
freeform: {
key: "name",
},
mappings: [
{
if: "noname=yes",
"then": "Has no name"
}
],
condition: "x="
}, "Tests");
expect(tr.GetRenderValue({"foo": "bar"})).undefined
expect (tr.GetRenderValue({"noname": "yes"})?.textFor("nl")).eq("Has no name")
expect( tr.GetRenderValue({"name": "xyz"})?.textFor("nl")).eq("Ook een {name}")
expect( tr.GetRenderValue({"foo": "bar"})).undefined
})
it("should give a correct indication", () => {
// tests a regression in parsing
const config = {
"#": "Bottle refill",
"question": {
"en": "How easy is it to fill water bottles?",
"nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?",
"de": "Wie einfach ist es, Wasserflaschen zu füllen?"
},
"mappings": [
{
"if": "bottle=yes",
"then": {
"en": "It is easy to refill water bottles",
"nl": "Een drinkbus bijvullen gaat makkelijk",
"de": "Es ist einfach, Wasserflaschen nachzufüllen"
}
},
{
"if": "bottle=no",
"then": {
"en": "Water bottles may not fit",
"nl": "Een drinkbus past moeilijk",
"de": "Wasserflaschen passen möglicherweise nicht"
}
}
]
};
const tagRendering = new TagRenderingConfig(config, "test");
expect(tagRendering.IsKnown({bottle: "yes"})).true
expect(tagRendering.IsKnown({})).false
})
})
})