split-relay.test.js
2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { describe, expect, it } from 'vitest'
import { splitRelayPayout } from '../src/split-relay.js'
const hold = (agent_id, end_reason, has_valid_checkpoint) => ({ agent_id, end_reason, has_valid_checkpoint })
describe('SM-02 splitRelayPayout', () => {
it('1 人:全额归提交者', () => {
expect(splitRelayPayout(100, [hold('b', 'submitted', true)], 'b')).toEqual([{ agent_id: 'b', amount: 100, kind: 'winner' }])
})
it('2 人平分', () => {
expect(splitRelayPayout(100, [hold('a', 'released', true), hold('b', 'submitted', false)], 'b')).toEqual([
{ agent_id: 'b', amount: 50, kind: 'winner' },
{ agent_id: 'a', amount: 50, kind: 'relay_share' },
])
})
it('3 人除不尽:余数归最终提交者', () => {
const payouts = splitRelayPayout(100, [hold('a', 'timeout', true), hold('c', 'transferred', true), hold('b', 'submitted', true)], 'b')
expect(payouts).toEqual([
{ agent_id: 'b', amount: 34, kind: 'winner' },
{ agent_id: 'a', amount: 33, kind: 'relay_share' },
{ agent_id: 'c', amount: 33, kind: 'relay_share' },
])
})
it('同一 Agent 多次持有只算一份;没留有效检查点的前任不参与', () => {
const holds = [hold('a', 'released', true), hold('a', 'timeout', true), hold('d', 'released', false), hold('b', 'released', true), hold('b', 'submitted', true)]
expect(splitRelayPayout(90, holds, 'b')).toEqual([
{ agent_id: 'b', amount: 45, kind: 'winner' },
{ agent_id: 'a', amount: 45, kind: 'relay_share' },
])
})
it('各笔之和恒等于 reward(含赏金小于人数)', () => {
const holds = [hold('a', 'released', true), hold('c', 'released', true), hold('b', 'submitted', true)]
for (const reward of [1, 2, 3, 4, 7, 100, 101]) {
const payouts = splitRelayPayout(reward, holds, 'b')
expect(payouts.reduce((sum, p) => sum + p.amount, 0)).toBe(reward)
expect(payouts.every((p) => p.amount > 0)).toBe(true)
}
expect(splitRelayPayout(2, holds, 'b')).toEqual([{ agent_id: 'b', amount: 2, kind: 'winner' }])
})
it('提交后又放弃的前任也参与平分', () => {
expect(splitRelayPayout(100, [hold('a', 'submitted', true), hold('b', 'submitted', true)], 'b')).toEqual([
{ agent_id: 'b', amount: 50, kind: 'winner' },
{ agent_id: 'a', amount: 50, kind: 'relay_share' },
])
})
it('全部结束原因都被处理;未知原因直接 throw', () => {
for (const reason of ['submitted', 'released', 'timeout', 'transferred', null]) expect(() => splitRelayPayout(10, [hold('a', reason, true)], 'b')).not.toThrow()
expect(() => splitRelayPayout(10, [hold('a', 'vanished', true)], 'b')).toThrow(/Unhandled end_reason: vanished/)
})
})