Skip to content

Commit 52938fe

Browse files
authored
Add new external test for time. (#3650)
* Add new external test for time. Added by iterating with cursor. 1. Asking what is missing from mineflayer in term of testing 2. Selecting time from his proposal 3. Reviewing the time test it wrote 4. Asking to run the test for version 1.21.4 5. Asking him to fix failures 6. Asking to run on all version to double check 7. Sending this PR * fix lint * increase tolerance * fix * refactor * faster
1 parent cab65b1 commit 52938fe

6 files changed

Lines changed: 99 additions & 18 deletions

File tree

docs/api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ Day of the world.
10891089

10901090
Whether it is day or not.
10911091

1092-
Based on whether the current time of day is between 13000 and 23000 ticks.
1092+
Based on whether the current time of day is between 0 and 13000 ticks (day + sunset).
10931093

10941094
#### bot.time.moonPhase
10951095

docs/br/api_br.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ Dia do mundo.
941941

942942
Se é dia ou não.
943943

944-
Baseado no horário atual estar entre 13.000 e 23.000 ticks.
944+
Baseado no horário atual estar entre 0 e 13000 ticks (dia + pôr do sol).
945945

946946
#### bot.time.moonPhase
947947

docs/es/api_es.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -943,9 +943,9 @@ Día del mundo
943943

944944
#### bot.time.isDay
945945

946-
Si es de día o no
946+
Si es de día o no.
947947

948-
Basado en si la hora actual está entre los 13000 y 23000 ticks.
948+
Basado en si la hora actual está entre 0 y 13000 ticks (día + atardecer).
949949

950950
#### bot.time.moonPhase
951951

docs/ru/api_ru.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ UUID существа, который определяется боссом.
11211121

11221122
Определяет, сейчас день (`true`) или ночь (`false`).
11231123

1124-
Основано на времени между `13000` и `23000` тиками.
1124+
Основано на времени между `0` и `13000` тиками (день + закат).
11251125

11261126
#### bot.time.moonPhase
11271127

lib/plugins/time.js

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,21 @@ function inject (bot) {
1313
age: null
1414
}
1515
bot._client.on('update_time', (packet) => {
16-
let time = longToBigInt(packet.time)
16+
const time = longToBigInt(packet.time)
17+
const age = longToBigInt(packet.age)
18+
const doDaylightCycle = packet.tickDayTime !== undefined ? !!packet.tickDayTime : time >= 0n
19+
// When doDaylightCycle is false, we need to take the absolute value of time
20+
const finalTime = doDaylightCycle ? time : (time < 0n ? -time : time)
1721

18-
if (time < 0) {
19-
bot.time.doDaylightCycle = false
20-
time *= -1n
21-
} else {
22-
bot.time.doDaylightCycle = true
23-
}
24-
25-
bot.time.bigTime = time
26-
bot.time.time = Number(time)
22+
bot.time.doDaylightCycle = doDaylightCycle
23+
bot.time.bigTime = finalTime
24+
bot.time.time = Number(finalTime)
2725
bot.time.timeOfDay = bot.time.time % 24000
2826
bot.time.day = Math.floor(bot.time.time / 24000)
29-
bot.time.isDay = bot.time.timeOfDay < 13000 || bot.time.timeOfDay >= 23000
27+
bot.time.isDay = bot.time.timeOfDay >= 0 && bot.time.timeOfDay < 13000
3028
bot.time.moonPhase = bot.time.day % 8
31-
bot.time.bigAge = longToBigInt(packet.age)
32-
bot.time.age = Number(bot.time.bigAge)
29+
bot.time.bigAge = age
30+
bot.time.age = Number(age)
3331

3432
bot.emit('time')
3533
})

test/externalTests/time.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
const assert = require('assert')
2+
const { once } = 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 () => {
34+
await once(bot, 'time')
35+
await bot.test.wait(200)
36+
}
37+
38+
// Test time transitions
39+
const timeTests = [
40+
{ time: 18000, name: 'midnight', isDay: false },
41+
{ time: 6000, name: 'noon', isDay: true },
42+
{ time: 12000, name: 'sunset', isDay: true },
43+
{ time: 0, name: 'sunrise', isDay: true }
44+
]
45+
46+
for (const test of timeTests) {
47+
bot.test.sayEverywhere(`/time set ${test.time}`)
48+
await waitForTime()
49+
assert(isTimeClose(bot.time.timeOfDay, test.time), `Expected time to be close to ${test.time}, got ${bot.time.timeOfDay}`)
50+
assert.strictEqual(bot.time.isDay, test.isDay, `${test.name} should be ${test.isDay ? 'day' : 'night'}`)
51+
}
52+
53+
// Test day and moon phase progression
54+
const currentDay = bot.time.day
55+
const currentPhase = bot.time.moonPhase
56+
bot.test.sayEverywhere('/time add 24000')
57+
await waitForTime()
58+
assert(bot.time.day >= currentDay + 1, `Expected day to be at least ${currentDay + 1}, got ${bot.time.day}`)
59+
assert.notStrictEqual(bot.time.moonPhase, currentPhase, 'Moon phase should change after a full day')
60+
61+
// Test daylight cycle
62+
const originalDaylightCycle = bot.time.doDaylightCycle
63+
bot.test.sayEverywhere('/gamerule doDaylightCycle false')
64+
await waitForTime()
65+
assert.strictEqual(bot.time.doDaylightCycle, false)
66+
67+
bot.test.sayEverywhere(`/gamerule doDaylightCycle ${originalDaylightCycle}`)
68+
await waitForTime()
69+
assert.strictEqual(bot.time.doDaylightCycle, originalDaylightCycle)
70+
71+
// Test day/night transitions
72+
const dayNightTests = [
73+
{ command: 'day', range: [0, 12000], isDay: true },
74+
{ command: 'night', range: [12000, 24000], isDay: false }
75+
]
76+
77+
for (const test of dayNightTests) {
78+
bot.test.sayEverywhere(`/time set ${test.command}`)
79+
await waitForTime()
80+
assert(isTimeInRange(bot.time.timeOfDay, test.range[0], test.range[1]), `Time should be in ${test.command} range`)
81+
assert.strictEqual(bot.time.isDay, test.isDay, `${test.command} should be ${test.isDay ? 'day' : 'night'}`)
82+
}
83+
}

0 commit comments

Comments
 (0)