Weighted person names, valid personal ids and date() in both locales #21
+17
-8
@@ -34,15 +34,24 @@ replacement, and each removed path, column or flag.
|
||||
`en_US.address` read those records, so `en_US.address.street` no longer carries
|
||||
`name` and `suffix`, and a locale folder loads only beside `geo`.
|
||||
- `{date(from,to,'layout')}` and `{time('layout')}`: a second between two days, or
|
||||
within one, in a quoted Go layout. `sv_SE.date`, `en_US.date`, `sv_SE.time` and
|
||||
`en_US.time` render through them, so `date.year`, `date.month`, `date.day` and
|
||||
`time.hour` are no longer paths, and `misc.datetime` is an RFC 3339 instant.
|
||||
within one, in a single-quoted Go layout, drawn in UTC; `from` may equal `to`.
|
||||
`sv_SE.date`, `en_US.date`, `sv_SE.time` and `en_US.time` render through them, so
|
||||
`date.year`, `date.month`, `date.day`, `time.hour`, `time.minute`, `time.minute.t`,
|
||||
`time.sec` and `time.ampm` are no longer paths — a part of a date is now its own
|
||||
`{date(…,'2006')}`. `misc.datetime` is an RFC 3339 instant.
|
||||
- `sex`, `first-name` and `last-name` tables in `sv_SE` and `en_US`, weighted by
|
||||
bearers from SCB, the SSA and the Census Bureau; `first-name` links to `sex`, and a
|
||||
name both sexes carry is a row under each. `person` reads them, so its columns are
|
||||
`first`, `last`, `prefix` and `sex`, and `person.femalefirst` and
|
||||
`person.malefirst` are no longer paths.
|
||||
`first`, `last`, `prefix` and `sex`; `person.femalefirst` and `person.malefirst` are
|
||||
no longer paths — draw `sex[f].first-name` and `sex[m].first-name` instead.
|
||||
`en_US.title` links to `sex` as well, so `en_US.person.prefix` draws `Mr` or `Ms`
|
||||
without contradicting the record's `sex`.
|
||||
- `sv_SE.personnummer` and `sv_SE.samordningsnummer`, Skatteverket's test series
|
||||
from a `sv_SE.birth-number` table under `sex`, in place of `sv_SE.ssn`; `en_US.ssn`
|
||||
in the ranges the SSA assigns, and `en_US.itin`. `en_US.person.prefix` no longer
|
||||
draws `Mr`, `Mrs`, `Ms` or `Miss`, which could contradict the record's `sex`.
|
||||
from a `sv_SE.birth-number` table under `sex`, in place of `sv_SE.ssn`, whose
|
||||
`ssn.mmdd`, `ssn.mmdd.m` and `ssn.mmdd.d` go with it. `en_US.ssn` now draws the
|
||||
ranges the SSA assigns and carries the columns `area`, `group` and `serial`, so
|
||||
`--format csv en_US.ssn` writes a header where it used to fail; `en_US.itin` is new.
|
||||
- An error names a spelling that runs: a layout is named single-quoted and free of
|
||||
its own quotes, a row of a table with no key is named as the path that selects it,
|
||||
`sv_SE.sex[f].first-name[Kim]`, and a category with no columns names the record
|
||||
that gives it one.
|
||||
|
||||
@@ -22,6 +22,7 @@ fejkdata 'geo.SE.locality[Lund].street' # Fjelievägen — a linked tabl
|
||||
fejkdata --data-path ./mydata sv_SE.word # layer a directory over the shipped data
|
||||
fejkdata --no-shipped-data -d ./mydata --list # only your data
|
||||
fejkdata 'name: {/sv_SE.person.last}' # name: <a surname> — an inline template
|
||||
fejkdata "{date(1990-01-01,2010-12-31,'2006-01-02')}" # 2003-11-27 — the argument in "…", the layout in '…'
|
||||
fejkdata '{"format":"name: {x}","x":["bosse","lina"]}' # name: bosse or name: lina
|
||||
```
|
||||
|
||||
@@ -237,7 +238,16 @@ draws a woman's name, and a name both sexes carry is a row under each, so
|
||||
`person` reads one draw of the three, so its `first` and `sex` columns agree, and so
|
||||
does a `personnummer` in the same render: its birth number, `sv_SE.birth-number`
|
||||
under `sex`, is Skatteverket's test series, 238 for a woman and 239 for a man, which no
|
||||
real person is ever given.
|
||||
real person is ever given. `en_US.title` links to `sex` too, so a person's prefix
|
||||
never contradicts it.
|
||||
|
||||
A person of a chosen sex is assembled from the tables — `sex[f].first-name` beside
|
||||
`last-name` — while a shipped `personnummer` agrees with the sex its own render
|
||||
*drew*, not with one a path selects. That test series is also small: a personnummer
|
||||
is one of about 70,000 values, a day in 1930–2025 against the two birth numbers, so a
|
||||
fixture past a few hundred rows repeats one and a `UNIQUE` column needs a category of
|
||||
your own. `sv_SE.date` and `en_US.date` are uniform over 1970-01-01 to 2029-12-31,
|
||||
`misc.datetime` over 2000-01-01 to 2029-12-31.
|
||||
|
||||
A `geo` folder holds one tree per country under its alpha-2 code: five
|
||||
[linked tables](#linked-tables) named alike, and an `address` record over one
|
||||
@@ -536,12 +546,14 @@ them a birthdate:
|
||||
Renders e.g. `811218-2389`. A layout is Go's: the reference time `Mon Jan 2
|
||||
15:04:05 MST 2006` spelled as the output should look, quoted, since a layout may
|
||||
carry the comma that separates arguments, with English names. Every second
|
||||
between the two days is reachable, so a layout with a clock draws the time too.
|
||||
between the two days is reachable, so a layout with a clock draws the time too, and
|
||||
`from` may equal `to`, which is that one day. The instant is UTC, so a zone in the
|
||||
layout prints `UTC` or `Z`.
|
||||
The quotes delimit a layout outside a selector only, so `[O'Fallon]` in an
|
||||
argument stays a name. Rejected at `New`: a bound that is no calendar date, or not
|
||||
before the other; an unquoted layout, naming the quoted one; a layout naming no field, which is text;
|
||||
for `date` a layout naming no date field, naming `time`; and for `time` a layout
|
||||
naming a date field, naming `date`. `{seq()}` spans `Fake`
|
||||
before the other; an unquoted layout, naming the single-quoted one; a layout naming no field, which is
|
||||
text, as is one day in a layout with no clock; for `date` a layout naming no date
|
||||
field, naming `time`; and for `time` a layout naming a date field, naming `date`. `{seq()}` spans `Fake`
|
||||
calls and `repeat`, resets with a new generator, and is the natural primary key for
|
||||
the SQL example above.
|
||||
|
||||
@@ -721,6 +733,15 @@ datatype and nullability, and each table's key, name, weight and parent columns;
|
||||
changes it or `data/` adds its `CHANGELOG.md` entry, which CI checks. A removed,
|
||||
renamed or retyped line is a major.
|
||||
|
||||
## Audience
|
||||
|
||||
App developers writing tests and fixtures, in Go and at a shell:
|
||||
|
||||
- a **bulk fixture author**, thousands of rows into CSV or SQL
|
||||
- a **Go test author**, filling a struct with `FakeStruct`
|
||||
- a **hand fixture author**, one value at a shell
|
||||
- a **validator-facing author**, who needs a value a real checker accepts
|
||||
|
||||
## Goals
|
||||
|
||||
1. **Valid by construction** — every value passes the check its real consumer
|
||||
@@ -1063,12 +1084,21 @@ renamed or retyped line is a major.
|
||||
bigger neighbour ship no address; counting the land outside every place too would
|
||||
drop a quarter of the places, whose codes straddle unincorporated land, for a
|
||||
postal city the USPS mostly names the same way.
|
||||
- **`--list` stays a plain list of paths.** It is what a script reads, so every line
|
||||
has to be a path that `Fake` takes; a marker for the tables a `[selector]` follows,
|
||||
or a legend above them, would make the output something to parse before use.
|
||||
`--help` names the selector spelling instead, and the Table section teaches it.
|
||||
- **A layout is always quoted.** A layout may carry the comma that separates
|
||||
arguments, `'January 2, 2006'`, and one spelling for every layout beats a rule
|
||||
about which ones need the quotes, so the bare spelling is refused naming the
|
||||
quoted one. The layout is Go's reference time because the library renders with
|
||||
it and a Go caller already knows it; its names are English, and a locale's own
|
||||
month and weekday names are data.
|
||||
- **A title is a table under `sex`.** A prefix drawn apart would put `Mr` on a record
|
||||
whose `sex` column says `female`, which is the disagreement the record exists to
|
||||
prevent; the tables this set already has are what a title needs, so `en_US.title`
|
||||
links to `sex` as `first-name` does. Swedish has no everyday sexed honorific, so
|
||||
`sv_SE` keeps an unsexed `dr` and `prof`.
|
||||
- **No builtin reads the clock, so a date is bounded by days, never by an age.**
|
||||
An `age(min,max)` would make a seeded fixture change with the day it runs on,
|
||||
which is what a seed exists to prevent; a birthdate for someone 20 to 60 is
|
||||
|
||||
@@ -164,9 +164,13 @@ address, phone, national id, company and date names each.
|
||||
1. Table node, key and name selection, parent links, consistent draws, the
|
||||
choice-of-rows fence, `DATA-LICENSES.md`, `data-import/` — done.
|
||||
2. `geo/SE` and `geo/US`, and `address` in both locales on top of them — done.
|
||||
3. Weighted person names and valid ids in both locales; `date()` — done. Middle
|
||||
names wait for a draw group that shares its family's pins, so a second name
|
||||
is drawn under the same sex.
|
||||
3. Weighted person names and valid ids in both locales; `date()` — done. Left for
|
||||
later: middle names, and drawing a shipped `personnummer` inside a *selected*
|
||||
sex, both of which want a draw group that shares its family's pins — until then
|
||||
the conflict error can name a rewrite that returns a different value when the
|
||||
read it conflicts with sits inside another category. Give the national ids one
|
||||
record shape in step 6, and report a struct column's draw conflict with the path
|
||||
spelling a tag takes rather than the reference spelling.
|
||||
4. `misc` conversions and the new `misc` tables.
|
||||
5. The remaining locale categories: company, phone, finance, vehicle, words.
|
||||
6. Records with building-block columns across the shipped set; shape re-pin.
|
||||
|
||||
Reference in New Issue
Block a user