github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/map_test.go (about)

     1  package goja
     2  
     3  import (
     4  	"hash/maphash"
     5  	"math"
     6  	"strconv"
     7  	"testing"
     8  )
     9  
    10  func testMapHashVal(v1, v2 Value, expected bool, t *testing.T) {
    11  	var h maphash.Hash
    12  	actual := v1.hash(&h) == v2.hash(&h)
    13  	if actual != expected {
    14  		t.Fatalf("testMapHashVal failed for %v, %v", v1, v2)
    15  	}
    16  }
    17  
    18  func TestMapHash(t *testing.T) {
    19  	testMapHashVal(_NaN, _NaN, true, t)
    20  	testMapHashVal(valueTrue, valueFalse, false, t)
    21  	testMapHashVal(valueTrue, valueTrue, true, t)
    22  	testMapHashVal(intToValue(0), _negativeZero, true, t)
    23  	testMapHashVal(asciiString("Test"), asciiString("Test"), true, t)
    24  	testMapHashVal(newStringValue("Тест"), newStringValue("Тест"), true, t)
    25  	testMapHashVal(floatToValue(1.2345), floatToValue(1.2345), true, t)
    26  	testMapHashVal(SymIterator, SymToStringTag, false, t)
    27  	testMapHashVal(SymIterator, SymIterator, true, t)
    28  
    29  	// The following tests introduce indeterministic behaviour
    30  	//testMapHashVal(asciiString("Test"), asciiString("Test1"), false, t)
    31  	//testMapHashVal(newStringValue("Тест"), asciiString("Test"), false, t)
    32  	//testMapHashVal(newStringValue("Тест"), newStringValue("Тест1"), false, t)
    33  }
    34  
    35  func TestOrderedMap(t *testing.T) {
    36  	m := newOrderedMap(&maphash.Hash{})
    37  	for i := int64(0); i < 50; i++ {
    38  		m.set(intToValue(i), asciiString(strconv.FormatInt(i, 10)))
    39  	}
    40  	if m.size != 50 {
    41  		t.Fatalf("Unexpected size: %d", m.size)
    42  	}
    43  
    44  	for i := int64(0); i < 50; i++ {
    45  		expected := asciiString(strconv.FormatInt(i, 10))
    46  		actual := m.get(intToValue(i))
    47  		if !expected.SameAs(actual) {
    48  			t.Fatalf("Wrong value for %d", i)
    49  		}
    50  	}
    51  
    52  	for i := int64(0); i < 50; i += 2 {
    53  		if !m.remove(intToValue(i)) {
    54  			t.Fatalf("remove(%d) return false", i)
    55  		}
    56  	}
    57  	if m.size != 25 {
    58  		t.Fatalf("Unexpected size: %d", m.size)
    59  	}
    60  
    61  	iter := m.newIter()
    62  	count := 0
    63  	for {
    64  		entry := iter.next()
    65  		if entry == nil {
    66  			break
    67  		}
    68  		m.remove(entry.key)
    69  		count++
    70  	}
    71  
    72  	if count != 25 {
    73  		t.Fatalf("Unexpected iter count: %d", count)
    74  	}
    75  
    76  	if m.size != 0 {
    77  		t.Fatalf("Unexpected size: %d", m.size)
    78  	}
    79  }
    80  
    81  func TestOrderedMapCollision(t *testing.T) {
    82  	m := newOrderedMap(&maphash.Hash{})
    83  	n1 := uint64(123456789)
    84  	n2 := math.Float64frombits(n1)
    85  	n1Key := intToValue(int64(n1))
    86  	n2Key := floatToValue(n2)
    87  	m.set(n1Key, asciiString("n1"))
    88  	m.set(n2Key, asciiString("n2"))
    89  	if m.size == len(m.hashTable) {
    90  		t.Fatal("Expected a collision but there wasn't one")
    91  	}
    92  	if n2Val := m.get(n2Key); !asciiString("n2").SameAs(n2Val) {
    93  		t.Fatalf("unexpected n2Val: %v", n2Val)
    94  	}
    95  	if n1Val := m.get(n1Key); !asciiString("n1").SameAs(n1Val) {
    96  		t.Fatalf("unexpected nVal: %v", n1Val)
    97  	}
    98  
    99  	if !m.remove(n1Key) {
   100  		t.Fatal("removing n1Key returned false")
   101  	}
   102  	if n2Val := m.get(n2Key); !asciiString("n2").SameAs(n2Val) {
   103  		t.Fatalf("2: unexpected n2Val: %v", n2Val)
   104  	}
   105  }
   106  
   107  func TestOrderedMapIter(t *testing.T) {
   108  	m := newOrderedMap(&maphash.Hash{})
   109  	iter := m.newIter()
   110  	ent := iter.next()
   111  	if ent != nil {
   112  		t.Fatal("entry should be nil")
   113  	}
   114  	iter1 := m.newIter()
   115  	m.set(intToValue(1), valueTrue)
   116  	ent = iter.next()
   117  	if ent != nil {
   118  		t.Fatal("2: entry should be nil")
   119  	}
   120  	ent = iter1.next()
   121  	if ent == nil {
   122  		t.Fatal("entry is nil")
   123  	}
   124  	if !intToValue(1).SameAs(ent.key) {
   125  		t.Fatal("unexpected key")
   126  	}
   127  	if !valueTrue.SameAs(ent.value) {
   128  		t.Fatal("unexpected value")
   129  	}
   130  }
   131  
   132  func TestOrderedMapIterVisitAfterReAdd(t *testing.T) {
   133  	m := newOrderedMap(&maphash.Hash{})
   134  	one := intToValue(1)
   135  	two := intToValue(2)
   136  
   137  	m.set(one, valueTrue)
   138  	m.set(two, valueTrue)
   139  	iter := m.newIter()
   140  	entry := iter.next()
   141  	if !one.SameAs(entry.key) {
   142  		t.Fatalf("1: unexpected key: %v", entry.key)
   143  	}
   144  	if !m.remove(one) {
   145  		t.Fatal("remove returned false")
   146  	}
   147  	entry = iter.next()
   148  	if !two.SameAs(entry.key) {
   149  		t.Fatalf("2: unexpected key: %v", entry.key)
   150  	}
   151  	m.set(one, valueTrue)
   152  	entry = iter.next()
   153  	if entry == nil {
   154  		t.Fatal("entry is nil")
   155  	}
   156  	if !one.SameAs(entry.key) {
   157  		t.Fatalf("3: unexpected key: %v", entry.key)
   158  	}
   159  }
   160  
   161  func TestOrderedMapIterAddAfterClear(t *testing.T) {
   162  	m := newOrderedMap(&maphash.Hash{})
   163  	one := intToValue(1)
   164  	m.set(one, valueTrue)
   165  	iter := m.newIter()
   166  	iter.next()
   167  	m.clear()
   168  	m.set(one, valueTrue)
   169  	entry := iter.next()
   170  	if entry == nil {
   171  		t.Fatal("entry is nil")
   172  	}
   173  	if entry.key != one {
   174  		t.Fatalf("unexpected key: %v", entry.key)
   175  	}
   176  	entry = iter.next()
   177  	if entry != nil {
   178  		t.Fatalf("entry is not nil: %v", entry)
   179  	}
   180  }
   181  
   182  func TestOrderedMapIterDeleteCurrent(t *testing.T) {
   183  	m := newOrderedMap(&maphash.Hash{})
   184  	one := intToValue(1)
   185  	two := intToValue(2)
   186  	iter := m.newIter()
   187  	m.set(one, valueTrue)
   188  	m.set(two, valueTrue)
   189  	entry := iter.next()
   190  	if entry.key != one {
   191  		t.Fatalf("unexpected key: %v", entry.key)
   192  	}
   193  	m.remove(one)
   194  	entry = iter.next()
   195  	if entry.key != two {
   196  		t.Fatalf("2: unexpected key: %v", entry.key)
   197  	}
   198  }