const seeded = Fiona(1322672)

For demonstration purposes, a seed of 1322672 is used, but changing this should render different, but consistent results.

Fiona.Array

A seeded array generation utility, which takes qty (how many items in array) and a callback that is called with seeded which should return the value of each array item.

// input

Fiona(1322672).array(10, Fiona.Number)
// output

[
  821136,
  284283,
  554749,
  753275,
  589712,
  783849,
  799655,
  102148,
  931044,
  659818
]

You can also pass a callback for access to the seeded instance, which can be useful for adding distribution weighting to values

// input

const spreadLow = i => i ** 10
const numberCallback = seeded => seeded.distribution(spreadLow).number()

Fiona(1322672).array(10, numberCallback)
// output

[
  139363,
  3,
  2760,
  58821,
  5086,
  87563,
  106912,
  0,
  489442,
  15640
]

Fiona.Unique

A seeded array generation utility, which generates an array of data by calling Fiona.Array but filters out duplicates.

// input

Fiona(1322672).unique(10, Fiona.Number({ min: 1, max: 5 }))
// output

[13,5,9,12,2,14,10,6,15,3]

The result should be similar to calling Fiona.Array but duplicates are skipped over and the next non-duplicated value is moved up in the output array.

// input

{
  array: Fiona(1322672).array(10, Fiona.Number({ min: 1, max: 15 }),
  unique: Fiona(1322672).unique(10, Fiona.Number({ min: 1, max: 15 }),
}
// output

{"array":[13,5,9,12,9,12,12,2,14,10],"unique":[13,5,9,12,2,14,10,6,15,3]}

When searching for non-duplicated values, there is a danger of searching forever for values that don't exist, in which case an error is thrown when a threshold is reached. The threshold is defined by the `duplicateLimit` property and by default is set to twice the length of the array being generated.

// input

Fiona(1322672).unique(3, Fiona.Bool)
// output

// Error: Too many duplicates
// input

Fiona(1322672).unique(5, Fiona.OneOf([1,2,3,4,5]), { duplicateLimit: 20 })
// output

5,2,3,4,1

When determining if elements are duplicates, for simple values like strings and numbers, it works as expected, but if two objects look the same, but are different instances, then we need to provide a comparator function that receives the left and right sides of the comparrison as arguments and returns true when they are considered a duplicate. In this example, the objects are compared by their id alone ti identify duplicates, even when the value is different.

// input

Fiona(1322672).unique(3, Fiona.OneOf([
    {id:1, value: "a"},
    {id:2, value: "b"},
    {id:1, value: "c"},
    {id:3, value: "d"},
    {id:2, value: "e"},
    {id:4, value: "f"},
    {id:5, value: "g"},
    {id:6, value: "h"},
    {id:4, value: "i"},
    {id:7, value: "j"}
  ]), { comparator: (left, right) => left.id === right.id })
// output

[{"id":4,"value":"i"},{"id":1,"value":"c"},{"id":6,"value":"h"}]

Fiona.Bool

A seeded utility to return true or false. Takes `chance` option to change the probability of true as decimal value between 0 and 1 which defaults to 0.5.

// input

Fiona(1322672).bool()
// output

true
// input

Fiona(1322672).string`The rumour is ${Fiona.Bool}`
// output

"The rumour is false"
// input

Fiona(1322672).array(5, Fiona.Bool({ chance: 0.3 }))
// output

[false,true,false,false,false]

Fiona.Choose

A seeded weighted method to select a specified number of items from a passed array.

// input

Fiona(1322672).choose(2, ['pink', 'powder blue', 'purple'])
// output

["pink","purple"]

Like `Fiona.OneOf`, the current distribution function will influence the choice.

// input

Fiona(1322672).distribution(i => i * i * i).choose(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
// output

[1,4,6]

Fiona.Date

A seeded utility to return a date as a string in format `YYYY-MM-DD`. Range is between `min` and `max` options, which default to 1940 and 2000 and can be overridden with strings parsable by the native `Date()` method. There is also a `long` to output full `Date.prototype.toISOString` format.

// input

Fiona(1322672).date()

Fiona(1322672).date({
  min: '1980',
  max: '2080',
  long: true
})
// output

"1956-01-23"

"2006-10-09T07:06:22.808Z"

Fiona.Img

A seeded utility to return a data uri of an SVG placeholder image, which takes optional arguments for width and height.

// input

Fiona(1322672).img()

Fiona(1322672).img({
  width: 200,
  height: 100
})
// output

data:image/svg+xml;utf8,%0A%20 ... etc ... %20%20%20%3C%2Fsvg%3E%0A%20%20

data:image/svg+xml;utf8,%0A%20 ... etc ... %20%20%20%3C%2Fsvg%3E%0A%20%20

Fiona.Duplicable

A seeded utility to help to produce duplicated data sometimes. By default, the seed will be picked from a pool of 10 possibilities, 10 per cent of the time.

In this example, the pool is 2, and the frequency is 0.6 so the numbers will be 373260 or 153925, 60% of the time, and the other numbers will be pseudo random according to the input seed.

// input

Fiona(1322672).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322673).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322674).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322675).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322676).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322677).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322678).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322679).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322680).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322681).duplicable({ frequency: 0.6, pool: 2 }).number()
Fiona(1322682).duplicable({ frequency: 0.6, pool: 2 }).number()
// output

106459
106459
997089
106459
957465
997089
106459
306540
958154
997089
106459

Fiona.Json

A method to return current data object as json string.

// input

Fiona(1322672).json({
  fullname: Fiona.Fullname,
  age: Fiona.Number({ max: 100 })
})
// output

{
  "fullname": "Sir Harry Paterson-Anderson",
  "age": 5
}

n.b. the Fiona.Json method proxies through to Fiona.Object then formats the output, so all arguments accepted by Fiona.Object are accepted by Fiona.Json

Fiona.Gibberish

A seeded utility to return gibberish text, optionally takes `qty` which is the number of words which defaults to `1`.

// input

Fiona(1322672).gibberish()
// output

"raof"
// input

Fiona(1322672).gibberish({ qty: 20 })
// output

"raof ings wetwingetern fobvieshimider hinghoranage ies ubemaning asapevewet ret aris tafvies wofen alacex causweveocpis ingeropmi wisorkershun ersar verhis wa bestanlase"

By setting syllableMin and syllableMax properties, the word length can be influenced.

// input

Fiona(1322672).gibberish({ qty: 20, syllableMin: 1, syllableMax: 2 })
// output

"ra ded tuntup etern fobvies imi erned horan age ral beman pan ap tup estmau el ingscin hoftat ac ac"
// input

Fiona(1322672).gibberish({ qty: 20, syllableMin: 5, syllableMax: 8 })
// output

"raofedrofmofraplernwasnout himidernedvedhanageernraltain espanageeltupdestmauarisings inpelwofenacersatpocausweveocpis ingeropmiwudorkershunageapas kingisofbimbestanlaseernoppetau bapmaringauskexsingadsageningsishorer ingsupladendisadetenceingganaustel nernversevemelnethelbesoc dermobenceobacgapdageafapmeler mingelernanunnitwanalaliaf estrimtiespadenrafernvenanad atinggitauwiscausriting ernberworelbiesnercofaucisnatmac etlasageaocpadbadlageersopoc lersingsrexuerkalimdaus annextouttuwersenteseseninsing dingstoutvufarditocadesiceled robesthunrubiesmeoutmesersbestence gasinggarwielisenceangevewevenob"
// input

Fiona(1322672).gibberish({ qty: 20, syllableMin: 2, syllableMax: 10 })
// output

"raof ings wetwingeternwas vieshimiderned horanageernral bemaningdasapeve manretenceelhingscin hoftatesalacex causweveocpis ingeropmiwu orkershunageap outking dofbimbest ing ersaren petauvacoffankaus exsingadsagenings red erbingsupladendis al"

Fiona.Lorem

A seeded utility to return lorem ipsum text, optionally takes `qty` which is approximate number of words and defaults to `15`.

// input

Fiona(1322672).lorem()

Fiona(1322672).lorem({ qty: 3 })

Fiona(1322672).lorem({ qty: 50 })
// output

velit pariatur amet consectetur culpa dolore laboris excepteur do adipisicing est in qui laborum sint

velit pariatur amet

velit pariatur amet consectetur culpa dolore laboris excepteur do adipisicing est in qui laborum sint exercitation dolor voluptate reprehenderit officia incididunt ea tempor eiusmod id occaecat sunt ut elit sit aliquip ullamco anim in nulla in non fugiat quis commodo ex magna nostrud eu cillum dolor duis proident ad mollit

Fiona.OneOf

A seeded weighted method to select one item from a passed array.

// input

Fiona(1322672).oneOf(['pink', 'powder blue', 'purple'])
// output

pink

The current distribution function will influence the choice, so for example, elements appearing earlier are more likely to be chosen when a weighting reduces the pseudo random values.

// input

Fiona(1322672).distribution(i => i * i * i).oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
// output

1

Fiona.Paragraph

A seeded utility to return a paragraph of lorem ipsum text.

// input

Fiona(1322672).paragraph()
// output

Pariatur sit amet culpa et ullamco excepteur sed consectetur est in qui laborum sint nostrud velit incididunt in officia tempor ex eiusmod dolor id adipisicing.  Quis in dolor irure voluptate officia magna commodo pariatur esse aliquip sint elit ea mollit et nostrud enim aliqua ut sit excepteur proident ut est.  Sit veniam eu aute et consectetur nulla fugiat ut dolor aliqua tempor ea velit qui laborum adipisicing exercitation esse cupidatat dolore consequat in commodo reprehenderit.

Fiona.Regex

A very general use, seeded utility to generate a string that matches a supplied regular expression. It uses the randexp library to expand expressions, seeded by the instance of Fiona.

// input

Fiona(1322672).regex(/[01]{8} (ro|cy)bo(rg|t)s/)
// output

11001001 cybots

When recursing objects, strings and arrays, any regex that's found will be

// input

Fiona(1322672).object({ army: /[01]{8} (ro|cy)bo(rg|t)s/, luckyNumber: Fiona.Number({ max: 10 }) })
// output

{"army":"10110100 robots","luckyNumber":2}
// input

Fiona(1322672).string`There is an army of ${/[01]{8} (ro|cy)bo(rg|t)s/} on their way!`
// output

There is an army of 10101000 robots on their way!
// input

Fiona(1322672).array(3, /[01]{8} (ro|cy)bo(rg|t)s/)
// output

["10101000 robots","11001110 roborgs","00100101 cyborgs"]

n.b. the regex method is only available on the main Fiona package and is not avaliable on the Fiona core package which focusses on being very light so does not include the external libraries required to expand regular expressions.

Fiona.Sentence

A seeded utility to return a sentence of lorem ipsum text.

// input

Fiona(1322672).sentence()
// output

Velit pariatur amet consectetur culpa dolore laboris excepteur do adipisicing est in qui laborum sint exercitation dolor voluptate reprehenderit officia incididunt ea tempor eiusmod id.

Fiona.Number

A seeded utility to return a number, taking options min and max and precision, which default to 0 and 1,000,000 and 0.

// input

Fiona(1322672).number()
Fiona(1322672).number({ max: 10 })
Fiona(1322672).number({ min: 10, max: 20 })
// output

267715
2
12

If you add a precision, instead of an integer you will get a float rounded to specified precision.

// input

Fiona(1322672).number({ precision: 2 })
Fiona(1322672).number({ precision: -2 })
// output

267715.42
267700

Fiona.Shuffle

A seeded utility to shuffle passed array, without modifying the original input.

// input

Fiona(1322672).shuffle(['my', 'is', 'Fiona', 'name', 'Moon']).join(' ')
// output

is name Moon my Fiona

n.b. this method is actually shorthand for seeded.choose(arr.length, arr)

Fiona.Word

A seeded utility to return a single word from lorem ipsum text.

// input

Fiona(1322672).word()
// output

velit

Fiona.Distribution

A utility to manipulate the result of seeded random nambers, allowing control over the distribution of values. Distribution functions influence Fiona.Random, Fiona.Bool, Fiona.Number, Fiona.OneOf, Fiona.Choice and any other methods that rely on them. The primary use case for this method is to create more realistic data.

The distribution method sets the distribution function on a seeded instance so that future calls to seeded.random are passed through the distribution function.

// input

Fiona(1322672).number()

Fiona(1322672).distribution(i => i ** 3).number()
// output

267715

19187

In most cases the upper and lower limits remain the same, but the distribution of the values in between change as with all the predefined functions, but you can also create custom functions that can be used for any purpose, for example to clamp outputs to min and max values.

// input

const clamp = i => i < 0.5 ? 0.5 : i > 0.7 ? 0.7 : i

Fiona(1322672).distribution(clamp).random()

Fiona(1322672).distribution(clamp).number({ max: 100 })
// output

// value is clamped from 0.5-0.7
0.5
// value is clamped from 50-70
50

Fiona.Random

Seeded version of native Math.random method.

// input

Fiona(1322672).random()
// output

0.2677151566686645

Fiona.Gender

A seeded utility to return male or female evenly distributed.

// input

Fiona(1322672).gender()
// output

male

Fiona.Title

A seeded utility to return a salutation, optionally taking a gender to adhere to.

// input

Fiona(1322672).title() // can be either gender
Fiona(1322672).title({ gender: 'male' }) // always male
// output

Dr
Mr

Fiona.namedata

The data used to generate names and salutations is exposed as Fiona.namedata which can be inspected, and modified. The data is based on Scottish census records and is structured like this sample:

Fiona.namedata = {
  male: {
    firstname: ['Jack', 'James', /* etc... */ 'Hunter', 'Zachary'],
    title: ['Mr', 'Dr', 'Sir', 'Lord']
  },
  female: {
    firstname: ['Fiona', 'Aria', 'Mia', /* etc... */ 'Matilda', 'Lauren'],
    title: ['Miss', 'Mrs', 'Dr', 'Ms', 'Dame']
  },
  lastname: ['Moon', 'Smith', 'Brown', /* etc... */ 'Mitchell', 'Fraser']
}

To change the namedata, you can assign new values to the properties of Fiona.namedata but not the object itself.

// input

Fiona(1322672).fullname()

Object.assign(Fiona.namedata, {
  male: {
    firstname: ['Austin', 'Ambrose', 'Andre', 'Arturo'],
    title: ['Lord', 'Baron', 'Count']
  },
  female: {
    firstname: ['Antonietta', 'Antonina', 'Marian', 'Antonetta'],
    title: ['Madam', 'Madame', 'Maid']
  }
})

Fiona(1322672).fullname()
// output

Dr Cooper Oliver Moon
Baron Andre Ambrose Moon

Fiona.Firstname

A seeded utility to return a single firstname, optionally taking a gender to adhere to.

// input

Fiona(1322672).firstname() // can be either gender
Fiona(1322672).firstname({ gender: 'male' }) // always male
// output

Kyle
Joshua

Fiona.Surname

A seeded utility to return a single surname.

// input

Fiona(1322672).surname()
// output

Campbell

Fiona.Fullname

A seeded utility to return a full name, optionally taking a gender to adhere to. This is useful for producing more realistic name data where people might have multiple first and middle names, and sometimes double barrel lastnames joined with hyphen.

// input

Fiona(1322672).fullname() // can be either gender
Fiona(1322672).fullname({ gender: 'male' }) // always male
// output

Dr Cooper Oliver Moon
Mr Kyle Ross

Fiona.Info

Method that returns info about seeded instance, currently only the initseed property is exposed. The initseed can be used to faithfully reproduce data given the same structure.

// input

Fiona(1322672).info()
// output

{"initseed":1322672,"path":[]}

Fiona.Seed

Method that returns the initseed of the seeded instance.

// input

Fiona(1322672).seed()
// output

1322672

Fiona.Index

Method that returns current index (or object key) within structure of seeded instance.

// input

Fiona(1322672).array(3, seeded => seeded.index())
// output

[0,1,2]
// input

Fiona(1322672).object({
    index1: seeded => seeded.index(),
    index2: seeded => seeded.index(),
    nested: {
        deeply: seeded => seeded.index()
    },
    inArray: [seeded => seeded.index()]
})
// output

{
  "index1": "index1",
  "index2": "index2",
  "nested": {
    "deeply": "deeply"
  },
  "inArray": [
    0
  ]
}
// input

Fiona(1322672).index()
// output

undefined

Fiona.Path

Method that returns current path within structure of seeded instance.

// input

Fiona(1322672).array(3, seeded => seeded.path())
// output

[[0],[1],[2]]
// input

Fiona(1322672).object({
    path1: seeded => seeded.path(),
    path2: seeded => seeded.path(),
    nested: {
        deeply: seeded => seeded.path()
    },
    inArray: [seeded => seeded.path()]
})
// output

{
"path1": [
    "path1"
  ],
  "path2": [
    "path2"
  ],
  "nested": {
    "deeply": [
      "nested",
      "deeply"
    ]
  },
  "inArray": [
    [
      "inArray",
      0
    ]
  ]
}}
// input

Fiona(1322672).path()
// output

[]

Fiona.register

A utility for extending Fiona with custom methods, either as a one off, or for re-usable components.

n.b. see Extending section in Overview

The Fiona.register method accepts one argument which should be a function that takes a seeded instance, and returns either a value, or the seeded instance to allow chaining.

In this example we will create a person extension that generates some data for a person, ensuring the gender is correct for each data item.

const person = (seeded, { gender }) => seeded.object({
  gender: seeded => gender || Fiona.Gender,
  title: ({ data }) => Fiona.Title({ gender: data.gender }),
  firstname: ({ data }) => Fiona.Firstname({ gender: data.gender }),
  lastname: Fiona.Surname
})

Fiona.register(['person', person])

Alternatively, if you are registering a named function, you can jut pass the function and the name of the function will be used in registration

Fiona.register(person)

Multiple functions can be registered in one call by passing multiple arguments, and configured constructor shorthands can be used to define extensions. For example, to register the person, and luckyNumber extensions, you can do something like this.

Fiona.register(person, ['luckyNumber', Fiona.Number({ max: 10 })])

A person method is added to seeded instances

// input

Fiona(1322672).person()
// output

{
  "gender": "male",
  "title": "Sir",
  "firstname": "Matthew",
  "lastname": "Taylor"
}

Arguments are passed through, so in this case specifying the gender

// input

Fiona(1322672).person({ gender: 'female' })
// output

{
  "gender": "female",
  "title": "Dr",
  "firstname": "Eva",
  "lastname": "Taylor"
}

A Fiona.Person constructor is added to use as shorthand

// input

Fiona(1322672).array(3, Fiona.Person)
// output

[
  {
    "gender": "female",
    "title": "Miss",
    "firstname": "Lillie",
    "lastname": "Stewart"
  },
  {
    "gender": "male",
    "title": "Dr",
    "firstname": "Jacob",
    "lastname": "Brown"
  },
  {
    "gender": "female",
    "title": "Miss",
    "firstname": "Esme",
    "lastname": "Stewart"
  }
]

The shorthand constructor can also take arguments by calling it as a function

// input

Fiona(1322672).array(3, Fiona.Person({ gender: 'female' }))
// output

[
  {
    "gender": "female",
    "title": "Miss",
    "firstname": "Lillie",
    "lastname": "Stewart"
  },
  {
    "gender": "female",
    "title": "Dr",
    "firstname": "Charlotte",
    "lastname": "Brown"
  },
  {
    "gender": "female",
    "title": "Miss",
    "firstname": "Esme",
    "lastname": "Stewart"
  }
]

Fiona.Object

A method that recurses a passed data structure to resolve it's values.

// input

Fiona(1322672).object({
  fullname: Fiona.Fullname,
  age: Fiona.Number({ max: 100 }),
  luckyNumber: seeded => seeded.number({ max: 10 })
})
// output

{
  "fullname": "Sir Harry Paterson-Anderson",
  "age": 5,
  "luckyNumber": 2
}

Data from prior values can be accessed on data attribute of seeded value passed to function values.

// input

Fiona(1322672).object({
  luckyNumber: seeded => seeded.number({ max: 10 }),
  unluckyNumber: seeded => 10 - seeded.data
})
// output

{
  "luckyNumber": 2,
  "unluckyNumber": 8
}

Objects can be nested

// input

Fiona(1322672).object({
    name: {
      gender: Fiona.Gender,
      title: seeded => seeded.title({ gender: seeded.data.name.gender }),
      firstname: seeded => seeded.firstname({ gender: seeded.data.name.gender }),
      middlenames: seeded => seeded.array(3, Fiona.Firstname({ gender: seeded.data.name.gender }), ' '),
      lastname: seeded => seeded.surname({ gender: seeded.data.name.gender })
    }
})
// output

{
  "name": {
    "gender": "male",
    "title": "Lord",
    "firstname": "Max",
    "middlenames": "Jamie Josh Kayden",
    "lastname": "Anderson"
  },
  "age": 5
}

Fiona.String

A method to populate stirng literal template with resolved values.

// input

Fiona(1322672).string`Hi ${Fiona.Firstname}, how are you?`
// output

"Hi Mila, how are you?"