Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
hudson-newey committed Dec 7, 2023
1 parent 9d891c7 commit e8b29cb
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,17 @@ <h1>DateTime Examples</h1>
<section class="mb-3">
<form>
<label for="datetime-input">Date/Time</label>

<!--
The datetime is emitted in full ISO8601 format so that the user can explicitly configure
the UTC offset (eg. +08:00)
-->
<input
type="datetime"
name="datetime-input"
id="datetime-input"
class="form-control"
placeholder="yyyy-mm-ddThh:mm:ss+hh:mm"
[ngModel]="fakeDate"
[ngModel]="formatDate(fakeDate)"
(keyup)="updateFakeDate($event)"
/>

<label for="timezone-input">Implicit/Explicit Timezone</label>
<label for="timezone-input">Timezone</label>
<input
type="text"
name="timezone-input"
Expand Down Expand Up @@ -46,41 +41,41 @@ <h1>DateTime Examples</h1>
<h2>baw-datetime</h2>

<div class="mt-3">
<strong>Date & Time Instants:</strong><br />
<strong>Date & Time Instants:</strong>

<code>
<pre>&lt;baw-datetime [value]="fakeUserDate" /&gt;</pre>
<pre>&lt;baw-datetime [value]="fakeDateWithZone" /&gt;</pre>
</code>

<baw-datetime [value]="fakeUserDate" />
<baw-datetime [value]="fakeDateWithZone" />
</div>

<div class="mt-3">
<strong>Date Instants:</strong><br />
<strong>Date Instants:</strong>

<code>
<pre>&lt;baw-datetime [value]="fakeUserDate" dateOnly /&gt;</pre>
<pre>&lt;baw-datetime [value]="fakeDateWithZone" dateOnly /&gt;</pre>
</code>

<baw-datetime [value]="fakeUserDate" dateOnly />
<baw-datetime [value]="fakeDateWithZone" dateOnly />
</div>

<div class="mt-3">
<strong>Time Instants:</strong><br />
<strong>Time Instants:</strong>

<code>
<pre>&lt;baw-datetime [value]="fakeUserDate" timeOnly /&gt;</pre>
<pre>&lt;baw-datetime [value]="fakeDateWithZone" timeOnly /&gt;</pre>
</code>

<baw-datetime [value]="fakeUserDate" timeOnly />
<baw-datetime [value]="fakeDateWithZone" timeOnly />
</div>
</section>

<section class="mt-4">
<h2>baw-zoned-datetime (Implicit)</h2>

<div class="mt-3">
<strong>Zoned Date & Time Instants:</strong><br />
<strong>Zoned Date & Time Instants:</strong>

<code>
<pre>&lt;baw-zoned-datetime [value]="fakeDateWithZone" /&gt;</pre>
Expand All @@ -90,7 +85,7 @@ <h2>baw-zoned-datetime (Implicit)</h2>
</div>

<div class="mt-3">
<strong>Zoned Date & Time Instants:</strong><br />
<strong>Zoned Date & Time Instants:</strong>

<code>
<pre>&lt;baw-zoned-datetime [value]="fakeDateWithZone" dateOnly /&gt;</pre>
Expand All @@ -100,7 +95,7 @@ <h2>baw-zoned-datetime (Implicit)</h2>
</div>

<div class="mt-3">
<strong>Zoned Date & Time Instants:</strong><br />
<strong>Zoned Date & Time Instants:</strong>

<code>
<pre>&lt;baw-zoned-datetime [value]="fakeDateWithZone" timeOnly /&gt;</pre>
Expand All @@ -112,7 +107,7 @@ <h2>baw-zoned-datetime (Implicit)</h2>
<h2>baw-zoned-datetime (Explicit)</h2>

<div class="mt-3">
<strong>Zoned Date & Time Instants:</strong><br />
<strong>Zoned Date & Time Instants:</strong>

<code>
<pre>&lt;baw-zoned-datetime [value]="fakeDate" [timezone]="fakeTimezone" /&gt;</pre>
Expand All @@ -122,7 +117,7 @@ <h2>baw-zoned-datetime (Explicit)</h2>
</div>

<div class="mt-3">
<strong>Zoned Date Instants:</strong><br />
<strong>Zoned Date Instants:</strong>

<code>
<pre>&lt;baw-zoned-datetime [value]="fakeDate" [timezone]="fakeTimezone" dateOnly /&gt;</pre>
Expand All @@ -136,7 +131,7 @@ <h2>baw-zoned-datetime (Explicit)</h2>
</div>

<div class="mt-3">
<strong>Zoned Time Instants:</strong><br />
<strong>Zoned Time Instants:</strong>

<code>
<pre>&lt;baw-zoned-datetime [value]="fakeDate" [timezone]="fakeTimezone" timeOnly /&gt;</pre>
Expand All @@ -154,7 +149,7 @@ <h2>baw-zoned-datetime (Explicit)</h2>
<h2>baw-duration</h2>

<div class="mt-3">
<strong>Durations (sexagesimal):</strong><br />
<strong>Durations (sexagesimal):</strong>

<code>
<pre>&lt;baw-duration [value]="fakeDuration" /&gt;</pre>
Expand All @@ -164,7 +159,7 @@ <h2>baw-duration</h2>
</div>

<div class="mt-3">
<strong>Duration (ISO 8601):</strong><br />
<strong>Duration (ISO 8601):</strong>

<code>
<pre>&lt;baw-duration [value]="fakeDuration" iso8601 /&gt;</pre>
Expand All @@ -174,7 +169,7 @@ <h2>baw-duration</h2>
</div>

<div class="mt-3">
<strong>Duration (Humanized):</strong><br />
<strong>Duration (Humanized):</strong>

<code>
<pre>&lt;baw-duration [value]="fakeDuration" humanized /&gt;</pre>
Expand All @@ -188,7 +183,7 @@ <h2>baw-duration</h2>
<h2>baw-time-since</h2>

<div class="mt-3">
<strong>Relative Date & Time Instants:</strong><br />
<strong>Relative Date & Time Instants:</strong>

<code>
<pre>&lt;baw-time-since [value]="fakeDate" /&gt;</pre>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnInit } from "@angular/core";
import { Component } from "@angular/core";
import { List } from "immutable";
import { PageComponent } from "@helpers/page/pageComponent";
import { DateTime, Duration } from "luxon";
Expand All @@ -9,28 +9,21 @@ import { adminMenuItemActions } from "../dashboard/dashboard.component";
selector: "baw-admin-datetime-templates",
templateUrl: "datetime-templates.component.html",
})
class DateTimeExampleComponent extends PageComponent implements OnInit {
class DateTimeExampleComponent extends PageComponent {
public constructor() {
super();
}

protected fakeTimezone = "Australia/Perth";
protected fakeDate;
protected fakeDuration;
protected fakeDate = DateTime.now();
protected fakeDuration = Duration.fromObject({ hours: 1, minutes: 30 });

public ngOnInit(): void {
this.fakeDate = DateTime.now();
this.fakeDuration = Duration.fromObject({ hours: 1, minutes: 30 });
}

protected get fakeUserDate(): DateTime {
const luxonDateTime = this.fakeDate instanceof DateTime ? this.fakeDate : DateTime.fromISO(this.fakeDate);
return luxonDateTime;
}

// used for implicit timezone tests
protected get fakeDateWithZone(): DateTime {
const luxonDateTime = this.fakeDate instanceof DateTime ? this.fakeDate : DateTime.fromISO(this.fakeDate);
const luxonDateTime =
this.fakeDate instanceof DateTime
? this.fakeDate
: DateTime.fromISO(this.fakeDate);

return luxonDateTime.setZone(this.fakeTimezone, { keepLocalTime: true });
}

Expand All @@ -45,12 +38,17 @@ class DateTimeExampleComponent extends PageComponent implements OnInit {

protected updateFakeDate(event: any): void {
const inputValue: string = event.target.value;
const newDate = DateTime.fromISO(inputValue).setZone(this.fakeTimezone, { keepLocalTime: true });
const newDate = DateTime.fromFormat(inputValue, "yyyy-MM-dd HH:mm:ss");

if (newDate.isValid) {
this.fakeDate = newDate;
}
}

// used in the date/time input
protected formatDate(dateTime: DateTime): string {
return dateTime.toFormat("yyyy-MM-dd HH:mm:ss");
}
}

DateTimeExampleComponent.linkToRoute({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { AbstractDatetimeComponent } from "./abstract-datetime.component";

describe("AbstractDatetimeComponent", () => {
let abstractDatetimeComponent: AbstractDatetimeComponent;

beforeEach(() => {
abstractDatetimeComponent = new AbstractDatetimeComponentMock();
});

it("should create", () => {
expect(abstractDatetimeComponent).toBeTruthy();
});

it("should have a default prefix of an empty string", () => {
expect(abstractDatetimeComponent.suffix()).toEqual("");
});
});

class AbstractDatetimeComponentMock extends AbstractDatetimeComponent {
public formattedValue = () => "";
public tooltipValue = () => "";
public rawDateTime = () => "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ describe("DatetimeComponent", () => {
});

function setup(): void {
// to ensure that tests pass for all timezones, we set the default timezone to utc
// this will ensure that all DateTime objects are created in utc instead of the test runners local timezone
// to ensure that tests pass for all timezones, we set the default timezone to Australia/Perth
// this mocks the test runners timezone to be Australia/Perth so that they will assert correctly in all timezones
Settings.defaultZone = "Australia/Perth";

// utc datetime should be localised to "Australia/Perth"
// utc datetime should be localized to "Australia/Perth"
let fakeDateTime = DateTime.fromISO("2020-01-01T12:10:11.000Z");
fakeDateTime = fakeDateTime.setZone("utc");
fakeDateTime = fakeDateTime.toUTC();

spectator = createComponent({ detectChanges: false });
spectator.component.value = fakeDateTime;
Expand All @@ -36,6 +36,9 @@ describe("DatetimeComponent", () => {
expect(spectator.component).toBeInstanceOf(DatetimeComponent);
});

// the output time should be localized to the users timezone
// eg. Because this fake DateTime was created using UTC+0, it should be localized to UTC+8
// adding 8 hours to the UTC time
it("should display the full date and time in the users local timezone by default", () => {
const fakeDateTime = DateTime.fromISO("2020-01-01T12:10:11.000Z");
const expectedDateTime = "2020-01-01 20:10:11";
Expand Down Expand Up @@ -81,17 +84,6 @@ describe("DatetimeComponent", () => {
expect(spectator.element).toHaveExactTrimmedText(expectedDateTime);
});

it("should show a full utc date time in the users timezone", () => {
const fakeDateTime = DateTime.fromISO("2020-01-01T12:10:11.000Z");
const expectedDateTime = "2020-01-01 20:10:11";

spectator.component.value = fakeDateTime;

spectator.detectChanges();

expect(spectator.element).toHaveExactTrimmedText(expectedDateTime);
});

it("should have a tooltip that displays the full un-localized date, time and utc offset for a JavaScript date object", () => {
const expectedTooltip = "2020-01-01 20:10:11 (Australia/Perth UTC+08:00)";
const mockDate = new Date("2020-01-01T12:10:11.000Z");
Expand All @@ -112,7 +104,7 @@ describe("DatetimeComponent", () => {
assertTooltip(componentElement(), expectedTooltip);
});

it("should localize an iso8601 date/time with an offset to the users local timezone", () => {
it("should localize an iso8601 date/time with an offset", () => {
const expectedDateTime = "2020-01-01 19:10:11";
const mockDateTime = new Date("2020-01-01T12:10:11.000+01:00");

Expand All @@ -122,7 +114,7 @@ describe("DatetimeComponent", () => {
expect(spectator.element).toHaveExactTrimmedText(expectedDateTime);
});

it("should localize a Luxon DateTime object with a timezone offset to the users local timezone", () => {
it("should localize a Luxon DateTime object with a timezone offset", () => {
const expectedDateTime = "2020-01-01 19:10:11";
const mockDateTime = DateTime.fromISO("2020-01-01T12:10:11.000+01:00");

Expand All @@ -133,8 +125,8 @@ describe("DatetimeComponent", () => {
});

it("should have the correct tooltip for a Luxon DateTime object with an offset, but no timezone", () => {
// since tooltips should always be localized to the users timezone, we know that the tooltip should
// include timezone information
// since tooltips should always be localized to the users timezone, we know the users timezone name
// so unlike the zoned-datetime component, the tooltip should include timezone information
const expectedTooltip = "2020-01-01 19:10:11 (Australia/Perth UTC+08:00)";
const mockDateTime = new Date("2020-01-01T12:10:11.000+01:00");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class DurationComponent extends AbstractDatetimeComponent {
@Input() public iso8601: string | boolean;

public formattedValue(): string {
// we use isInstantiated() to check if the humanized attribute is set (empty)
// we use isInstantiated() to check if the humanized attribute is set
// and we also check that it is not set to false
// by allowing boolean values, we support reactive formats (e.g. [humanized]="isHumanized")
if (isInstantiated(this.humanized) && this.humanized !== false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe("RelativeTimeComponent", () => {
expect(spectator.element).toHaveExactTrimmedText(expectedText);
});

it("should not emit seconds or miliseconds in the formatted text", () => {
it("should not emit seconds or milliseconds in the formatted text", () => {
const expectedText = "4 hours 42 minutes ago";
const fakeDuration = Duration.fromObject({
hours: 4,
Expand All @@ -62,7 +62,7 @@ describe("RelativeTimeComponent", () => {
expect(spectator.element).toHaveExactTrimmedText(expectedText);
});

it("should round up times to the nearest second", () => {
it("should round up times to the nearest minute", () => {
const expectedText = "4 hours 42 minutes ago";
const fakeDuration = Duration.fromObject({
hours: 4,
Expand Down
Loading

0 comments on commit e8b29cb

Please sign in to comment.