mirror of
https://github.com/lune-org/lune.git
synced 2025-05-04 10:43:57 +01:00
chore(tests): updated test suite
This commit is contained in:
parent
72f136f1d3
commit
eb642473e3
15 changed files with 250 additions and 165 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -310,9 +310,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.26"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
|
||||
checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
|
@ -320,7 +320,7 @@ dependencies = [
|
|||
"num-traits",
|
||||
"time 0.1.45",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::lune::builtins::datetime::date_time::Timezone;
|
|||
use chrono::prelude::*;
|
||||
use chrono_locale::LocaleDate;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct DateTimeBuilder {
|
||||
/// The year. In the range 1400 - 9999.
|
||||
pub year: i32,
|
||||
|
@ -98,7 +98,7 @@ impl DateTimeBuilder {
|
|||
{
|
||||
let format = match format {
|
||||
Some(fmt) => fmt.to_string(),
|
||||
None => "%Y-%m-%dT%H:%M:%SZ".to_string(),
|
||||
None => "%Y-%m-%dT%H:%M:%SZUTC+%z".to_string(),
|
||||
};
|
||||
|
||||
let locale = match locale {
|
||||
|
@ -106,34 +106,69 @@ impl DateTimeBuilder {
|
|||
None => "en".to_string(),
|
||||
};
|
||||
|
||||
let time = Utc
|
||||
.with_ymd_and_hms(
|
||||
self.year,
|
||||
self.month,
|
||||
self.day,
|
||||
self.hour,
|
||||
self.minute,
|
||||
self.second,
|
||||
)
|
||||
.single()
|
||||
.ok_or(())?;
|
||||
|
||||
// dbg!(
|
||||
// "{}",
|
||||
// match timezone {
|
||||
// Timezone::Utc => time.to_rfc3339(), //.formatl((format).as_str(), locale.as_str()),
|
||||
// Timezone::Local => time.with_timezone(&Local).to_rfc3339(), // .formatl((format).as_str(), locale.as_str()),
|
||||
// }
|
||||
// );
|
||||
|
||||
Ok(match timezone {
|
||||
Timezone::Utc => Utc
|
||||
.with_ymd_and_hms(
|
||||
self.year,
|
||||
self.month,
|
||||
self.day,
|
||||
self.hour,
|
||||
self.minute,
|
||||
self.second,
|
||||
)
|
||||
.single()
|
||||
.ok_or(())?
|
||||
.formatl((format).as_str(), locale.as_str())
|
||||
.to_string(),
|
||||
Timezone::Local => Local
|
||||
.with_ymd_and_hms(
|
||||
self.year,
|
||||
self.month,
|
||||
self.day,
|
||||
self.hour,
|
||||
self.minute,
|
||||
self.second,
|
||||
)
|
||||
.single()
|
||||
.ok_or(())?
|
||||
.formatl((format).as_str(), locale.as_str())
|
||||
.to_string(),
|
||||
})
|
||||
Timezone::Utc => time.formatl((format).as_str(), locale.as_str()),
|
||||
Timezone::Local => time
|
||||
.with_timezone(&Local)
|
||||
.formatl((format).as_str(), locale.as_str()),
|
||||
}
|
||||
.to_string())
|
||||
|
||||
// .formatl((format).as_str(), locale.as_str())
|
||||
// .to_string())
|
||||
|
||||
// Ok(match timezone {
|
||||
// Timezone::Utc => Utc
|
||||
// .with_ymd_and_hms(
|
||||
// self.year,
|
||||
// self.month,
|
||||
// self.day,
|
||||
// self.hour,
|
||||
// self.minute,
|
||||
// self.second,
|
||||
// )
|
||||
// .single()
|
||||
// .ok_or(())?
|
||||
// .with_timezone(&match timezone {
|
||||
// Timezone::Utc => Utc,
|
||||
// Timezone::Local => Local
|
||||
// })
|
||||
// .formatl((format).as_str(), locale.as_str())
|
||||
// .to_string(),
|
||||
// Timezone::Local => Local
|
||||
// .with_ymd_and_hms(
|
||||
// self.year,
|
||||
// self.month,
|
||||
// self.day,
|
||||
// self.hour,
|
||||
// self.minute,
|
||||
// self.second,
|
||||
// )
|
||||
// .single()
|
||||
// .ok_or(())?
|
||||
// .formatl((format).as_str(), locale.as_str())
|
||||
// .to_string(),
|
||||
// })
|
||||
}
|
||||
|
||||
pub fn build(self) -> Self {
|
||||
|
|
|
@ -9,6 +9,7 @@ pub enum TimestampType {
|
|||
}
|
||||
|
||||
/// General timezone types accepted by `DateTime` methods.
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub enum Timezone {
|
||||
Utc,
|
||||
Local,
|
||||
|
@ -67,30 +68,28 @@ impl DateTime {
|
|||
/// - Non-integer values are rounded down. For example, providing 2.5 hours will be equivalent to providing 2 hours, not 2 hours 30 minutes.
|
||||
/// - Omitted values are assumed to be their lowest value in their normal range, except for year which defaults to 1970.
|
||||
pub fn from_universal_time(date_time: Option<DateTimeBuilder>) -> Result<Self, ()> {
|
||||
if let Some(date_time) = date_time {
|
||||
let utc_time: ChronoDateTime<Utc> = Utc.from_utc_datetime(&NaiveDateTime::new(
|
||||
NaiveDate::from_ymd_opt(date_time.year, date_time.month, date_time.day).ok_or(())?,
|
||||
NaiveTime::from_hms_milli_opt(
|
||||
date_time.hour,
|
||||
date_time.minute,
|
||||
date_time.second,
|
||||
date_time.millisecond,
|
||||
)
|
||||
.ok_or(())?,
|
||||
));
|
||||
Ok(match date_time {
|
||||
Some(date_time) => {
|
||||
let utc_time: ChronoDateTime<Utc> = Utc.from_utc_datetime(&NaiveDateTime::new(
|
||||
NaiveDate::from_ymd_opt(date_time.year, date_time.month, date_time.day)
|
||||
.ok_or(())?,
|
||||
NaiveTime::from_hms_milli_opt(
|
||||
date_time.hour,
|
||||
date_time.minute,
|
||||
date_time.second,
|
||||
date_time.millisecond,
|
||||
)
|
||||
.ok_or(())?,
|
||||
));
|
||||
|
||||
Ok(Self {
|
||||
unix_timestamp: utc_time.timestamp(),
|
||||
unix_timestamp_millis: utc_time.timestamp_millis(),
|
||||
})
|
||||
} else {
|
||||
let utc_time = Utc::now();
|
||||
Self {
|
||||
unix_timestamp: utc_time.timestamp(),
|
||||
unix_timestamp_millis: utc_time.timestamp_millis(),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
unix_timestamp: utc_time.timestamp(),
|
||||
unix_timestamp_millis: utc_time.timestamp_millis(),
|
||||
})
|
||||
}
|
||||
None => Self::now(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a new `DateTime` using the given units from a local time. The
|
||||
|
@ -102,34 +101,38 @@ impl DateTime {
|
|||
/// - Non-integer values are rounded down. For example, providing 2.5 hours will be equivalent to providing 2 hours, not 2 hours 30 minutes.
|
||||
/// - Omitted values are assumed to be their lowest value in their normal range, except for year which defaults to 1970.
|
||||
pub fn from_local_time(date_time: Option<DateTimeBuilder>) -> Result<Self, ()> {
|
||||
if let Some(date_time) = date_time {
|
||||
let local_time: ChronoDateTime<Local> = Local
|
||||
.from_local_datetime(&NaiveDateTime::new(
|
||||
NaiveDate::from_ymd_opt(date_time.year, date_time.month, date_time.day)
|
||||
Ok(match date_time {
|
||||
Some(date_time) => {
|
||||
let local_time: ChronoDateTime<Local> = Local
|
||||
.from_local_datetime(&NaiveDateTime::new(
|
||||
NaiveDate::from_ymd_opt(date_time.year, date_time.month, date_time.day)
|
||||
.ok_or(())?,
|
||||
NaiveTime::from_hms_milli_opt(
|
||||
date_time.hour,
|
||||
date_time.minute,
|
||||
date_time.second,
|
||||
date_time.millisecond,
|
||||
)
|
||||
.ok_or(())?,
|
||||
NaiveTime::from_hms_milli_opt(
|
||||
date_time.hour,
|
||||
date_time.minute,
|
||||
date_time.second,
|
||||
date_time.millisecond,
|
||||
)
|
||||
.ok_or(())?,
|
||||
))
|
||||
.single()
|
||||
.ok_or(())?;
|
||||
))
|
||||
.single()
|
||||
.ok_or(())?;
|
||||
|
||||
Ok(Self {
|
||||
unix_timestamp: local_time.timestamp(),
|
||||
unix_timestamp_millis: local_time.timestamp_millis(),
|
||||
})
|
||||
} else {
|
||||
let local_time = Local::now();
|
||||
Self {
|
||||
unix_timestamp: local_time.timestamp(),
|
||||
unix_timestamp_millis: local_time.timestamp_millis(),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
unix_timestamp: local_time.timestamp(),
|
||||
unix_timestamp_millis: local_time.timestamp_millis(),
|
||||
})
|
||||
}
|
||||
None => {
|
||||
let local_time = Local::now();
|
||||
|
||||
Self {
|
||||
unix_timestamp: local_time.timestamp(),
|
||||
unix_timestamp_millis: local_time.timestamp_millis(),
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a `DateTime` from an ISO 8601 date-time string in UTC
|
||||
|
@ -168,6 +171,7 @@ impl DateTime {
|
|||
// Any less tedious way to get Enum member based on index?
|
||||
// I know there's some crates available with derive macros for this,
|
||||
// would it be okay if used some of them?
|
||||
|
||||
date_time_constructor
|
||||
.with_year(date_time.year())
|
||||
.with_month(match date_time.month() {
|
||||
|
@ -199,12 +203,12 @@ impl DateTime {
|
|||
/// description. The values within this table could be passed to `from_local_time`
|
||||
/// to produce the original `DateTime` object.
|
||||
pub fn to_local_time(&self) -> Result<DateTimeBuilder, ()> {
|
||||
Ok(Self::to_datetime_builder(
|
||||
Self::to_datetime_builder(
|
||||
Local
|
||||
.timestamp_opt(self.unix_timestamp, 0)
|
||||
.single()
|
||||
.ok_or(())?,
|
||||
)?)
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts the value of this `DateTime` object to Universal Coordinated Time (UTC).
|
||||
|
@ -213,11 +217,15 @@ impl DateTime {
|
|||
/// in this data type's description. The values within this table could be passed
|
||||
/// to `from_universal_time` to produce the original `DateTime` object.
|
||||
pub fn to_universal_time(&self) -> Result<DateTimeBuilder, ()> {
|
||||
Ok(Self::to_datetime_builder(
|
||||
Self::to_datetime_builder(
|
||||
Utc.timestamp_opt(self.unix_timestamp, 0)
|
||||
.single()
|
||||
.ok_or(())?,
|
||||
)?)
|
||||
)
|
||||
|
||||
// dbg!("{:#?}", m?);
|
||||
|
||||
// m
|
||||
}
|
||||
|
||||
/// Formats a date as a ISO 8601 date-time string, returns None if the DateTime object is invalid.
|
||||
|
|
16
src/tests.rs
16
src/tests.rs
|
@ -108,14 +108,14 @@ create_tests! {
|
|||
task_wait: "task/wait",
|
||||
|
||||
datetime_now: "datetime/now",
|
||||
datetime_fromunixtimestamp: "datetime/fromunixtimestamp",
|
||||
datetime_fromuniversaltime: "datetime/fromuniversaltime",
|
||||
datetime_touniversaltime: "datetime/touniversaltime",
|
||||
datetime_fromlocaltime: "datetime/fromlocaltime",
|
||||
datetime_tolocaltime: "datetime/tolocaltime",
|
||||
datetime_fromisodate: "datetime/fromisodate",
|
||||
datetime_toisodate: "datetime/toisodate",
|
||||
datetime_formattime: "datetime/formattime",
|
||||
datetime_from_unix_timestamp: "datetime/fromUnixTimestamp",
|
||||
datetime_from_universal_time: "datetime/fromUniversalTime",
|
||||
datetime_to_universal_time: "datetime/toUniversalTime",
|
||||
datetime_from_local_time: "datetime/fromLocalTime",
|
||||
datetime_to_local_time: "datetime/toLocalTime",
|
||||
datetime_from_iso_date: "datetime/fromIsoDate",
|
||||
datetime_to_iso_date: "datetime/toIsoDate",
|
||||
datetime_format_time: "datetime/formatTime",
|
||||
}
|
||||
|
||||
#[cfg(feature = "roblox")]
|
||||
|
|
41
tests/datetime/formatTime.luau
Normal file
41
tests/datetime/formatTime.luau
Normal file
|
@ -0,0 +1,41 @@
|
|||
local DateTime = require("@lune/datetime")
|
||||
|
||||
-- UTC Timezone
|
||||
assert(
|
||||
DateTime.fromUnixTimestamp(1693068988):formatTime("utc", "%Y-%m-%dT%H:%M:%SZ", "en")
|
||||
== "2023-08-26T16:56:28Z",
|
||||
"invalid ISO 8601 formatting for DateTime.formatTime() (UTC)"
|
||||
)
|
||||
|
||||
assert(
|
||||
DateTime.fromUnixTimestamp(1693068988):formatTime("utc", "%A, %d %B %Y", "fr")
|
||||
== "samedi, 26 août 2023",
|
||||
"expected format specifier '%A, %d %B %Y' to return 'samedi, 26 août 2023' for locale 'fr'"
|
||||
)
|
||||
|
||||
-- FIXME: Local timezone formatTime fails due to a rust side bug
|
||||
|
||||
local expectedTimeString = os.date("%Y-%m-%dT%H:%M:%SZ%z", 1693932753)
|
||||
|
||||
-- NOTE: UTC Timezone conversions work perfectly fine, issue only for local.
|
||||
-- So far I've made it so that format_time always converts to_universal_time
|
||||
-- Builder object. Then in to_string, we construct a ChronoDateTime from the values
|
||||
-- and convert it to the requested timezone. We then format this with our formatter
|
||||
-- string.
|
||||
|
||||
-- For debugging, try checking what to_universal_time returns, maybe that's where
|
||||
-- an incorrect DateTimeBuilder is getting returned... If that's the case, that means
|
||||
-- there probably isn't any issue with to_string at all.
|
||||
|
||||
-- Yes, an invalid DateTimeBuilder is being returned turns out. Still don't know why actually.
|
||||
|
||||
print(
|
||||
expectedTimeString,
|
||||
DateTime.fromUnixTimestamp(1693068988):formatTime("local", "%Y-%m-%dT%H:%M:%SZ", "en")
|
||||
)
|
||||
|
||||
assert(
|
||||
DateTime.fromUnixTimestamp(1693068988):formatTime("local", "%Y-%m-%dT%H:%M:%SZ", "en")
|
||||
== expectedTimeString,
|
||||
"invalid ISO 8601 formatting for DateTime.formatTime() (local)"
|
||||
)
|
|
@ -1,16 +0,0 @@
|
|||
local DateTime = require("@lune/datetime")
|
||||
|
||||
-- UTC Timezone
|
||||
assert(
|
||||
DateTime.fromUnixTimestamp(1693068988):formatTime("utc", "%Y-%m-%dT%H:%M:%SZ", "en")
|
||||
== "2023-08-26T16:56:28Z",
|
||||
"invalid ISO 8601 formatting for DateTime.formatTime()"
|
||||
)
|
||||
|
||||
assert(
|
||||
DateTime.fromUnixTimestamp(1693068988):formatTime("utc", "%A, %d %B %Y", "fr")
|
||||
== "samedi, 26 août 2023",
|
||||
"expected format specifier '%A, %d %B %Y' to return 'samedi, 26 août 2023' for locale 'fr'"
|
||||
)
|
||||
|
||||
-- TODO: local timezone tests
|
|
@ -1,7 +1,5 @@
|
|||
local DateTime = require("@lune/datetime")
|
||||
|
||||
-- Fails due to issue with rust side implementation
|
||||
|
||||
assert(
|
||||
DateTime.fromIsoDate("2023-08-26T16:56:28Z") ~= nil,
|
||||
"expected DateTime.fromIsoDate() to return DateTime, got nil"
|
45
tests/datetime/fromLocalTime.luau
Normal file
45
tests/datetime/fromLocalTime.luau
Normal file
|
@ -0,0 +1,45 @@
|
|||
local DateTime = require("@lune/datetime")
|
||||
assert(
|
||||
DateTime.fromLocalTime()["unixTimestamp"] == os.time(),
|
||||
"expected DateTime.fromLocalTime() with no args to return DateTime at current moment"
|
||||
)
|
||||
|
||||
local timeValues1 = os.date("*t", 1693049188)
|
||||
|
||||
assert(
|
||||
DateTime.fromLocalTime({
|
||||
["year"] = timeValues1.year,
|
||||
["month"] = timeValues1.month,
|
||||
["day"] = timeValues1.day,
|
||||
["hour"] = timeValues1.hour,
|
||||
["minute"] = timeValues1.min,
|
||||
["second"] = timeValues1.sec,
|
||||
["millisecond"] = 0,
|
||||
})["unixTimestamp"] == 1693049188,
|
||||
"expected DateTime.fromLocalTime() with DateTimeValues arg to return 1693049188s"
|
||||
)
|
||||
|
||||
print(DateTime.fromLocalTime({
|
||||
["year"] = 2023,
|
||||
["month"] = "aug",
|
||||
["day"] = 26,
|
||||
["hour"] = 16,
|
||||
["minute"] = 56,
|
||||
["second"] = 28,
|
||||
["millisecond"] = 892,
|
||||
})["unixTimestamp"])
|
||||
|
||||
local timeValues2 = os.date("*t", 1693049188.892)
|
||||
|
||||
assert(
|
||||
DateTime.fromLocalTime({
|
||||
["year"] = timeValues2.year,
|
||||
["month"] = timeValues2.month,
|
||||
["day"] = timeValues2.day,
|
||||
["hour"] = timeValues2.hour,
|
||||
["minute"] = timeValues2.min,
|
||||
["second"] = timeValues2.sec,
|
||||
["millisecond"] = 892,
|
||||
})["unixTimestampMillis"] == 1693049188892,
|
||||
"expected DateTime.fromLocalTime() with DateTimeValues arg with millis to return 1693049188892ms"
|
||||
)
|
|
@ -1,32 +0,0 @@
|
|||
local DateTime = require("@lune/datetime")
|
||||
|
||||
assert(
|
||||
DateTime.fromLocalTime()["unixTimestamp"] == os.time(),
|
||||
"expected DateTime.fromLocalTime() with no args to return DateTime at current moment"
|
||||
)
|
||||
|
||||
assert(
|
||||
DateTime.fromLocalTime({
|
||||
["year"] = 2023,
|
||||
["month"] = "aug",
|
||||
["day"] = 26,
|
||||
["hour"] = 16,
|
||||
["minute"] = 56,
|
||||
["second"] = 28,
|
||||
["millisecond"] = 0,
|
||||
})["unixTimestamp"] == 1693049188,
|
||||
"expected DateTime.fromLocalTime() with DateTimeValues arg to return 1693049188s"
|
||||
)
|
||||
|
||||
assert(
|
||||
DateTime.fromLocalTime({
|
||||
["year"] = 2023,
|
||||
["month"] = "aug",
|
||||
["day"] = 26,
|
||||
["hour"] = 16,
|
||||
["minute"] = 56,
|
||||
["second"] = 28,
|
||||
["millisecond"] = 892,
|
||||
})["unixTimestampMillis"] == 1693049188892,
|
||||
"expected DateTime.fromLocalTime() with DateTimeValues arg with millis to return 1693049188892ms"
|
||||
)
|
30
tests/datetime/toLocalTime.luau
Normal file
30
tests/datetime/toLocalTime.luau
Normal file
|
@ -0,0 +1,30 @@
|
|||
local DateTime = require("@lune/datetime")
|
||||
|
||||
local dateTime = (DateTime.fromIsoDate("2023-08-27T05:54:19Z") :: DateTime.DateTime):toLocalTime()
|
||||
|
||||
local expectedDateTimeValues = os.date("*t", 1693115659)
|
||||
|
||||
assert(
|
||||
dateTime.year == expectedDateTimeValues.year,
|
||||
`expected {dateTime.year} == {expectedDateTimeValues.year}`
|
||||
)
|
||||
assert(
|
||||
dateTime.month == expectedDateTimeValues.month,
|
||||
`expected {dateTime.month} == {expectedDateTimeValues.month}`
|
||||
)
|
||||
assert(
|
||||
dateTime.day == expectedDateTimeValues.day,
|
||||
`expected {dateTime.day} == {expectedDateTimeValues.day}`
|
||||
)
|
||||
assert(
|
||||
dateTime.hour == expectedDateTimeValues.hour,
|
||||
`expected {dateTime.hour} == {expectedDateTimeValues.hour}`
|
||||
)
|
||||
assert(
|
||||
dateTime.minute == expectedDateTimeValues.min,
|
||||
`expected {dateTime.minute} == {expectedDateTimeValues.min}`
|
||||
)
|
||||
assert(
|
||||
dateTime.second == expectedDateTimeValues.sec,
|
||||
`expected {dateTime.second} == {expectedDateTimeValues.sec}`
|
||||
)
|
|
@ -1,24 +0,0 @@
|
|||
local DateTime = require("@lune/datetime")
|
||||
|
||||
local dateTime = (DateTime.fromIsoDate("2023-08-27T05:54:19Z") :: DateTime.DateTime):toLocalTime()
|
||||
|
||||
local expectedDateTimeValues = table.pack(
|
||||
string.match(
|
||||
"2023-08-27T11:24:19Z",
|
||||
"(%d%d%d%d)-?(%d?%d?)-?(%d?%d?)T(%d?%d?):(%d?%d?):(%d?%d?)Z$"
|
||||
)
|
||||
)
|
||||
|
||||
local expectedYear = tonumber(expectedDateTimeValues[1])
|
||||
local expectedMonth = tonumber(expectedDateTimeValues[2])
|
||||
local expectedDay = tonumber(expectedDateTimeValues[3])
|
||||
local expectedHour = tonumber(expectedDateTimeValues[4])
|
||||
local expectedMinute = tonumber(expectedDateTimeValues[5])
|
||||
local expectedSecond = tonumber(expectedDateTimeValues[6])
|
||||
|
||||
assert(dateTime.year == expectedYear, `expected {dateTime.year} == {expectedYear}`)
|
||||
assert(dateTime.month == expectedMonth, `expected {dateTime.month} == {expectedMonth}`)
|
||||
assert(dateTime.day == expectedDay, `expected {dateTime.day} == {expectedDay}`)
|
||||
assert(dateTime.hour == expectedHour, `expected {dateTime.hour} == {expectedHour}`)
|
||||
assert(dateTime.minute == expectedMinute, `expected {dateTime.minute} == {expectedMinute}`)
|
||||
assert(dateTime.second == expectedSecond, `expected {dateTime.second} == {expectedSecond}`)
|
Loading…
Add table
Reference in a new issue