forked from MapComplete/MapComplete
Fix: force a space between value and denomination (e.g. 20 mph
), add integration test for this
This commit is contained in:
parent
946439f8c3
commit
258cbe0802
4 changed files with 43 additions and 29 deletions
|
@ -13,7 +13,7 @@ type Brand<B> = { [__is_optimized]: B }
|
|||
*/
|
||||
export type OptimizedTag = Brand<TagsFilter>
|
||||
|
||||
export type UploadableTag = Tag | SubstitutingTag | And
|
||||
export type UploadableTag = Tag | SubstitutingTag | And<UploadableTag>
|
||||
/**
|
||||
* Not nested
|
||||
*/
|
||||
|
|
|
@ -328,22 +328,6 @@ export class TagUtils {
|
|||
return keyValues
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens an 'uploadableTag' and replaces all 'SubstitutingTags' into normal tags
|
||||
*/
|
||||
static FlattenAnd(tagFilters: UploadableTag, currentProperties: Record<string, string>): Tag[] {
|
||||
const tags: Tag[] = []
|
||||
tagFilters.visit((tf: UploadableTag) => {
|
||||
if (tf instanceof Tag) {
|
||||
tags.push(tf)
|
||||
}
|
||||
if (tf instanceof SubstitutingTag) {
|
||||
tags.push(tf.asTag(currentProperties))
|
||||
}
|
||||
})
|
||||
return tags
|
||||
}
|
||||
|
||||
static optimzeJson(json: TagConfigJson): TagConfigJson | boolean {
|
||||
const optimized = TagUtils.Tag(json).optimize()
|
||||
if (optimized === true || optimized === false) {
|
||||
|
@ -1024,4 +1008,14 @@ export class TagUtils {
|
|||
}
|
||||
return tag
|
||||
}
|
||||
|
||||
static flattenAnd(tg: UploadableTag | UploadableTag[]): (SubstitutingTag | Tag)[] {
|
||||
if (Array.isArray(tg)) {
|
||||
return tg.flatMap(t => TagUtils.flattenAnd(t))
|
||||
}
|
||||
if (tg["and"] || tg instanceof And) {
|
||||
return tg["and"].flatMap(tg => TagUtils.flattenAnd(tg))
|
||||
}
|
||||
return [tg]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,7 @@ import { TagUtils } from "../../Logic/Tags/TagUtils"
|
|||
import { And } from "../../Logic/Tags/And"
|
||||
import { Utils } from "../../Utils"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import {
|
||||
MappingConfigJson,
|
||||
QuestionableTagRenderingConfigJson,
|
||||
} from "./Json/QuestionableTagRenderingConfigJson"
|
||||
import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "./Json/QuestionableTagRenderingConfigJson"
|
||||
import Validators, { ValidatorType } from "../../UI/InputElement/Validators"
|
||||
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson"
|
||||
import { RegexTag } from "../../Logic/Tags/RegexTag"
|
||||
|
@ -23,6 +20,7 @@ import ComparingTag from "../../Logic/Tags/ComparingTag"
|
|||
import { Unit } from "../Unit"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
import { IsOnline } from "../../Logic/Web/IsOnline"
|
||||
import SubstitutingTag from "../../Logic/Tags/SubstitutingTag"
|
||||
|
||||
export interface Mapping {
|
||||
readonly if: UploadableTag
|
||||
|
@ -803,7 +801,7 @@ export default class TagRenderingConfig {
|
|||
multiSelectedMapping: boolean[] | undefined,
|
||||
currentProperties: Record<string, string>,
|
||||
unit?: Unit
|
||||
): UploadableTag[] {
|
||||
): (Tag | SubstitutingTag)[] {
|
||||
if (typeof freeformValue === "string") {
|
||||
freeformValue = freeformValue?.trim()
|
||||
}
|
||||
|
@ -820,7 +818,8 @@ export default class TagRenderingConfig {
|
|||
valueNoUnit,
|
||||
() => currentProperties["_country"]
|
||||
)
|
||||
freeformValue = formatted + denom.canonical
|
||||
// In general, we want a space between the amount and the unit
|
||||
freeformValue = formatted + " " + denom.canonical
|
||||
} else {
|
||||
freeformValue = validator.reformat(
|
||||
freeformValue,
|
||||
|
@ -865,7 +864,7 @@ export default class TagRenderingConfig {
|
|||
const freeformOnly = { [this.freeform.key]: freeformValue }
|
||||
const matchingMapping = this.mappings?.find((m) => m.if.matchesProperties(freeformOnly))
|
||||
if (matchingMapping) {
|
||||
return [matchingMapping.if, ...(matchingMapping.addExtraTags ?? [])]
|
||||
return [...TagUtils.flattenAnd(matchingMapping.if), ...(matchingMapping.addExtraTags ?? [])]
|
||||
}
|
||||
// Either no mappings, or this is a radio-button selected freeform value
|
||||
const tag = [
|
||||
|
@ -877,7 +876,7 @@ export default class TagRenderingConfig {
|
|||
return undefined
|
||||
}
|
||||
|
||||
return tag
|
||||
return TagUtils.flattenAnd(tag)
|
||||
}
|
||||
|
||||
if (this.multiAnswer) {
|
||||
|
@ -907,7 +906,7 @@ export default class TagRenderingConfig {
|
|||
) {
|
||||
return undefined
|
||||
}
|
||||
return and
|
||||
return TagUtils.flattenAnd(and)
|
||||
}
|
||||
|
||||
// Is at least one mapping shown in the answer?
|
||||
|
@ -927,11 +926,11 @@ export default class TagRenderingConfig {
|
|||
if (useFreeform) {
|
||||
return [
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
...(TagUtils.flattenAnd(this.freeform.addExtraTags) ?? [])
|
||||
]
|
||||
} else if (singleSelectedMapping !== undefined) {
|
||||
return [
|
||||
this.mappings[singleSelectedMapping].if,
|
||||
...TagUtils.flattenAnd(this.mappings[singleSelectedMapping].if),
|
||||
...(this.mappings[singleSelectedMapping].addExtraTags ?? []),
|
||||
]
|
||||
} else {
|
||||
|
@ -1188,7 +1187,7 @@ export class TagRenderingConfigUtils {
|
|||
console.log("Could not download the NSI: ", extraMappingsErr["error"])
|
||||
return config
|
||||
}
|
||||
const extraMappings = extraMappingsErr?.success
|
||||
const extraMappings = extraMappingsErr?.["success"]
|
||||
if(extraMappings === undefined){
|
||||
if(!IsOnline.isOnline.data){
|
||||
// The 'extraMappings' will still attempt to download the NSI - it might be in the service worker's cache
|
||||
|
|
21
test/integration/UnitHasSpace.spec.ts
Normal file
21
test/integration/UnitHasSpace.spec.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { describe, it } from "vitest"
|
||||
import LayerConfig from "../../src/Models/ThemeConfig/LayerConfig"
|
||||
import maxspeed_layer from "../../public/assets/generated/layers/maxspeed.json"
|
||||
import { LayerConfigJson } from "../../src/Models/ThemeConfig/Json/LayerConfigJson"
|
||||
import { expect } from "chai"
|
||||
import { Tag } from "../../src/Logic/Tags/Tag"
|
||||
|
||||
describe("Integration_unit_has_space", () => {
|
||||
it("maxspeed should produce '20 mph' and not '20mph'", () => {
|
||||
const maxspeed = new LayerConfig(
|
||||
<LayerConfigJson><any>maxspeed_layer, "integration_test"
|
||||
)
|
||||
const maxspeedQuestion = maxspeed.tagRenderings.find(tr => tr.id === "maxspeed-maxspeed")
|
||||
const unit = maxspeed.units.find(unit => unit.appliesToKeys.has("maxspeed"))
|
||||
const spec = maxspeedQuestion.constructChangeSpecification("20", undefined, undefined, {
|
||||
"_country": "gb"
|
||||
}, unit).find(t => t["key"] === "maxspeed")
|
||||
expect(spec.asJson()).to.eq(new Tag("maxspeed", "20 mph").asJson())
|
||||
})
|
||||
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue