Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PrismarineJS
GitHub Repository: PrismarineJS/mineflayer
Path: blob/master/test/externalTests/time.js
9427 views
1
const assert = require('assert')
2
const { once, onceWithCleanup } = require('../../lib/promise_utils')
3
4
module.exports = () => async (bot) => {
5
// Test time properties and ranges
6
const timeProps = {
7
doDaylightCycle: 'boolean',
8
bigTime: 'bigint',
9
time: 'number',
10
timeOfDay: 'number',
11
day: 'number',
12
isDay: 'boolean',
13
moonPhase: 'number',
14
bigAge: 'bigint',
15
age: 'number'
16
}
17
18
// Verify all properties exist and have correct types
19
Object.entries(timeProps).forEach(([prop, type]) => {
20
assert.strictEqual(typeof bot.time[prop], type, `Property ${prop} should be of type ${type}`)
21
})
22
23
// Verify ranges
24
assert(bot.time.timeOfDay >= 0 && bot.time.timeOfDay < 24000, 'timeOfDay should be between 0 and 24000')
25
assert(bot.time.moonPhase >= 0 && bot.time.moonPhase < 8, 'moonPhase should be between 0 and 7')
26
assert(bot.time.day >= 0, 'day should be non-negative')
27
assert(bot.time.age >= 0, 'age should be non-negative')
28
assert(bot.time.bigAge >= 0n, 'bigAge should be non-negative')
29
30
// Helper functions
31
const isTimeClose = (current, target) => Math.abs(current - target) < 510
32
const isTimeInRange = (current, start, end) => start <= end ? current >= start && current <= end : current >= start || current <= end
33
const waitForTime = async (expectedTime) => {
34
// Wait for a time event that matches our expectation (if provided)
35
// This helps avoid race conditions where we catch an old time update
36
if (expectedTime !== undefined) {
37
await onceWithCleanup(bot, 'time', {
38
timeout: 5000,
39
checkCondition: () => isTimeClose(bot.time.timeOfDay, expectedTime)
40
})
41
} else {
42
await once(bot, 'time')
43
}
44
}
45
46
// Helper to set gamerule using the correct name for the version
47
const setDaylightCycle = (value) => {
48
if (bot.supportFeature('gameRuleUsesResourceLocation')) {
49
bot.test.sayEverywhere(`/gamerule minecraft:advance_time ${value}`)
50
} else {
51
bot.test.sayEverywhere(`/gamerule doDaylightCycle ${value}`)
52
}
53
}
54
55
// Disable daylight cycle before time transition tests to prevent
56
// time from drifting between /time set and the assertion
57
const originalDaylightCycle = bot.time.doDaylightCycle
58
setDaylightCycle(false)
59
await waitForTime()
60
61
// Test time transitions
62
const timeTests = [
63
{ time: 18000, name: 'midnight', isDay: false },
64
{ time: 6000, name: 'noon', isDay: true },
65
{ time: 12000, name: 'sunset', isDay: true },
66
{ time: 0, name: 'sunrise', isDay: true }
67
]
68
69
for (const test of timeTests) {
70
bot.test.sayEverywhere(`/time set ${test.time}`)
71
await waitForTime(test.time)
72
assert(isTimeClose(bot.time.timeOfDay, test.time), `Expected time to be close to ${test.time}, got ${bot.time.timeOfDay}`)
73
assert.strictEqual(bot.time.isDay, test.isDay, `${test.name} should be ${test.isDay ? 'day' : 'night'}`)
74
}
75
76
// Re-enable daylight cycle for progression test
77
setDaylightCycle(true)
78
await waitForTime()
79
80
// Test day and moon phase progression
81
const currentDay = bot.time.day
82
const currentPhase = bot.time.moonPhase
83
bot.test.sayEverywhere('/time add 24000')
84
await waitForTime()
85
assert(bot.time.day >= currentDay + 1, `Expected day to be at least ${currentDay + 1}, got ${bot.time.day}`)
86
assert.notStrictEqual(bot.time.moonPhase, currentPhase, 'Moon phase should change after a full day')
87
88
// Test daylight cycle toggle
89
setDaylightCycle(false)
90
await waitForTime()
91
assert.strictEqual(bot.time.doDaylightCycle, false)
92
93
setDaylightCycle(originalDaylightCycle)
94
await waitForTime()
95
assert.strictEqual(bot.time.doDaylightCycle, originalDaylightCycle)
96
97
// Disable daylight cycle again for day/night range tests
98
setDaylightCycle(false)
99
await waitForTime()
100
101
// Test day/night transitions
102
const dayNightTests = [
103
{ command: 'day', range: [0, 12000], isDay: true },
104
{ command: 'night', range: [12000, 24000], isDay: false }
105
]
106
107
for (const test of dayNightTests) {
108
bot.test.sayEverywhere(`/time set ${test.command}`)
109
await waitForTime()
110
assert(isTimeInRange(bot.time.timeOfDay, test.range[0], test.range[1]), `Time should be in ${test.command} range`)
111
assert.strictEqual(bot.time.isDay, test.isDay, `${test.command} should be ${test.isDay ? 'day' : 'night'}`)
112
}
113
114
// Restore original daylight cycle setting
115
setDaylightCycle(originalDaylightCycle)
116
await waitForTime()
117
}
118
119