| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- package gonanoid
- import (
- "math"
- "strings"
- "testing"
- )
- var urlLength = len(defaults.Alphabet)
- // Test that nanoid generates URL friendly IDs
- // it ('generates URL-friendly IDs')
- func TestGeneratesURLFriendlyIDs(t *testing.T) {
- for i := 0; i < 10; i++ {
- id, err := Nanoid()
- if err != nil {
- t.Errorf("Nanoid error: %v", err)
- }
- if len(id) != defaults.Size {
- t.Errorf(
- "TestGeneratesURLFriendlyIDs error: length of id %v should be %v, got %v",
- id,
- defaults.Size,
- id,
- )
- }
- runeID := []rune(id)
- for j := 0; j < len(runeID); j++ {
- res := strings.Contains(defaults.Alphabet, string(runeID[j]))
- if !res {
- t.Errorf(
- "GeneratesURLFriendlyIds error: char %v should be contained in %v",
- string(runeID[j]),
- defaults.Alphabet,
- )
- }
- }
- }
- }
- // Test that nanoid has no collisions
- // it ('has no collisions')
- func TestHasNoCollisions(t *testing.T) {
- COUNT := 100 * 1000
- used := make(map[string]bool)
- for i := 0; i < COUNT; i++ {
- id, err := Nanoid()
- if err != nil {
- t.Errorf("Nanoid error: %v", err)
- }
- if used[id] {
- t.Errorf("Collision error! Id %v found for test arr %v", id, used)
- }
- used[id] = true
- }
- }
- // Test that Nanoid has flat distribution
- // it ('has flat distribution')
- func TestFlatDistribution(t *testing.T) {
- COUNT := 100 * 1000
- instance, err := Nanoid()
- if err != nil {
- t.Errorf("Nanoid error: %v", err)
- }
- LENGTH := len(instance)
- chars := make(map[byte]int)
- for i := 0; i < COUNT; i++ {
- id, _ := Nanoid()
- for j := 0; j < LENGTH; j++ {
- // https://github.com/ai/nanoid/blob/d6ad3412147fa4c2b0d404841ade245a00c2009f/test/index.test.js#L33
- // if (!chars[char]) chars[char] = 0 is useless since it
- // is initialized by default to 0 from Golang
- chars[id[j]]++
- }
- }
- for char, k := range chars {
- distribution := float64(k) * float64(urlLength) / float64(COUNT*LENGTH)
- if !toBeCloseTo(distribution, 1, 1) {
- t.Errorf("Distribution error! Distribution %v found for char %v", distribution, char)
- }
- }
- }
- // utility that replicates jest.toBeCloseTo
- func toBeCloseTo(value, actual, expected float64) bool {
- precision := 2
- // https://github.com/facebook/jest/blob/a397abaf9f08e691f8739899819fc4da41c1e476/packages/expect/src/matchers.js#L83
- pass := math.Abs(expected-actual) < math.Pow10(-precision)/2
- return pass
- }
- // Benchmark nanoid generator
- func BenchmarkNanoid(b *testing.B) {
- for n := 0; n < b.N; n++ {
- Nanoid()
- }
- }
|