Skip to content

Commit effa14d

Browse files
Merge pull request #175 from keep-network/position-tests
Position Tests
2 parents 8739341 + 7e2e028 commit effa14d

1 file changed

Lines changed: 146 additions & 24 deletions

File tree

test/positionTest.js

Lines changed: 146 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,169 @@
11
const { expect } = require("chai")
2-
const utils = require("./utils")
3-
const params = require("./params")
42

53
describe("Position", async () => {
64
let positionInstance
7-
let childPosition
8-
let parentPosition
9-
let fullPosition
5+
const maxPosition = Math.pow(8, 7) // max number of operators
106

117
beforeEach(async () => {
128
const PositionStub = await ethers.getContractFactory("PositionStub")
139
positionInstance = await PositionStub.deploy()
1410
await positionInstance.deployed()
15-
16-
fullPosition = utils
17-
.range(params.levels)
18-
.map((n) => (n + 1) % params.slotCount << (n * params.slotBits))
19-
.reduce(utils.sumReducer)
20-
childPosition = 1
21-
parentPosition = utils
22-
.range(params.levels - 1)
23-
.map((n) => (n + 2) % params.slotCount << (n * params.slotBits))
24-
.reduce(utils.sumReducer)
2511
})
2612

2713
describe("slot", async () => {
28-
it("Returns the last bits", async () => {
29-
const result = await positionInstance.slot(fullPosition)
30-
expect(result).to.be.equal(childPosition)
14+
it("Returns the slot of a node in its parent", async () => {
15+
// Sample Cases
16+
//
17+
// The first position gets the first slot in the first parent, the
18+
// second gets the second slot in the first parent, and so on, until
19+
// the 9th, which gets the first slot in the second parent. Thus, the
20+
// slot is just `position % 8`.
21+
const testData = [
22+
{
23+
position: 196831,
24+
slot: 7,
25+
},
26+
{
27+
position: 238968,
28+
slot: 0,
29+
},
30+
{
31+
position: 31002,
32+
slot: 2,
33+
},
34+
{
35+
position: 1617940,
36+
slot: 4,
37+
},
38+
]
39+
for (let i = 0; i < testData.length; i++) {
40+
const test = testData[i]
41+
const slot = await positionInstance.slot(test.position)
42+
expect(slot).to.equal(
43+
test.slot,
44+
`unexpected result for test index ${i}`,
45+
)
46+
}
47+
48+
// Generative Testing
49+
const numSamples = 100
50+
for (let i = 0; i < numSamples; i++) {
51+
// generate a random position in [0, maxPosition)
52+
const position = Math.floor(Math.random() * maxPosition)
53+
const slot = await positionInstance.slot(position)
54+
const expectation = position % 8
55+
expect(slot).to.equal(
56+
expectation,
57+
`unexpected result for position ${position}`,
58+
)
59+
}
3160
})
3261
})
3362

3463
describe("parent", async () => {
35-
it("Returns the first bits", async () => {
36-
const result = await positionInstance.parent(fullPosition)
37-
expect(result).to.be.equal(parentPosition)
64+
it("Returns the associated parent position for a child position", async () => {
65+
// Sample Cases
66+
//
67+
// The first 8 positions get the first parent, the next 8 positions get
68+
// the second parent, and so on. The formula to find a parent position
69+
// based on a child position is `position / 8`.
70+
71+
const testData = [
72+
{
73+
position: 196831,
74+
parent: 24603,
75+
},
76+
{
77+
position: 238968,
78+
parent: 29871,
79+
},
80+
{
81+
position: 31002,
82+
parent: 3875,
83+
},
84+
{
85+
position: 1617940,
86+
parent: 202242,
87+
},
88+
]
89+
for (let i = 0; i < testData.length; i++) {
90+
const test = testData[i]
91+
const parent = await positionInstance.parent(test.position)
92+
expect(parent).to.equal(
93+
test.parent,
94+
`unexpected result for test index ${i}`,
95+
)
96+
}
97+
98+
// Generative Testing
99+
const numSamples = 100
100+
for (let i = 0; i < numSamples; i++) {
101+
// generate a random position in [0, maxPosition)
102+
const position = Math.floor(Math.random() * maxPosition)
103+
const parent = await positionInstance.parent(position)
104+
const expectation = Math.floor(position / 8)
105+
expect(parent).to.equal(
106+
expectation,
107+
`unexpected result for position ${position}`,
108+
)
109+
}
38110
})
39111
})
40112

41113
describe("child", async () => {
42-
it("Returns the child address", async () => {
43-
const result = await positionInstance.child(parentPosition, childPosition)
44-
expect(result).to.be.equal(fullPosition)
114+
it("Returns the position of the child given the position and slot of the parent", async () => {
115+
// Sample Cases
116+
//
117+
// The first position gets the first slot in the first parent, the
118+
// second gets the second slot in the first parent, and so on, until
119+
// the 9th, which gets the first slot in the second parent. Working
120+
// backwards, that means that if we know the parent's position and
121+
// child's slot, the child's position is `parentPosition * 8 + slot`
122+
const testData = [
123+
{
124+
position: 24603,
125+
slot: 7,
126+
child: 196831,
127+
},
128+
{
129+
position: 29871,
130+
slot: 0,
131+
child: 238968,
132+
},
133+
{
134+
position: 3875,
135+
slot: 2,
136+
child: 31002,
137+
},
138+
{
139+
position: 202242,
140+
slot: 4,
141+
child: 1617940,
142+
},
143+
]
144+
for (let i = 0; i < testData.length; i++) {
145+
const test = testData[i]
146+
const child = await positionInstance.child(test.position, test.slot)
147+
expect(child).to.equal(
148+
test.child,
149+
`unexpected result for test index ${i}`,
150+
)
151+
}
152+
153+
// Generative Testing
154+
const numSamples = 100
155+
const maxParentIndex = Math.pow(8, 6) // the largest possible parent index
156+
for (let i = 0; i < numSamples; i++) {
157+
// generate a random position in [0, maxParentIndex)
158+
const position = Math.floor(Math.random() * maxParentIndex)
159+
const slot = Math.floor(Math.random() * 8) // slots range from 0 to 7
160+
const child = await positionInstance.child(position, slot)
161+
const expectation = position * 8 + slot
162+
expect(child).to.equal(
163+
expectation,
164+
`unexpected result for position ${position}`,
165+
)
166+
}
45167
})
46168
})
47169
})

0 commit comments

Comments
 (0)