diff --git a/.ember-cli b/.ember-cli index acc2a0e0d..a37e45fab 100644 --- a/.ember-cli +++ b/.ember-cli @@ -3,7 +3,7 @@ Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript rather than JavaScript by default, when a TypeScript version of a given blueprint is available. */ - "isTypeScriptProject": false, + "isTypeScriptProject": true, /** Setting `componentAuthoringFormat` to "strict" will force the blueprint generators to generate GJS diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4c4eb8f5c..1b1c5690d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ Roughly every 4 minor versions, and every final minor version before the next ma Once a new LTS has been announced, please update the [LTS Channel page](https://emberjs.com/releases/lts/) by following these steps: -- Update `app/utils/releases/lts.js` to show currently supported LTS versions. +- Update `app/utils/releases/lts.ts` to show currently supported LTS versions. - Update `data/project/ember/lts.md` to show the most recent LTS version. You can find out _when_ a release was promoted to LTS from the [changelog for Ember.js](https://github.com/emberjs/ember.js/blob/master/CHANGELOG.md). The LTS promotion date is the release date of the next minor version. For example, Ember 3.16 was promoted to LTS on [March 4, 2020](https://github.com/emberjs/ember.js/blob/master/CHANGELOG.md#v3170-march-4-2020) because that's the release date of v3.17.0. diff --git a/app/adapters/application.js b/app/adapters/application.ts similarity index 64% rename from app/adapters/application.js rename to app/adapters/application.ts index b20584305..9e13c1880 100644 --- a/app/adapters/application.js +++ b/app/adapters/application.ts @@ -1,21 +1,23 @@ import JSONAPIAdapter from '@ember-data/adapter/json-api'; export default class ApplicationAdapter extends JSONAPIAdapter { - shouldBackgroundReloadAll() { + shouldBackgroundReloadAll(): boolean { return false; } - shouldBackgroundReloadRecord() { + shouldBackgroundReloadRecord(): boolean { return false; } - urlForFindAll(modelName) { + urlForFindAll(modelName: string): string { const path = this.pathForType(modelName); + return `/data/${path}/all.json`; } - urlForFindRecord(id, modelName) { + urlForFindRecord(id: string, modelName: string): string { const path = this.pathForType(modelName); + return `/data/${path}/${id}.json`; } } diff --git a/app/app.js b/app/app.ts similarity index 100% rename from app/app.js rename to app/app.ts diff --git a/app/config/environment.ts b/app/config/environment.ts new file mode 100644 index 000000000..bc80f9a2d --- /dev/null +++ b/app/config/environment.ts @@ -0,0 +1,33 @@ +import { assert } from '@ember/debug'; +import loadConfigFromMeta from '@embroider/config-meta-loader'; + +const config = loadConfigFromMeta('ember-website') as unknown; + +assert( + 'config is not an object', + typeof config === 'object' && config !== null, +); +assert( + 'modulePrefix was not detected on your config', + 'modulePrefix' in config && typeof config.modulePrefix === 'string', +); +assert( + 'locationType was not detected on your config', + 'locationType' in config && typeof config.locationType === 'string', +); +assert( + 'rootURL was not detected on your config', + 'rootURL' in config && typeof config.rootURL === 'string', +); +assert( + 'APP was not detected on your config', + 'APP' in config && typeof config.APP === 'object', +); + +export default config as { + APP: Record; + locationType: string; + modulePrefix: string; + podModulePrefix?: string; + rootURL: string; +} & Record; diff --git a/app/helpers/add-weeks.js b/app/helpers/add-weeks.js deleted file mode 100644 index dc195abde..000000000 --- a/app/helpers/add-weeks.js +++ /dev/null @@ -1,6 +0,0 @@ -import { helper } from '@ember/component/helper'; -import dayjs from 'dayjs'; - -export default helper(function addWeeks([initialDate, numWeeks = 0]) { - return dayjs(initialDate).add(numWeeks, 'week'); -}); diff --git a/app/helpers/add-weeks.ts b/app/helpers/add-weeks.ts new file mode 100644 index 000000000..aa7a096dc --- /dev/null +++ b/app/helpers/add-weeks.ts @@ -0,0 +1,18 @@ +import { helper } from '@ember/component/helper'; +import dayjs from 'dayjs'; +import type { Dayjs } from 'dayjs'; + +interface AddWeeksSignature { + Args: { + Named: {}; + Positional: [initialDate: string | Date | Dayjs, numWeeks?: number]; + }; + Return: Dayjs; +} + +export default helper(function addWeeks([ + initialDate, + numWeeks = 0, +]) { + return dayjs(initialDate).add(numWeeks, 'week'); +}); diff --git a/app/helpers/format-date-time.js b/app/helpers/format-date-time.js deleted file mode 100644 index 7ae0842d6..000000000 --- a/app/helpers/format-date-time.js +++ /dev/null @@ -1,10 +0,0 @@ -import { helper } from '@ember/component/helper'; -import dayjs from 'dayjs'; - -export default helper(function formatDateTime([date, format = 'MMM D']) { - if (!date) { - return 'Unknown date'; - } - - return dayjs(date).format(format); -}); diff --git a/app/helpers/format-date-time.ts b/app/helpers/format-date-time.ts new file mode 100644 index 000000000..351e28608 --- /dev/null +++ b/app/helpers/format-date-time.ts @@ -0,0 +1,22 @@ +import { helper } from '@ember/component/helper'; +import dayjs from 'dayjs'; +import type { Dayjs } from 'dayjs'; + +interface FormatDateTimeSignature { + Args: { + Named: {}; + Positional: [date?: string | Date | Dayjs, format?: string]; + }; + Return: string; +} + +export default helper(function formatDateTime([ + date, + format = 'MMM D', +]) { + if (!date) { + return 'Unknown date'; + } + + return dayjs(date).format(format); +}); diff --git a/app/helpers/printf.js b/app/helpers/printf.js deleted file mode 100644 index c16f5a6d2..000000000 --- a/app/helpers/printf.js +++ /dev/null @@ -1,5 +0,0 @@ -import { helper } from '@ember/component/helper'; - -export default helper(function printf([string = '', replacement = '']) { - return string.replace(/%s/g, replacement); -}); diff --git a/app/helpers/printf.ts b/app/helpers/printf.ts new file mode 100644 index 000000000..44089c0f3 --- /dev/null +++ b/app/helpers/printf.ts @@ -0,0 +1,16 @@ +import { helper } from '@ember/component/helper'; + +interface PrintFSignature { + Args: { + Named: {}; + Positional: [value?: string, replacement?: string]; + }; + Return: string; +} + +export default helper(function printf([ + value = '', + replacement = '', +]) { + return value.replace(/%s/g, replacement); +}); diff --git a/app/helpers/qp.js b/app/helpers/qp.js deleted file mode 100644 index 9940abbcf..000000000 --- a/app/helpers/qp.js +++ /dev/null @@ -1,10 +0,0 @@ -import Helper from '@ember/component/helper'; -import { service } from '@ember/service'; - -export default class QP extends Helper { - @service router; - - compute([qp]) { - return this.router.currentRoute?.queryParams?.[qp]; - } -} diff --git a/app/helpers/qp.ts b/app/helpers/qp.ts new file mode 100644 index 000000000..27c8f5e11 --- /dev/null +++ b/app/helpers/qp.ts @@ -0,0 +1,21 @@ +import Helper from '@ember/component/helper'; +import { type Registry as Services, service } from '@ember/service'; + +interface QpSignature { + Args: { + Named: {}; + Positional: [key: string]; + }; + Return: string | undefined; +} + +export default class QpHelper extends Helper { + @service declare router: Services['router']; + + compute([key]: QpSignature['Args']['Positional']): QpSignature['Return'] { + const queryParams = this.router.currentRoute?.queryParams as + Record | undefined; + + return queryParams?.[key]; + } +} diff --git a/app/models/initiative-sponsor.js b/app/models/initiative-sponsor.js deleted file mode 100644 index 4c0dd8a9b..000000000 --- a/app/models/initiative-sponsor.js +++ /dev/null @@ -1,10 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class SponsorModel extends Model { - @attr content; - @attr image; - @attr name; - @attr url; - @attr('number') tier; - @attr('number') order; -} diff --git a/app/models/initiative-sponsor.ts b/app/models/initiative-sponsor.ts new file mode 100644 index 000000000..0a99898ed --- /dev/null +++ b/app/models/initiative-sponsor.ts @@ -0,0 +1,13 @@ +import Model, { attr } from '@ember-data/model'; +import type { Type } from '@warp-drive/core-types/symbols'; + +export default class InitiativeSponsorModel extends Model { + declare [Type]: 'initiative-sponsor'; + + @attr declare content: string; + @attr declare image: string; + @attr declare name: string; + @attr declare url: string; + @attr('number') declare tier: number; + @attr('number') declare order: number; +} diff --git a/app/models/meetup.js b/app/models/meetup.js deleted file mode 100644 index 9d635f94c..000000000 --- a/app/models/meetup.js +++ /dev/null @@ -1,10 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class MeetupModel extends Model { - @attr('string') area; - @attr('number') lat; - @attr('number') lng; - @attr('string') location; - @attr organizers; - @attr('string') url; -} diff --git a/app/models/meetup.ts b/app/models/meetup.ts new file mode 100644 index 000000000..d4170eaba --- /dev/null +++ b/app/models/meetup.ts @@ -0,0 +1,16 @@ +import Model, { attr } from '@ember-data/model'; +import type { Type } from '@warp-drive/core-types/symbols'; + +export default class MeetupModel extends Model { + declare [Type]: 'meetup'; + + @attr declare area: string; + @attr('number') declare lat: number; + @attr('number') declare lng: number; + @attr declare location: string; + @attr declare organizers: { + organizer: string; + profileImage?: string; + }[]; + @attr declare url: string; +} diff --git a/app/models/project.js b/app/models/project.js deleted file mode 100644 index 5a1cc247d..000000000 --- a/app/models/project.js +++ /dev/null @@ -1,23 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class ProjectModel extends Model { - @attr('string') baseFileName; - @attr('string') changelogPath; - @attr('string') channel; - @attr('string') content; - @attr('date') date; - @attr('string') debugFileName; - @attr filter; - @attr ignoreFiles; - @attr('string') lastRelease; - @attr('string') name; - @attr('string') repo; - - get lastReleaseChangelogUrl() { - if (this.channel === 'canary' || !this.changelogPath) { - return ''; - } - - return `https://github.com/${this.repo}/blob/v${this.lastRelease}/${this.changelogPath}`; - } -} diff --git a/app/models/project.ts b/app/models/project.ts new file mode 100644 index 000000000..503baa1e5 --- /dev/null +++ b/app/models/project.ts @@ -0,0 +1,26 @@ +import Model, { attr } from '@ember-data/model'; +import type { Type } from '@warp-drive/core-types/symbols'; + +export default class ProjectModel extends Model { + declare [Type]: 'project'; + + @attr declare baseFileName: string; + @attr declare changelogPath: string; + @attr declare channel: string; + @attr declare content: string; + @attr('date') declare date: Date; + @attr declare debugFileName: string; + @attr declare filter: string; + @attr declare ignoreFiles: string[]; + @attr declare lastRelease: string; + @attr declare name: string; + @attr declare repo: string; + + get lastReleaseChangelogUrl(): string { + if (this.channel === 'canary' || !this.changelogPath) { + return ''; + } + + return `https://github.com/${this.repo}/blob/v${this.lastRelease}/${this.changelogPath}`; + } +} diff --git a/app/models/showcase.js b/app/models/showcase.js deleted file mode 100644 index 4da3f09ef..000000000 --- a/app/models/showcase.js +++ /dev/null @@ -1,10 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class ShowcaseModel extends Model { - @attr('string') demo; - @attr features; - @attr('string') html; - @attr image; - @attr('string') name; - @attr('string') repository; -} diff --git a/app/models/showcase.ts b/app/models/showcase.ts new file mode 100644 index 000000000..b6388598f --- /dev/null +++ b/app/models/showcase.ts @@ -0,0 +1,15 @@ +import Model, { attr } from '@ember-data/model'; +import type { Type } from '@warp-drive/core-types/symbols'; + +export default class ShowcaseModel extends Model { + declare [Type]: 'showcase'; + + @attr declare demo: string; + @attr declare features: string; + @attr declare html: string; + @attr declare image: { + src: string; + }; + @attr declare name: string; + @attr declare repository: string; +} diff --git a/app/models/sponsor.js b/app/models/sponsor.js deleted file mode 100644 index fb5018744..000000000 --- a/app/models/sponsor.js +++ /dev/null @@ -1,30 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class SponsorModel extends Model { - @attr content; - @attr('date') end; - @attr image; - @attr name; - @attr('date') start; - @attr url; - @attr('number') order; - - get term() { - let startYear = this.start.getFullYear(); - let endYear; - - if (this.end) { - endYear = this.end.getFullYear(); - } - - if (startYear === endYear) { - return `${startYear}`; - } - - if (!endYear) { - endYear = 'present'; - } - - return `${startYear} - ${endYear}`; - } -} diff --git a/app/models/sponsor.ts b/app/models/sponsor.ts new file mode 100644 index 000000000..ce3fdf271 --- /dev/null +++ b/app/models/sponsor.ts @@ -0,0 +1,33 @@ +import Model, { attr } from '@ember-data/model'; +import type { Type } from '@warp-drive/core-types/symbols'; + +export default class SponsorModel extends Model { + declare [Type]: 'sponsor'; + + @attr declare content: string; + @attr('date') declare end: Date; + @attr declare image: string; + @attr declare name: string; + @attr('date') declare start: Date; + @attr declare url: string; + @attr('number') declare order: number; + + get term(): string { + const startYear = this.start.getFullYear(); + let endYear; + + if (this.end) { + endYear = this.end.getFullYear(); + } + + if (startYear === endYear) { + return `${startYear}`; + } + + if (!endYear) { + endYear = 'present'; + } + + return `${startYear} - ${endYear}`; + } +} diff --git a/app/models/team-member.js b/app/models/team-member.js deleted file mode 100644 index cf75670f9..000000000 --- a/app/models/team-member.js +++ /dev/null @@ -1,15 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class TeamMemberModel extends Model { - @attr('date') added; - @attr bluesky; - @attr first; - @attr github; - @attr image; - @attr last; - @attr mastodon; - @attr name; - @attr social; - @attr teams; - @attr twitter; -} diff --git a/app/models/team-member.ts b/app/models/team-member.ts new file mode 100644 index 000000000..0a481d7ce --- /dev/null +++ b/app/models/team-member.ts @@ -0,0 +1,18 @@ +import Model, { attr } from '@ember-data/model'; +import type { Type } from '@warp-drive/core-types/symbols'; + +export default class TeamMemberModel extends Model { + declare [Type]: 'team-member'; + + @attr('date') declare added: Date; + @attr declare bluesky?: string; + @attr declare first: string; + @attr declare github?: string; + @attr declare image: string; + @attr declare last: string; + @attr declare mastodon?: string; + @attr declare name: string; + @attr declare social?: string; + @attr declare teams: string[]; + @attr declare twitter?: string; +} diff --git a/app/models/tomster.js b/app/models/tomster.js deleted file mode 100644 index c45ae103b..000000000 --- a/app/models/tomster.js +++ /dev/null @@ -1,9 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class TomsterModel extends Model { - @attr('date') date; - @attr('string') image; - @attr tags; - @attr('string') title; - @attr('string') url; -} diff --git a/app/models/tomster.ts b/app/models/tomster.ts new file mode 100644 index 000000000..435b5779f --- /dev/null +++ b/app/models/tomster.ts @@ -0,0 +1,12 @@ +import Model, { attr } from '@ember-data/model'; +import type { Type } from '@warp-drive/core-types/symbols'; + +export default class TomsterModel extends Model { + declare [Type]: 'tomster'; + + @attr('date') declare date: Date; + @attr declare image: string; + @attr declare tags: string[]; + @attr declare title: string; + @attr declare url: string; +} diff --git a/app/models/user.js b/app/models/user.js deleted file mode 100644 index c089bc41d..000000000 --- a/app/models/user.js +++ /dev/null @@ -1,11 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class UserModel extends Model { - @attr('date') added; - @attr('string') content; - @attr('boolean') featured; - @attr('string') image; - @attr('boolean') inactive; - @attr('string') name; - @attr('string') url; -} diff --git a/app/models/user.ts b/app/models/user.ts new file mode 100644 index 000000000..1bae9e4ce --- /dev/null +++ b/app/models/user.ts @@ -0,0 +1,14 @@ +import Model, { attr } from '@ember-data/model'; +import type { Type } from '@warp-drive/core-types/symbols'; + +export default class UserModel extends Model { + declare [Type]: 'user'; + + @attr('date') declare added: Date; + @attr declare content: string; + @attr('boolean') declare featured: boolean; + @attr declare image: string; + @attr('boolean') declare inactive: boolean; + @attr declare name: string; + @attr declare url: string; +} diff --git a/app/modifiers/draw-chart.js b/app/modifiers/draw-chart.ts similarity index 59% rename from app/modifiers/draw-chart.js rename to app/modifiers/draw-chart.ts index 07a0bd691..0463f7306 100644 --- a/app/modifiers/draw-chart.js +++ b/app/modifiers/draw-chart.ts @@ -1,7 +1,23 @@ import { registerDestructor } from '@ember/destroyable'; import merge from 'deepmerge'; +import type { PositionalArgs } from 'ember-modifier'; import Modifier from 'ember-modifier'; +// eslint-disable-next-line @typescript-eslint/consistent-type-imports +type Highcharts = typeof import('highcharts'); + +type Chart = { + highchartsOptions: Highcharts.ChartOptions; +}; + +interface DrawChartSignature { + Args: { + Named: {}; + Positional: [chart?: Chart]; + }; + Element: HTMLElement; +} + const optionsForAllCharts = { credits: { enabled: false, @@ -18,10 +34,15 @@ const optionsForAllCharts = { }, }; -export default class DrawChartModifier extends Modifier { - highcharts; +export default class DrawChartModifier extends Modifier { + declare chartInstance: Highcharts.Chart; + declare highcharts: Highcharts; - async modify(element, [chart]) { + // eslint-disable-next-line @typescript-eslint/no-misused-promises + async modify( + element: HTMLElement, + [chart]: PositionalArgs, + ): Promise { if (!chart) { return; } @@ -33,7 +54,7 @@ export default class DrawChartModifier extends Modifier { registerDestructor(this, this.destroyChart.bind(this)); } - async initializeHighcharts() { + async initializeHighcharts(): Promise { if (this.highcharts) { return; } @@ -48,7 +69,8 @@ export default class DrawChartModifier extends Modifier { this.highcharts.setOptions(optionsForAllCharts); } - drawChart({ chart, element }) { + drawChart({ chart, element }: { chart: Chart; element: HTMLElement }): void { + // @ts-expect-error: Incorrect type element.removeAttribute('data-render-state', 'settled'); const chartOptions = merge( @@ -67,7 +89,7 @@ export default class DrawChartModifier extends Modifier { this.chartInstance = this.highcharts.chart(element, chartOptions); } - destroyChart() { + destroyChart(): void { this.chartInstance.destroy(); } } diff --git a/app/router.js b/app/router.ts similarity index 100% rename from app/router.js rename to app/router.ts diff --git a/app/serializers/application.js b/app/serializers/application.ts similarity index 79% rename from app/serializers/application.js rename to app/serializers/application.ts index eaffa3a0b..87d376aca 100644 --- a/app/serializers/application.js +++ b/app/serializers/application.ts @@ -1,7 +1,7 @@ import JSONAPISerializer from '@ember-data/serializer/json-api'; export default class ApplicationSerializer extends JSONAPISerializer { - keyForAttribute(key) { + keyForAttribute(key: string): string { return key; } } diff --git a/app/services/head-data.js b/app/services/head-data.ts similarity index 52% rename from app/services/head-data.js rename to app/services/head-data.ts index de8ae86b1..95e2f46bc 100644 --- a/app/services/head-data.js +++ b/app/services/head-data.ts @@ -2,5 +2,11 @@ import Service from '@ember/service'; import { tracked } from '@glimmer/tracking'; export default class HeadDataService extends Service { - @tracked pageTitle; + @tracked pageTitle?: string; +} + +declare module '@ember/service' { + interface Registry { + 'head-data': HeadDataService; + } } diff --git a/app/services/page-title.js b/app/services/page-title.ts similarity index 64% rename from app/services/page-title.js rename to app/services/page-title.ts index 9e2f2c2af..f087b0160 100644 --- a/app/services/page-title.js +++ b/app/services/page-title.ts @@ -8,13 +8,19 @@ https://github.com/ember-cli/ember-page-title/issues/201#issuecomment-761081734 */ -import { service } from '@ember/service'; +import { type Registry as Services, service } from '@ember/service'; import EmberPageTitleService from 'ember-page-title/services/page-title'; export default class PageTitleService extends EmberPageTitleService { - @service headData; + @service declare headData: Services['head-data']; - titleDidUpdate(pageTitle) { + titleDidUpdate(pageTitle: string): void { this.headData.pageTitle = pageTitle; } } + +declare module '@ember/service' { + interface Registry { + 'page-title': PageTitleService; + } +} diff --git a/app/utils/format-url.js b/app/utils/format-url.ts similarity index 79% rename from app/utils/format-url.js rename to app/utils/format-url.ts index 374a8a1e6..09787d193 100644 --- a/app/utils/format-url.js +++ b/app/utils/format-url.ts @@ -1,4 +1,4 @@ -export function formatURL(url) { +export function formatURL(url: string): string { if (url.includes('#')) { return url.replace(/([^/])#(.*)/, '$1/#$2'); } diff --git a/app/utils/highcharts/area-spline-chart.js b/app/utils/highcharts/area-spline-chart.ts similarity index 67% rename from app/utils/highcharts/area-spline-chart.js rename to app/utils/highcharts/area-spline-chart.ts index 043f80a25..2095f0852 100644 --- a/app/utils/highcharts/area-spline-chart.js +++ b/app/utils/highcharts/area-spline-chart.ts @@ -3,15 +3,34 @@ */ import { tracked } from '@glimmer/tracking'; +export type Chart = { + categories: string[]; + subtitle?: string; + title: string; +}; + +export type RawData = { + color: string; + label: string; + values: number[]; +}[]; + +type Series = { + color: string; + data: number[]; + name: string; +}[]; + export default class AreaSplineChart { - @tracked chart; - @tracked rawData; + @tracked chart: Chart; + @tracked rawData?: RawData; - constructor({ chart, rawData }) { + constructor({ chart, rawData }: { chart: Chart; rawData: RawData }) { this.chart = chart; this.rawData = rawData; } + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type get highchartsOptions() { const { chart, isLegendEnabled, series } = this; @@ -55,19 +74,19 @@ export default class AreaSplineChart { }; } - get isLegendEnabled() { + get isLegendEnabled(): boolean { const { series } = this; return series.length > 1; } - get series() { + get series(): Series { return createSeries(this.rawData); } } -function createSeries(rawData = []) { - const data = []; +function createSeries(rawData: RawData = []): Series { + const data: Series = []; rawData.forEach((datum) => { const { color, label, values } = datum; diff --git a/app/utils/highcharts/horizontal-bar-chart.js b/app/utils/highcharts/horizontal-bar-chart.ts similarity index 67% rename from app/utils/highcharts/horizontal-bar-chart.js rename to app/utils/highcharts/horizontal-bar-chart.ts index b1470af1f..d0ff7335a 100644 --- a/app/utils/highcharts/horizontal-bar-chart.js +++ b/app/utils/highcharts/horizontal-bar-chart.ts @@ -3,15 +3,34 @@ */ import { tracked } from '@glimmer/tracking'; +export type Chart = { + categories: string[]; + subtitle?: string; + title: string; +}; + +export type RawData = { + color: string; + label: string; + values: number[]; +}[]; + +type Series = { + color: string; + data: number[]; + name: string; +}[]; + export default class HorizontalBarChart { - @tracked chart; - @tracked rawData; + @tracked chart: Chart; + @tracked rawData?: RawData; - constructor({ chart, rawData }) { + constructor({ chart, rawData }: { chart: Chart; rawData: RawData }) { this.chart = chart; this.rawData = rawData; } + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type get highchartsOptions() { const { chart, isLegendEnabled, series } = this; @@ -56,19 +75,19 @@ export default class HorizontalBarChart { }; } - get isLegendEnabled() { + get isLegendEnabled(): boolean { const { series } = this; return series.length > 1; } - get series() { + get series(): Series { return createSeries(this.rawData); } } -function createSeries(rawData = []) { - const data = []; +function createSeries(rawData: RawData = []): Series { + const data: Series = []; rawData.forEach((datum) => { const { color, label, values } = datum; diff --git a/app/utils/highcharts/index.js b/app/utils/highcharts/index.ts similarity index 100% rename from app/utils/highcharts/index.js rename to app/utils/highcharts/index.ts diff --git a/app/utils/highcharts/pie-chart.js b/app/utils/highcharts/pie-chart.ts similarity index 60% rename from app/utils/highcharts/pie-chart.js rename to app/utils/highcharts/pie-chart.ts index 130e05f5c..210003c47 100644 --- a/app/utils/highcharts/pie-chart.js +++ b/app/utils/highcharts/pie-chart.ts @@ -3,15 +3,37 @@ */ import { tracked } from '@glimmer/tracking'; +export type Chart = { + subtitle?: string; + title: string; +}; + +export type RawData = { + color: string; + label: string; + value: number; +}[]; + +type Series = [ + { + colors: string[]; + data: { + name: string; + y: number; + }[]; + }, +]; + export default class PieChart { - @tracked chart; - @tracked rawData; + @tracked chart: Chart; + @tracked rawData?: RawData; - constructor({ chart, rawData }) { + constructor({ chart, rawData }: { chart: Chart; rawData: RawData }) { this.chart = chart; this.rawData = rawData; } + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type get highchartsOptions() { const { chart, series } = this; @@ -37,14 +59,17 @@ export default class PieChart { }; } - get series() { + get series(): Series { return createSeries(this.rawData); } } -function createSeries(rawData = []) { - const colors = []; - const data = []; +function createSeries(rawData: RawData = []): Series { + const colors: string[] = []; + const data: { + name: string; + y: number; + }[] = []; const total = rawData.reduce((accumulator, datum) => { const { value } = datum; diff --git a/app/utils/highcharts/spline-chart.js b/app/utils/highcharts/spline-chart.ts similarity index 68% rename from app/utils/highcharts/spline-chart.js rename to app/utils/highcharts/spline-chart.ts index 1333bfd19..8e8f15dac 100644 --- a/app/utils/highcharts/spline-chart.js +++ b/app/utils/highcharts/spline-chart.ts @@ -3,15 +3,34 @@ */ import { tracked } from '@glimmer/tracking'; +export type Chart = { + categories: string[]; + subtitle?: string; + title: string; +}; + +export type RawData = { + color: string; + label: string; + values: (number | null)[]; +}[]; + +type Series = { + color: string; + data: (number | null)[]; + name: string; +}[]; + export default class SplineChart { - @tracked chart; - @tracked rawData; + @tracked chart: Chart; + @tracked rawData?: RawData; - constructor({ chart, rawData }) { + constructor({ chart, rawData }: { chart: Chart; rawData: RawData }) { this.chart = chart; this.rawData = rawData; } + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type get highchartsOptions() { const { chart, isLegendEnabled, series } = this; @@ -64,19 +83,19 @@ export default class SplineChart { }; } - get isLegendEnabled() { + get isLegendEnabled(): boolean { const { series } = this; return series.length > 1; } - get series() { + get series(): Series { return createSeries(this.rawData); } } -function createSeries(rawData = []) { - const data = []; +function createSeries(rawData: RawData = []): Series { + const data: Series = []; rawData.forEach((datum) => { const { color, label, values } = datum; diff --git a/app/utils/highcharts/vertical-bar-chart.js b/app/utils/highcharts/vertical-bar-chart.ts similarity index 64% rename from app/utils/highcharts/vertical-bar-chart.js rename to app/utils/highcharts/vertical-bar-chart.ts index 564a8696a..253dfb052 100644 --- a/app/utils/highcharts/vertical-bar-chart.js +++ b/app/utils/highcharts/vertical-bar-chart.ts @@ -3,15 +3,34 @@ */ import { tracked } from '@glimmer/tracking'; +export type Chart = { + categories?: string[]; + subtitle?: string; + title: string; +}; + +export type RawData = { + color: string; + label: string; + values: (number | { name: string; y: number })[]; +}[]; + +type Series = { + color: string; + data: (number | { name: string; y: number })[]; + name: string; +}[]; + export default class VerticalBarChart { - @tracked chart; - @tracked rawData; + @tracked chart: Chart; + @tracked rawData?: RawData; - constructor({ chart, rawData }) { + constructor({ chart, rawData }: { chart: Chart; rawData: RawData }) { this.chart = chart; this.rawData = rawData; } + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type get highchartsOptions() { const { chart, isLegendEnabled, series } = this; @@ -55,19 +74,19 @@ export default class VerticalBarChart { }; } - get isLegendEnabled() { + get isLegendEnabled(): boolean { const { series } = this; return series.length > 1; } - get series() { + get series(): Series { return createSeries(this.rawData); } } -function createSeries(rawData = []) { - const data = []; +function createSeries(rawData: RawData = []): Series { + const data: Series = []; rawData.forEach((datum) => { const { color, label, values } = datum; diff --git a/app/utils/navigate-tabs.js b/app/utils/navigate-tabs.ts similarity index 73% rename from app/utils/navigate-tabs.js rename to app/utils/navigate-tabs.ts index f55f5c35f..9b43e59ca 100644 --- a/app/utils/navigate-tabs.js +++ b/app/utils/navigate-tabs.ts @@ -3,9 +3,9 @@ const ALLOWED_KEYS = { ARROW_LEFT_IE11: 'Left', ARROW_RIGHT: 'ArrowRight', ARROW_RIGHT_IE11: 'Right', -}; +} as const; -export function getTabIdIncrement(event) { +export function getTabIdIncrement(event: { key: string }): -1 | 1 | undefined { switch (event.key) { case ALLOWED_KEYS.ARROW_LEFT: case ALLOWED_KEYS.ARROW_LEFT_IE11: { @@ -21,6 +21,6 @@ export function getTabIdIncrement(event) { return undefined; } -export function modulus(m, n) { +export function modulus(m: number, n: number): number { return ((m % n) + n) % n; } diff --git a/app/utils/releases/lts.js b/app/utils/releases/lts.ts similarity index 95% rename from app/utils/releases/lts.js rename to app/utils/releases/lts.ts index 7f1b397ed..8cd41c37b 100644 --- a/app/utils/releases/lts.js +++ b/app/utils/releases/lts.ts @@ -1,6 +1,12 @@ +type Release = { + isActive: boolean; + promotionDate: Date; + version: string; +}; + // promotion date should be the day of the release of the following ember minor version // you can run `npm info ember-source time` to see a list -export const emberLtsReleases = [ +export const emberLtsReleases: Release[] = [ { version: '6.12', promotionDate: new Date('2026-05-12'), @@ -108,7 +114,7 @@ export const emberLtsReleases = [ }, ]; -export const dataLtsReleases = [ +export const dataLtsReleases: Release[] = [ { version: '5.3', promotionDate: new Date('2023-12-10'), diff --git a/app/utils/replace-links.js b/app/utils/replace-links.ts similarity index 63% rename from app/utils/replace-links.js rename to app/utils/replace-links.ts index 9ceb21b35..d174c665c 100644 --- a/app/utils/replace-links.js +++ b/app/utils/replace-links.ts @@ -4,14 +4,14 @@ const legacyExternalLinks = new Set([ 'https://emberjs.com/deprecations', ]); -function isExternalLink(url) { +function isExternalLink(url: string): boolean { const isExternalLink = !url.startsWith('https://emberjs.com'); const isLegacyExternalLink = legacyExternalLinks.has(url); return isExternalLink || isLegacyExternalLink; } -function replaceInternalLinks(url) { +function replaceInternalLinks(url: string): string { if (isExternalLink(url)) { return url; } @@ -24,16 +24,34 @@ function replaceInternalLinks(url) { .replace(/\/builds$/, '/releases'); } -export function replaceLinks(links) { +type SimpleDivider = { + type: 'divider'; +}; + +type SimpleLink = { + href: string; + name: string; + type: 'link'; +}; + +type SimpleDropdown = { + items: Link[]; + name: string; + type: 'dropdown'; +}; + +export type Link = SimpleDivider | SimpleDropdown | SimpleLink; + +export function replaceLinks(links: Link[]): Link[] { return links.map((group) => { - if (group.items) { + if (group.type === 'dropdown') { return { ...group, items: replaceLinks(group.items), }; } - if (group.href) { + if (group.type === 'link') { return { ...group, href: replaceInternalLinks(group.href), diff --git a/app/utils/routes/index.ts b/app/utils/routes/index.ts new file mode 100644 index 000000000..41a22704d --- /dev/null +++ b/app/utils/routes/index.ts @@ -0,0 +1,14 @@ +/* + https://docs.ember-cli-typescript.com/cookbook/working-with-route-models +*/ +import type Route from '@ember/routing/route'; + +/** + Get the resolved type of an item. + - If the item is a promise, the result will be the resolved value type + - If the item is not a promise, the result will just be the type of the item + */ +type Resolved

= P extends Promise ? T : P; + +/** Get the resolved model value from a route. */ +export type ModelFrom = Resolved>; diff --git a/app/utils/surveys/2016.js b/app/utils/surveys/2016.ts similarity index 99% rename from app/utils/surveys/2016.js rename to app/utils/surveys/2016.ts index e196c155b..d5ec7e01f 100644 --- a/app/utils/surveys/2016.js +++ b/app/utils/surveys/2016.ts @@ -14,6 +14,7 @@ const chartHowlong = new VerticalBarChart({ '3–6 months', 'Less than 3 months', ], + title: '', }, rawData: [ diff --git a/app/utils/surveys/2017.js b/app/utils/surveys/2017.ts similarity index 100% rename from app/utils/surveys/2017.js rename to app/utils/surveys/2017.ts diff --git a/app/utils/surveys/2018.js b/app/utils/surveys/2018.ts similarity index 100% rename from app/utils/surveys/2018.js rename to app/utils/surveys/2018.ts diff --git a/app/utils/surveys/2019.js b/app/utils/surveys/2019.ts similarity index 100% rename from app/utils/surveys/2019.js rename to app/utils/surveys/2019.ts diff --git a/app/utils/surveys/2020.js b/app/utils/surveys/2020.ts similarity index 100% rename from app/utils/surveys/2020.js rename to app/utils/surveys/2020.ts diff --git a/app/utils/surveys/2022.js b/app/utils/surveys/2022.ts similarity index 100% rename from app/utils/surveys/2022.js rename to app/utils/surveys/2022.ts diff --git a/app/utils/teams/in-team.js b/app/utils/teams/in-team.js deleted file mode 100644 index 51ef6391b..000000000 --- a/app/utils/teams/in-team.js +++ /dev/null @@ -1,5 +0,0 @@ -export function inTeam(team) { - return (teamMember) => { - return (teamMember.teams ?? []).includes(team); - }; -} diff --git a/app/utils/teams/in-team.ts b/app/utils/teams/in-team.ts new file mode 100644 index 000000000..169dd28d1 --- /dev/null +++ b/app/utils/teams/in-team.ts @@ -0,0 +1,9 @@ +type TeamMember = { + teams?: string[]; +}; + +export function inTeam(team: string): (teamMember: TeamMember) => boolean { + return (teamMember) => { + return (teamMember.teams ?? []).includes(team); + }; +} diff --git a/ember-cli-build.js b/ember-cli-build.js index 1ee8ca851..4fb06b4a5 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -14,6 +14,10 @@ module.exports = function (defaults) { }, }, + 'ember-cli-babel': { + enableTypeScriptTransform: true, + }, + 'ember-composable-helpers': { only: ['filter-by', 'reject-by', 'sort-by'], }, diff --git a/eslint.config.mjs b/eslint.config.mjs index 0f66ad6f4..f574cd00f 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -85,6 +85,18 @@ export default defineConfig([ parser: eslintPluginEmber.parser, parserOptions: parserOptions.esm.ts, }, + rules: { + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/explicit-function-return-type': 'error', + '@typescript-eslint/no-empty-object-type': [ + 'error', + { + allowInterfaces: 'always', + allowObjectTypes: 'always', + }, + ], + '@typescript-eslint/no-import-type-side-effects': 'error', + }, }, { ...eslintPluginQunit.configs.recommended, diff --git a/package.json b/package.json index d19b7ee13..6e016e934 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "build": "ember build --environment=production", "format": "prettier . --cache --write", "lint": "concurrently \"pnpm:lint:*(!fix)\" --names \"lint:\"", - "lint:css": "stylelint \"**/*.css\" --cache", + "lint:css": "stylelint \"app/**/*.css\" --cache", "lint:css:fix": "stylelint \"app/**/*.css\" --fix", "lint:fix": "concurrently \"pnpm:lint:*:fix\" --names \"fix:\" && pnpm format", "lint:format": "prettier . --cache --check", @@ -31,10 +31,15 @@ "@babel/core": "^7.29.7", "@babel/eslint-parser": "^7.29.7", "@babel/plugin-proposal-decorators": "^7.29.7", + "@ember-data-types/adapter": "~5.7.0", + "@ember-data-types/model": "~5.7.0", + "@ember-data-types/serializer": "~5.7.0", + "@ember-data-types/store": "~5.7.0", "@ember/app-tsconfig": "^2.0.0", "@ember/optional-features": "^3.0.0", "@ember/string": "^4.0.1", "@ember/test-helpers": "^5.4.3", + "@embroider/config-meta-loader": "^1.0.0", "@eslint/js": "^9.39.5", "@glimmer/component": "^2.1.1", "@glimmer/tracking": "^1.1.2", @@ -46,6 +51,7 @@ "@percy/cli": "^1.32.7", "@percy/ember": "^5.0.2", "@types/qunit": "^2.19.14", + "@warp-drive-types/core-types": "~5.7.0", "algoliasearch": "^3.35.1", "blurhash": "^2.0.5", "broccoli-asset-rev": "^3.0.0", @@ -71,6 +77,7 @@ "ember-cli-terser": "^4.0.2", "ember-data": "~5.7.0", "ember-data-fastboot": "^0.1.2", + "ember-data-types": "~5.7.0", "ember-fetch": "^8.1.2", "ember-href-to": "^5.1.1", "ember-inflector": "^6.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6110b29b3..895dffe53 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,6 +24,18 @@ importers: '@babel/plugin-proposal-decorators': specifier: ^7.29.7 version: 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + '@ember-data-types/adapter': + specifier: ~5.7.0 + version: 5.7.0 + '@ember-data-types/model': + specifier: ~5.7.0 + version: 5.7.0 + '@ember-data-types/serializer': + specifier: ~5.7.0 + version: 5.7.0 + '@ember-data-types/store': + specifier: ~5.7.0 + version: 5.7.0 '@ember/app-tsconfig': specifier: ^2.0.0 version: 2.0.0 @@ -36,6 +48,9 @@ importers: '@ember/test-helpers': specifier: ^5.4.3 version: 5.4.3(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + '@embroider/config-meta-loader': + specifier: ^1.0.0 + version: 1.0.0 '@eslint/js': specifier: ^9.39.5 version: 9.39.5 @@ -69,6 +84,9 @@ importers: '@types/qunit': specifier: ^2.19.14 version: 2.19.14 + '@warp-drive-types/core-types': + specifier: ~5.7.0 + version: 5.7.0 algoliasearch: specifier: ^3.35.1 version: 3.35.1(supports-color@10.2.2) @@ -144,6 +162,9 @@ importers: ember-data-fastboot: specifier: ^0.1.2 version: 0.1.2(patch_hash=32da3248de941d97c233aeef4cd09b59d69a331edadf1a2f3840f1ed348ab371)(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2) + ember-data-types: + specifier: ~5.7.0 + version: 5.7.0 ember-fetch: specifier: ^8.1.2 version: 8.1.2(supports-color@10.2.2) @@ -917,6 +938,18 @@ packages: peerDependencies: postcss-selector-parser: ^7.1.1 + '@ember-data-types/adapter@5.7.0': + resolution: {integrity: sha512-hIPaB8N/VOWC13t9aIJWbAHkInDp5gInhNu2jGWlweHGecDnUkobosG4v7dbD3IXdPjFNHoIR9AcqWZQ99xg7g==} + + '@ember-data-types/model@5.7.0': + resolution: {integrity: sha512-S20lRMWLJpH9zQwgZQyvLLLgC1kEvhAikyfOUmPQe2L+3nLDAVjdkJHSU+dh60RRdgyDvEYeNFGftghX7dzKoA==} + + '@ember-data-types/serializer@5.7.0': + resolution: {integrity: sha512-DiB+4BxvddZVxfqpHo1pcz+7wD+aETX/RVBTy0v7f4o6RoQk7FDpcP3M1zpHWwFvxnt2e4ONVoYrl8x8rDWuEw==} + + '@ember-data-types/store@5.7.0': + resolution: {integrity: sha512-To+Ld0xmYZUtyidUXfPBl2kp2RQ89gfdpIcyc4qv0n0Fa5K76iDvIE5BORoslMEYi5jClPg6JjHnrciEhnRAUg==} + '@ember-data/adapter@5.7.0': resolution: {integrity: sha512-H0EWf7CNlpxwJxygFA4qoRNdpuHHwxXrY94YXdd5kh/wDUn5vNke//tHiVPXJJPAM7Ndgsq4gw3mSDP1Uhg1hQ==} @@ -1022,6 +1055,10 @@ packages: resolution: {integrity: sha512-GYbaiC1v9inbiwVg5s+Sd14Jc66NYxg23mEOocgWAZFCtOfhMnRLaLAA6SytW76myVVYImGHX5PFK4PVuH2yng==} engines: {node: 12.* || 14.* || >= 16} + '@embroider/config-meta-loader@1.0.0': + resolution: {integrity: sha512-qznkdjgEGPe6NM94hZNXvOm/WhrJwBh8FtSQZ+nGjh9TOjY42tOiTEevFuM0onNXUn6bpdGzmjwKo2xY2jxQxQ==} + engines: {node: 12.* || 14.* || >= 16} + '@embroider/macros@1.20.2': resolution: {integrity: sha512-WJWSkG9vIL0s93vKwtNFqqAOCOflNkWNpqsC7VAqXeeTKNpCc7wtdOhPkNGJpb52CEt7vlQ5R/zMyCfGAB7MEA==} engines: {node: 12.* || 14.* || >= 16} @@ -2179,6 +2216,9 @@ packages: '@vscode/l10n@0.0.18': resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} + '@warp-drive-types/core-types@5.7.0': + resolution: {integrity: sha512-3FymVgRr1/FcWFyAgY+619rR69gX5eeGsbZzyg0+XLHiYg3mzG+yFZomphEYraAokijSW9dE/Uvx75GzidgWbA==} + '@warp-drive/build-config@5.7.0': resolution: {integrity: sha512-lCltr4xG9jQmBRlM8+gMJ06o3pnOHs7uDFdIX36dIczKCFjfTvaSVbYf+n/VLEAT4GyaMoQU11xkY1zHa5XucA==} @@ -4246,6 +4286,9 @@ packages: resolution: {integrity: sha512-aPb318FGngnG0xbDc3/oz2L7tqgFj1qLZNdiqMI1TRMu9FL4zmrxw5WAGHyRt2ECSNssrbme/Zb8WcNhWTlHkA==} engines: {node: ^4.5 || 6.* || >= 7.*} + ember-data-types@5.7.0: + resolution: {integrity: sha512-zpbyWMCeVaVeH0UZ/yLTVITdVVVll/D55BUgs8J6m4OOr/2iKN3HGGdTJbVEfsTIzg2X4x04zmnS08QDRveA2w==} + ember-data@5.7.0: resolution: {integrity: sha512-KPs+p5/F/YSIFsc0hYg+kaER8XoMhAzy+gOVAJhdtbFrhn3oftTogcAMTGo/glUpXnzwt8dSkN+GfNMWMPmSlw==} peerDependencies: @@ -9679,6 +9722,14 @@ snapshots: dependencies: postcss-selector-parser: 7.1.5 + '@ember-data-types/adapter@5.7.0': {} + + '@ember-data-types/model@5.7.0': {} + + '@ember-data-types/serializer@5.7.0': {} + + '@ember-data-types/store@5.7.0': {} + '@ember-data/adapter@5.7.0(@babel/core@7.29.7(supports-color@10.2.2))(@glint/template@1.9.0)(supports-color@10.2.2)': dependencies: '@ember/edition-utils': 1.2.0 @@ -9911,6 +9962,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@embroider/config-meta-loader@1.0.0': {} + '@embroider/macros@1.20.2(@babel/core@7.29.7(supports-color@10.2.2))(@glint/template@1.9.0)(supports-color@10.2.2)': dependencies: '@embroider/shared-internals': 3.0.2(supports-color@10.2.2) @@ -11480,6 +11533,8 @@ snapshots: '@vscode/l10n@0.0.18': {} + '@warp-drive-types/core-types@5.7.0': {} + '@warp-drive/build-config@5.7.0(@babel/core@7.29.7(supports-color@10.2.2))(@glint/template@1.9.0)(supports-color@10.2.2)': dependencies: '@embroider/addon-shim': 1.10.3(supports-color@10.2.2) @@ -14583,6 +14638,8 @@ snapshots: - '@babel/core' - supports-color + ember-data-types@5.7.0: {} + ember-data@5.7.0(@babel/core@7.29.7(supports-color@10.2.2))(@ember/test-helpers@5.4.3(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@ember/test-waiters@4.1.2(supports-color@10.2.2))(@glint/template@1.9.0)(ember-inflector@6.0.0(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(qunit@2.26.0)(supports-color@10.2.2): dependencies: '@ember-data/adapter': 5.7.0(@babel/core@7.29.7(supports-color@10.2.2))(@glint/template@1.9.0)(supports-color@10.2.2) diff --git a/tests/acceptance/about/legal-test.js b/tests/acceptance/about/legal-test.ts similarity index 100% rename from tests/acceptance/about/legal-test.js rename to tests/acceptance/about/legal-test.ts diff --git a/tests/acceptance/browser-support-test.js b/tests/acceptance/browser-support-test.ts similarity index 100% rename from tests/acceptance/browser-support-test.js rename to tests/acceptance/browser-support-test.ts diff --git a/tests/acceptance/community-test.js b/tests/acceptance/community-test.ts similarity index 100% rename from tests/acceptance/community-test.js rename to tests/acceptance/community-test.ts diff --git a/tests/acceptance/community/black-lives-matter-test.js b/tests/acceptance/community/black-lives-matter-test.ts similarity index 100% rename from tests/acceptance/community/black-lives-matter-test.js rename to tests/acceptance/community/black-lives-matter-test.ts diff --git a/tests/acceptance/community/meetups-getting-started-test.js b/tests/acceptance/community/meetups-getting-started-test.ts similarity index 100% rename from tests/acceptance/community/meetups-getting-started-test.js rename to tests/acceptance/community/meetups-getting-started-test.ts diff --git a/tests/acceptance/community/meetups-test.js b/tests/acceptance/community/meetups-test.ts similarity index 100% rename from tests/acceptance/community/meetups-test.js rename to tests/acceptance/community/meetups-test.ts diff --git a/tests/acceptance/community/meetups/assets-test.js b/tests/acceptance/community/meetups/assets-test.ts similarity index 100% rename from tests/acceptance/community/meetups/assets-test.js rename to tests/acceptance/community/meetups/assets-test.ts diff --git a/tests/acceptance/editions-test.js b/tests/acceptance/editions-test.ts similarity index 100% rename from tests/acceptance/editions-test.js rename to tests/acceptance/editions-test.ts diff --git a/tests/acceptance/editions/octane-test.js b/tests/acceptance/editions/octane-test.ts similarity index 100% rename from tests/acceptance/editions/octane-test.js rename to tests/acceptance/editions/octane-test.ts diff --git a/tests/acceptance/ember-users-test.js b/tests/acceptance/ember-users-test.ts similarity index 100% rename from tests/acceptance/ember-users-test.js rename to tests/acceptance/ember-users-test.ts diff --git a/tests/acceptance/guidelines-test.js b/tests/acceptance/guidelines-test.ts similarity index 100% rename from tests/acceptance/guidelines-test.js rename to tests/acceptance/guidelines-test.ts diff --git a/tests/acceptance/index-test.js b/tests/acceptance/index-test.ts similarity index 87% rename from tests/acceptance/index-test.js rename to tests/acceptance/index-test.ts index 204233fc2..2e67493b2 100644 --- a/tests/acceptance/index-test.js +++ b/tests/acceptance/index-test.ts @@ -5,7 +5,10 @@ import { setupApplicationTest } from 'ember-qunit'; import { assertPageTitle } from 'ember-website/tests/helpers/page-title'; import { module, test } from 'qunit'; -function assertParentNavItems(assert, expectedOutput = []) { +function assertParentNavItems( + assert: Assert, + expectedOutput: { label: string }[] = [], +): void { const parentNavItems = findAll('.navbar-list-item'); assert.strictEqual( @@ -22,13 +25,17 @@ function assertParentNavItems(assert, expectedOutput = []) { assert .dom(parentNavItem) .hasText( - expectedOutput[index].label, + expectedOutput[index]!.label, `The label for the parent navigation item is correct. (${index + 1})`, ); }); } -function assertChildNavItems(assert, expectedOutput = [], scope = document) { +function assertChildNavItems( + assert: Assert, + expectedOutput: { href: string; label: string }[] = [], + scope: Document | Element = document, +): void { const childNavItems = scope.querySelectorAll( '.navbar-dropdown-list-item-link', ); @@ -47,12 +54,12 @@ function assertChildNavItems(assert, expectedOutput = [], scope = document) { assert .dom(childNavItem) .hasText( - expectedOutput[index].label, + expectedOutput[index]!.label, `The label for the child navigation item is correct. (${index + 1})`, ) .hasAttribute( 'href', - expectedOutput[index].href, + expectedOutput[index]!.href, `The URL for the child navigation item is correct. (${index + 1})`, ); }); @@ -111,7 +118,7 @@ module('Acceptance | index', function (hooks) { assertChildNavItems(assert, [], parentNavItems[3]); - await click(parentNavItems[3].querySelector('button')); + await click(parentNavItems[3]!.querySelector('button')!); assertChildNavItems( assert, @@ -128,11 +135,11 @@ module('Acceptance | index', function (hooks) { ); // Navigate to another page - const childNavItems = parentNavItems[3].querySelectorAll( + const childNavItems = parentNavItems[3]!.querySelectorAll( '.navbar-dropdown-list-item-link', ); - await click(childNavItems[0]); + await click(childNavItems[0]!); assert.strictEqual( currentURL(), diff --git a/tests/acceptance/learn-test.js b/tests/acceptance/learn-test.ts similarity index 100% rename from tests/acceptance/learn-test.js rename to tests/acceptance/learn-test.ts diff --git a/tests/acceptance/learn/examples-test.js b/tests/acceptance/learn/examples-test.ts similarity index 100% rename from tests/acceptance/learn/examples-test.js rename to tests/acceptance/learn/examples-test.ts diff --git a/tests/acceptance/logos-test.js b/tests/acceptance/logos-test.ts similarity index 100% rename from tests/acceptance/logos-test.js rename to tests/acceptance/logos-test.ts diff --git a/tests/acceptance/mascots-test.js b/tests/acceptance/mascots-test.ts similarity index 100% rename from tests/acceptance/mascots-test.js rename to tests/acceptance/mascots-test.ts diff --git a/tests/acceptance/mascots/commission-sent-test.js b/tests/acceptance/mascots/commission-sent-test.ts similarity index 100% rename from tests/acceptance/mascots/commission-sent-test.js rename to tests/acceptance/mascots/commission-sent-test.ts diff --git a/tests/acceptance/mascots/commission-test.js b/tests/acceptance/mascots/commission-test.ts similarity index 100% rename from tests/acceptance/mascots/commission-test.js rename to tests/acceptance/mascots/commission-test.ts diff --git a/tests/acceptance/mascots/faq-test.js b/tests/acceptance/mascots/faq-test.ts similarity index 100% rename from tests/acceptance/mascots/faq-test.js rename to tests/acceptance/mascots/faq-test.ts diff --git a/tests/acceptance/mascots/payment-sent-test.js b/tests/acceptance/mascots/payment-sent-test.ts similarity index 100% rename from tests/acceptance/mascots/payment-sent-test.js rename to tests/acceptance/mascots/payment-sent-test.ts diff --git a/tests/acceptance/mascots/payment-test.js b/tests/acceptance/mascots/payment-test.ts similarity index 100% rename from tests/acceptance/mascots/payment-test.js rename to tests/acceptance/mascots/payment-test.ts diff --git a/tests/acceptance/not-found-test.js b/tests/acceptance/not-found-test.ts similarity index 100% rename from tests/acceptance/not-found-test.js rename to tests/acceptance/not-found-test.ts diff --git a/tests/acceptance/releases-test.js b/tests/acceptance/releases-test.ts similarity index 100% rename from tests/acceptance/releases-test.js rename to tests/acceptance/releases-test.ts diff --git a/tests/acceptance/releases/beta-test.js b/tests/acceptance/releases/beta-test.ts similarity index 100% rename from tests/acceptance/releases/beta-test.js rename to tests/acceptance/releases/beta-test.ts diff --git a/tests/acceptance/releases/canary-test.js b/tests/acceptance/releases/canary-test.ts similarity index 100% rename from tests/acceptance/releases/canary-test.js rename to tests/acceptance/releases/canary-test.ts diff --git a/tests/acceptance/releases/lts-test.js b/tests/acceptance/releases/lts-test.ts similarity index 100% rename from tests/acceptance/releases/lts-test.js rename to tests/acceptance/releases/lts-test.ts diff --git a/tests/acceptance/releases/release-test.js b/tests/acceptance/releases/release-test.ts similarity index 100% rename from tests/acceptance/releases/release-test.js rename to tests/acceptance/releases/release-test.ts diff --git a/tests/acceptance/security-test.js b/tests/acceptance/security-test.ts similarity index 100% rename from tests/acceptance/security-test.js rename to tests/acceptance/security-test.ts diff --git a/tests/acceptance/sponsors-test.js b/tests/acceptance/sponsors-test.ts similarity index 100% rename from tests/acceptance/sponsors-test.js rename to tests/acceptance/sponsors-test.ts diff --git a/tests/acceptance/survey-test.js b/tests/acceptance/survey-test.ts similarity index 100% rename from tests/acceptance/survey-test.js rename to tests/acceptance/survey-test.ts diff --git a/tests/acceptance/survey/2016-test.js b/tests/acceptance/survey/2016-test.ts similarity index 100% rename from tests/acceptance/survey/2016-test.js rename to tests/acceptance/survey/2016-test.ts diff --git a/tests/acceptance/survey/2017-test.js b/tests/acceptance/survey/2017-test.ts similarity index 100% rename from tests/acceptance/survey/2017-test.js rename to tests/acceptance/survey/2017-test.ts diff --git a/tests/acceptance/survey/2018-test.js b/tests/acceptance/survey/2018-test.ts similarity index 100% rename from tests/acceptance/survey/2018-test.js rename to tests/acceptance/survey/2018-test.ts diff --git a/tests/acceptance/survey/2019-test.js b/tests/acceptance/survey/2019-test.ts similarity index 100% rename from tests/acceptance/survey/2019-test.js rename to tests/acceptance/survey/2019-test.ts diff --git a/tests/acceptance/survey/2020-test.js b/tests/acceptance/survey/2020-test.ts similarity index 100% rename from tests/acceptance/survey/2020-test.js rename to tests/acceptance/survey/2020-test.ts diff --git a/tests/acceptance/survey/2021-test.js b/tests/acceptance/survey/2021-test.ts similarity index 100% rename from tests/acceptance/survey/2021-test.js rename to tests/acceptance/survey/2021-test.ts diff --git a/tests/acceptance/survey/2022-test.js b/tests/acceptance/survey/2022-test.ts similarity index 100% rename from tests/acceptance/survey/2022-test.js rename to tests/acceptance/survey/2022-test.ts diff --git a/tests/acceptance/team-redirect-test.js b/tests/acceptance/team-redirect-test.ts similarity index 100% rename from tests/acceptance/team-redirect-test.js rename to tests/acceptance/team-redirect-test.ts diff --git a/tests/acceptance/teams-test.js b/tests/acceptance/teams-test.ts similarity index 100% rename from tests/acceptance/teams-test.js rename to tests/acceptance/teams-test.ts diff --git a/tests/helpers/highcharts.js b/tests/helpers/highcharts.ts similarity index 60% rename from tests/helpers/highcharts.js rename to tests/helpers/highcharts.ts index 365a6d69a..35da86953 100644 --- a/tests/helpers/highcharts.js +++ b/tests/helpers/highcharts.ts @@ -1,10 +1,12 @@ import { findAll, waitUntil } from '@ember/test-helpers'; -export async function waitUntilAllChartsAreDrawn() { +export async function waitUntilAllChartsAreDrawn(): Promise { await waitUntil(() => { let areAllChartsSettled = true; - findAll('[data-test-chart]').forEach(({ dataset }) => { + findAll('[data-test-chart]').forEach((element) => { + const { dataset } = element as HTMLElement; + if (dataset.renderState !== 'settled') { areAllChartsSettled = false; } diff --git a/tests/helpers/index.js b/tests/helpers/index.ts similarity index 57% rename from tests/helpers/index.js rename to tests/helpers/index.ts index ab04c162d..cd12a7e41 100644 --- a/tests/helpers/index.js +++ b/tests/helpers/index.ts @@ -2,38 +2,32 @@ import { setupApplicationTest as upstreamSetupApplicationTest, setupRenderingTest as upstreamSetupRenderingTest, setupTest as upstreamSetupTest, + type SetupTestOptions, } from 'ember-qunit'; // This file exists to provide wrappers around ember-qunit's // test setup functions. This way, you can easily extend the setup that is // needed per test type. -function setupApplicationTest(hooks, options) { +function setupApplicationTest( + hooks: NestedHooks, + options?: SetupTestOptions, +): void { upstreamSetupApplicationTest(hooks, options); // Additional setup for application tests can be done here. - // - // For example, if you need an authenticated session for each - // application test, you could do: - // - // hooks.beforeEach(async function () { - // await authenticateSession(); // ember-simple-auth - // }); - // - // This is also a good place to call test setup functions coming - // from other addons: - // - // setupIntl(hooks, 'en-us'); // ember-intl - // setupMirage(hooks); // ember-cli-mirage } -function setupRenderingTest(hooks, options) { +function setupRenderingTest( + hooks: NestedHooks, + options?: SetupTestOptions, +): void { upstreamSetupRenderingTest(hooks, options); // Additional setup for rendering tests can be done here. } -function setupTest(hooks, options) { +function setupTest(hooks: NestedHooks, options?: SetupTestOptions): void { upstreamSetupTest(hooks, options); // Additional setup for unit tests can be done here. diff --git a/tests/helpers/page-title.js b/tests/helpers/page-title.ts similarity index 84% rename from tests/helpers/page-title.js rename to tests/helpers/page-title.ts index 754880f3a..2790310af 100644 --- a/tests/helpers/page-title.js +++ b/tests/helpers/page-title.ts @@ -1,6 +1,6 @@ import { getPageTitle } from 'ember-page-title/test-support'; -export function assertPageTitle(assert, expectedValue) { +export function assertPageTitle(assert: Assert, expectedValue: string): void { // Check the element assert.strictEqual( getPageTitle(), diff --git a/tests/integration/helpers/add-weeks-test.gjs b/tests/integration/helpers/add-weeks-test.gts similarity index 100% rename from tests/integration/helpers/add-weeks-test.gjs rename to tests/integration/helpers/add-weeks-test.gts diff --git a/tests/integration/helpers/format-date-time-test.gjs b/tests/integration/helpers/format-date-time-test.gts similarity index 100% rename from tests/integration/helpers/format-date-time-test.gjs rename to tests/integration/helpers/format-date-time-test.gts diff --git a/tests/integration/helpers/printf-test.gjs b/tests/integration/helpers/printf-test.gts similarity index 100% rename from tests/integration/helpers/printf-test.gjs rename to tests/integration/helpers/printf-test.gts diff --git a/tests/integration/helpers/qp-test.gts b/tests/integration/helpers/qp-test.gts new file mode 100644 index 000000000..117a7b6ba --- /dev/null +++ b/tests/integration/helpers/qp-test.gts @@ -0,0 +1,16 @@ +import { render } from '@ember/test-helpers'; +import { setupRenderingTest } from 'ember-qunit'; +import qp from 'ember-website/helpers/qp'; +import { module, test } from 'qunit'; + +module('Integration | Helper | qp', function (hooks) { + setupRenderingTest(hooks); + + test('it works', async function (assert) { + const key = 'uwu'; + + await render(<template>{{if (qp key) "true" "false"}}</template>); + + assert.dom().hasText('false'); + }); +}); diff --git a/tests/integration/modifiers/draw-chart-test.gjs b/tests/integration/modifiers/draw-chart-test.gts similarity index 100% rename from tests/integration/modifiers/draw-chart-test.gjs rename to tests/integration/modifiers/draw-chart-test.gts diff --git a/tests/test-helper.js b/tests/test-helper.ts similarity index 100% rename from tests/test-helper.js rename to tests/test-helper.ts diff --git a/tests/unit/adapters/application-test.js b/tests/unit/adapters/application-test.ts similarity index 78% rename from tests/unit/adapters/application-test.js rename to tests/unit/adapters/application-test.ts index b9c19c3d0..4b9ee4ac6 100644 --- a/tests/unit/adapters/application-test.js +++ b/tests/unit/adapters/application-test.ts @@ -1,11 +1,14 @@ import { setupTest } from 'ember-qunit'; +import type ApplicationAdapter from 'ember-website/adapters/application'; import { module, test } from 'qunit'; module('Unit | Adapter | application', function (hooks) { setupTest(hooks); test('urlForFindAll works', function (assert) { - const adapter = this.owner.lookup('adapter:application'); + const adapter = this.owner.lookup( + 'adapter:application', + ) as ApplicationAdapter; assert.strictEqual( adapter.urlForFindAll('project'), @@ -21,7 +24,9 @@ module('Unit | Adapter | application', function (hooks) { }); test('urlForFindRecord works', function (assert) { - const adapter = this.owner.lookup('adapter:application'); + const adapter = this.owner.lookup( + 'adapter:application', + ) as ApplicationAdapter; assert.strictEqual( adapter.urlForFindRecord('ember/release', 'project'), diff --git a/tests/unit/models/initiative-sponsor-test.ts b/tests/unit/models/initiative-sponsor-test.ts new file mode 100644 index 000000000..d8a46bec2 --- /dev/null +++ b/tests/unit/models/initiative-sponsor-test.ts @@ -0,0 +1,17 @@ +import type InitiativeSponsor from 'ember-website/models/initiative-sponsor'; +import { setupTest } from 'ember-website/tests/helpers'; +import { module, test } from 'qunit'; + +module('Unit | Model | initiative-sponsor', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord<InitiativeSponsor>( + 'initiative-sponsor', + {}, + ); + + assert.ok(model); + }); +}); diff --git a/tests/unit/models/meetup-test.ts b/tests/unit/models/meetup-test.ts new file mode 100644 index 000000000..92825491f --- /dev/null +++ b/tests/unit/models/meetup-test.ts @@ -0,0 +1,14 @@ +import type MeetupModel from 'ember-website/models/meetup'; +import { setupTest } from 'ember-website/tests/helpers'; +import { module, test } from 'qunit'; + +module('Unit | Model | meetup', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord<MeetupModel>('meetup', {}); + + assert.ok(model); + }); +}); diff --git a/tests/unit/models/project-test.js b/tests/unit/models/project-test.ts similarity index 58% rename from tests/unit/models/project-test.js rename to tests/unit/models/project-test.ts index ed854370d..2c5fd1b3c 100644 --- a/tests/unit/models/project-test.js +++ b/tests/unit/models/project-test.ts @@ -1,16 +1,23 @@ +import type { Registry as Services } from '@ember/service'; +import type { TestContext as BaseTestContext } from '@ember/test-helpers'; import { setupTest } from 'ember-qunit'; +import type Project from 'ember-website/models/project'; import { module, test } from 'qunit'; +interface TestContext extends BaseTestContext { + store: Services['store']; +} + module('Unit | Model | project', function (hooks) { setupTest(hooks); module('Ember.js', function (hooks) { - hooks.beforeEach(function () { + hooks.beforeEach(function (this: TestContext) { this.store = this.owner.lookup('service:store'); }); - test('The model can generate a lastReleaseChangelogUrl correctly', function (assert) { - const model = this.store.createRecord('project', { + test('The model can generate a lastReleaseChangelogUrl correctly', function (this: TestContext, assert) { + const model = this.store.createRecord<Project>('project', { repo: 'face/mine.js', lastRelease: '7', changelogPath: 'CHANGELOG.md', @@ -22,14 +29,12 @@ module('Unit | Model | project', function (hooks) { ); }); - test('No lastReleaseChangelogUrl is generated if changelogPath is missing', function (assert) { - const model = this.store.createRecord('project', { + test('No lastReleaseChangelogUrl is generated if changelogPath is missing', function (this: TestContext, assert) { + const model = this.store.createRecord<Project>('project', { repo: 'face/mine.js', lastRelease: '7', }); - assert.ok(model, 'We can create the record.'); - assert.strictEqual(model.lastReleaseChangelogUrl, ''); }); }); diff --git a/tests/unit/models/showcase-test.ts b/tests/unit/models/showcase-test.ts new file mode 100644 index 000000000..dd91081c1 --- /dev/null +++ b/tests/unit/models/showcase-test.ts @@ -0,0 +1,14 @@ +import type Showcase from 'ember-website/models/showcase'; +import { setupTest } from 'ember-website/tests/helpers'; +import { module, test } from 'qunit'; + +module('Unit | Model | showcase', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord<Showcase>('showcase', {}); + + assert.ok(model); + }); +}); diff --git a/tests/unit/models/sponsor-test.js b/tests/unit/models/sponsor-test.ts similarity index 58% rename from tests/unit/models/sponsor-test.js rename to tests/unit/models/sponsor-test.ts index 9dc719357..68f20f95d 100644 --- a/tests/unit/models/sponsor-test.js +++ b/tests/unit/models/sponsor-test.ts @@ -1,21 +1,26 @@ +import type { Registry as Services } from '@ember/service'; +import type { TestContext as BaseTestContext } from '@ember/test-helpers'; import { setupTest } from 'ember-qunit'; +import type Sponsor from 'ember-website/models/sponsor'; import { module, test } from 'qunit'; +interface TestContext extends BaseTestContext { + store: Services['store']; +} + module('Unit | Model | sponsor', function (hooks) { setupTest(hooks); - hooks.beforeEach(function () { + hooks.beforeEach(function (this: TestContext) { this.store = this.owner.lookup('service:store'); }); - test('The model can describe a current sponsor', function (assert) { - const model = this.store.createRecord('sponsor', { + test('The model can describe a current sponsor', function (this: TestContext, assert) { + const model = this.store.createRecord<Sponsor>('sponsor', { name: 'Super Corp.', start: new Date('2011-01-01'), }); - assert.ok(model, 'We can create the record.'); - assert.strictEqual( model.term, '2011 - present', @@ -23,15 +28,13 @@ module('Unit | Model | sponsor', function (hooks) { ); }); - test('The model can describe a past sponsor that spanned multiple years', function (assert) { - const model = this.store.createRecord('sponsor', { + test('The model can describe a past sponsor that spanned multiple years', function (this: TestContext, assert) { + const model = this.store.createRecord<Sponsor>('sponsor', { name: 'Super Corp.', start: new Date('2015-01-01'), end: new Date('2018-01-01'), }); - assert.ok(model, 'We can create the record.'); - assert.strictEqual( model.term, '2015 - 2018', @@ -39,15 +42,13 @@ module('Unit | Model | sponsor', function (hooks) { ); }); - test('The model can describe a past sponsor that only sponsored one year', function (assert) { - const model = this.store.createRecord('sponsor', { + test('The model can describe a past sponsor that only sponsored one year', function (this: TestContext, assert) { + const model = this.store.createRecord<Sponsor>('sponsor', { name: 'Super Corp.', start: new Date('2018-01-01'), end: new Date('2018-08-01'), }); - assert.ok(model, 'We can create the record.'); - assert.strictEqual( model.term, '2018', diff --git a/tests/unit/models/team-member-test.ts b/tests/unit/models/team-member-test.ts new file mode 100644 index 000000000..c165335c0 --- /dev/null +++ b/tests/unit/models/team-member-test.ts @@ -0,0 +1,14 @@ +import type TeamMember from 'ember-website/models/team-member'; +import { setupTest } from 'ember-website/tests/helpers'; +import { module, test } from 'qunit'; + +module('Unit | Model | team-member', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord<TeamMember>('team-member', {}); + + assert.ok(model); + }); +}); diff --git a/tests/unit/models/tomster-test.ts b/tests/unit/models/tomster-test.ts new file mode 100644 index 000000000..2c79c7475 --- /dev/null +++ b/tests/unit/models/tomster-test.ts @@ -0,0 +1,14 @@ +import type Tomster from 'ember-website/models/tomster'; +import { setupTest } from 'ember-website/tests/helpers'; +import { module, test } from 'qunit'; + +module('Unit | Model | tomster', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord<Tomster>('tomster', {}); + + assert.ok(model); + }); +}); diff --git a/tests/unit/models/user-test.ts b/tests/unit/models/user-test.ts new file mode 100644 index 000000000..9601e4aed --- /dev/null +++ b/tests/unit/models/user-test.ts @@ -0,0 +1,14 @@ +import type User from 'ember-website/models/user'; +import { setupTest } from 'ember-website/tests/helpers'; +import { module, test } from 'qunit'; + +module('Unit | Model | user', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord<User>('user', {}); + + assert.ok(model); + }); +}); diff --git a/tests/unit/serializers/application-test.js b/tests/unit/serializers/application-test.js deleted file mode 100644 index 1f1b8a444..000000000 --- a/tests/unit/serializers/application-test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { setupTest } from 'ember-qunit'; -import { module, test } from 'qunit'; - -module('Unit | Serializer | application', function (hooks) { - setupTest(hooks); - - // Replace this with your real tests. - test('it exists', function (assert) { - let store = this.owner.lookup('service:store'); - let serializer = store.serializerFor('application'); - - assert.ok(serializer); - }); - - test('it serializes records', function (assert) { - let store = this.owner.lookup('service:store'); - let record = store.createRecord('tomster', {}); - - let serializedRecord = record.serialize(); - - assert.ok(serializedRecord); - }); -}); diff --git a/tests/unit/serializers/application-test.ts b/tests/unit/serializers/application-test.ts new file mode 100644 index 000000000..68fe26749 --- /dev/null +++ b/tests/unit/serializers/application-test.ts @@ -0,0 +1,28 @@ +import type ApplicationSerializer from 'ember-website/serializers/application'; +import { setupTest } from 'ember-qunit'; +import type Tomster from 'ember-website/models/tomster'; +import { module, test } from 'qunit'; + +module('Unit | Serializer | application', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const store = this.owner.lookup('service:store'); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + const serializer = store.serializerFor( + 'application', + ) as ApplicationSerializer; + + assert.ok(serializer); + }); + + test('it serializes records', function (assert) { + const store = this.owner.lookup('service:store'); + + const record = store.createRecord<Tomster>('tomster', {}); + const serializedRecord = record.serialize(); + + assert.ok(serializedRecord); + }); +}); diff --git a/tests/unit/services/head-data-test.ts b/tests/unit/services/head-data-test.ts new file mode 100644 index 000000000..adf06e33c --- /dev/null +++ b/tests/unit/services/head-data-test.ts @@ -0,0 +1,12 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +module('Unit | Service | head-data', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const service = this.owner.lookup('service:head-data'); + + assert.strictEqual(service.pageTitle, undefined); + }); +}); diff --git a/tests/unit/services/page-title-test.ts b/tests/unit/services/page-title-test.ts new file mode 100644 index 000000000..205f565f3 --- /dev/null +++ b/tests/unit/services/page-title-test.ts @@ -0,0 +1,12 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +module('Unit | Service | page-title', function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + const service = this.owner.lookup('service:page-title'); + + assert.ok(service); + }); +}); diff --git a/tests/unit/utils/format-url-test.js b/tests/unit/utils/format-url-test.ts similarity index 100% rename from tests/unit/utils/format-url-test.js rename to tests/unit/utils/format-url-test.ts diff --git a/tests/unit/utils/highcharts/area-spline-chart-test.js b/tests/unit/utils/highcharts/area-spline-chart-test.ts similarity index 77% rename from tests/unit/utils/highcharts/area-spline-chart-test.js rename to tests/unit/utils/highcharts/area-spline-chart-test.ts index 190824e73..ebe1a8b5a 100644 --- a/tests/unit/utils/highcharts/area-spline-chart-test.js +++ b/tests/unit/utils/highcharts/area-spline-chart-test.ts @@ -1,8 +1,18 @@ +import type { TestContext as BaseTestContext } from '@ember/test-helpers'; import AreaSplineChart from 'ember-website/utils/highcharts/area-spline-chart'; +import type { + Chart, + RawData, +} from 'ember-website/utils/highcharts/area-spline-chart'; import { module, test } from 'qunit'; +interface TestContext extends BaseTestContext { + chart: Chart; + rawData: RawData; +} + module('Unit | Utility | highcharts/area-spline-chart', function (hooks) { - hooks.beforeEach(function () { + hooks.beforeEach(function (this: TestContext) { this.chart = { categories: ['1.x', '2.x', '3.0-3.4', '3.5-3.8', '3.9-3.12', '3.13-3.16'], subtitle: '(Multi-select question)', @@ -36,20 +46,23 @@ module('Unit | Utility | highcharts/area-spline-chart', function (hooks) { }); module('highchartsOptions', function () { - test('returns a configuration object that is compatible with Highcharts', function (assert) { + test('returns a configuration object that is compatible with Highcharts', function (this: TestContext, assert) { const { highchartsOptions } = new AreaSplineChart({ chart: this.chart, rawData: this.rawData, }); // We tested `legend` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.legend; // We tested `series` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.series; assert.deepEqual( highchartsOptions, + // @ts-expect-error: Incorrect type { chart: { backgroundColor: 'transparent', @@ -95,8 +108,8 @@ module('Unit | Utility | highcharts/area-spline-chart', function (hooks) { }); module('isLegendEnabled', function () { - test('returns true when series has more than 1 element', function (assert) { - const rawData = this.rawData; + test('returns true when series has more than 1 element', function (this: TestContext, assert) { + const rawData: RawData = this.rawData; const { isLegendEnabled } = new AreaSplineChart({ chart: this.chart, @@ -106,8 +119,8 @@ module('Unit | Utility | highcharts/area-spline-chart', function (hooks) { assert.true(isLegendEnabled, 'We get the correct value.'); }); - test('returns false when series has 1 element', function (assert) { - const rawData = [this.rawData[0]]; + test('returns false when series has 1 element', function (this: TestContext, assert) { + const rawData: RawData = [this.rawData[0]!]; const { isLegendEnabled } = new AreaSplineChart({ chart: this.chart, @@ -117,8 +130,8 @@ module('Unit | Utility | highcharts/area-spline-chart', function (hooks) { assert.false(isLegendEnabled, 'We get the correct value.'); }); - test('returns false when series has 0 elements', function (assert) { - const rawData = []; + test('returns false when series has 0 elements', function (this: TestContext, assert) { + const rawData: RawData = []; const { isLegendEnabled } = new AreaSplineChart({ chart: this.chart, @@ -130,7 +143,7 @@ module('Unit | Utility | highcharts/area-spline-chart', function (hooks) { }); module('series', function () { - test('transforms rawData into an array that is compatible with Highcharts', function (assert) { + test('transforms rawData into an array that is compatible with Highcharts', function (this: TestContext, assert) { const { series } = new AreaSplineChart({ chart: this.chart, rawData: this.rawData, @@ -141,9 +154,9 @@ module('Unit | Utility | highcharts/area-spline-chart', function (hooks) { // Check series 1 assert.deepEqual( { - color: series[0].color, - data: series[0].data.map(Math.round), - name: series[0].name, + color: series[0]!.color, + data: series[0]!.data.map(Math.round), + name: series[0]!.name, }, { color: '#1E719B', @@ -156,9 +169,9 @@ module('Unit | Utility | highcharts/area-spline-chart', function (hooks) { // Check series 2 assert.deepEqual( { - color: series[1].color, - data: series[1].data.map(Math.round), - name: series[1].name, + color: series[1]!.color, + data: series[1]!.data.map(Math.round), + name: series[1]!.name, }, { color: '#9B2918', diff --git a/tests/unit/utils/highcharts/horizontal-bar-chart-test.js b/tests/unit/utils/highcharts/horizontal-bar-chart-test.ts similarity index 80% rename from tests/unit/utils/highcharts/horizontal-bar-chart-test.js rename to tests/unit/utils/highcharts/horizontal-bar-chart-test.ts index 7c1413ea1..3e38e5e4a 100644 --- a/tests/unit/utils/highcharts/horizontal-bar-chart-test.js +++ b/tests/unit/utils/highcharts/horizontal-bar-chart-test.ts @@ -1,8 +1,18 @@ +import type { TestContext as BaseTestContext } from '@ember/test-helpers'; import HorizontalBarChart from 'ember-website/utils/highcharts/horizontal-bar-chart'; +import type { + Chart, + RawData, +} from 'ember-website/utils/highcharts/horizontal-bar-chart'; import { module, test } from 'qunit'; +interface TestContext extends BaseTestContext { + chart: Chart; + rawData: RawData; +} + module('Unit | Utility | highcharts/horizontal-bar-chart', function (hooks) { - hooks.beforeEach(function () { + hooks.beforeEach(function (this: TestContext) { this.chart = { categories: [ 'Writing RFCs', @@ -31,20 +41,23 @@ module('Unit | Utility | highcharts/horizontal-bar-chart', function (hooks) { }); module('highchartsOptions', function () { - test('returns a configuration object that is compatible with Highcharts', function (assert) { + test('returns a configuration object that is compatible with Highcharts', function (this: TestContext, assert) { const { highchartsOptions } = new HorizontalBarChart({ chart: this.chart, rawData: this.rawData, }); // We tested `legend` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.legend; // We tested `series` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.series; assert.deepEqual( highchartsOptions, + // @ts-expect-error: Incorrect type { chart: { backgroundColor: 'transparent', @@ -91,8 +104,8 @@ module('Unit | Utility | highcharts/horizontal-bar-chart', function (hooks) { }); module('isLegendEnabled', function () { - test('returns true when series has more than 1 element', function (assert) { - const rawData = this.rawData; + test('returns true when series has more than 1 element', function (this: TestContext, assert) { + const rawData: RawData = this.rawData; const { isLegendEnabled } = new HorizontalBarChart({ chart: this.chart, @@ -102,8 +115,8 @@ module('Unit | Utility | highcharts/horizontal-bar-chart', function (hooks) { assert.true(isLegendEnabled, 'We get the correct value.'); }); - test('returns false when series has 1 element', function (assert) { - const rawData = [this.rawData[0]]; + test('returns false when series has 1 element', function (this: TestContext, assert) { + const rawData: RawData = [this.rawData[0]!]; const { isLegendEnabled } = new HorizontalBarChart({ chart: this.chart, @@ -113,8 +126,8 @@ module('Unit | Utility | highcharts/horizontal-bar-chart', function (hooks) { assert.false(isLegendEnabled, 'We get the correct value.'); }); - test('returns false when series has 0 elements', function (assert) { - const rawData = []; + test('returns false when series has 0 elements', function (this: TestContext, assert) { + const rawData: RawData = []; const { isLegendEnabled } = new HorizontalBarChart({ chart: this.chart, @@ -126,7 +139,7 @@ module('Unit | Utility | highcharts/horizontal-bar-chart', function (hooks) { }); module('series', function () { - test('transforms rawData into an array that is compatible with Highcharts', function (assert) { + test('transforms rawData into an array that is compatible with Highcharts', function (this: TestContext, assert) { const { series } = new HorizontalBarChart({ chart: this.chart, rawData: this.rawData, diff --git a/tests/unit/utils/highcharts/index-test.js b/tests/unit/utils/highcharts/index-test.ts similarity index 100% rename from tests/unit/utils/highcharts/index-test.js rename to tests/unit/utils/highcharts/index-test.ts index 42c8f62e7..22ed32e6c 100644 --- a/tests/unit/utils/highcharts/index-test.js +++ b/tests/unit/utils/highcharts/index-test.ts @@ -1,4 +1,3 @@ -import { setupTest } from 'ember-qunit'; import { AreaSplineChart, HorizontalBarChart, @@ -6,6 +5,7 @@ import { SplineChart, VerticalBarChart, } from 'ember-website/utils/highcharts/index'; +import { setupTest } from 'ember-qunit'; import { module, test } from 'qunit'; module('Unit | Utility | highcharts/index', function (hooks) { diff --git a/tests/unit/utils/highcharts/pie-chart-test.js b/tests/unit/utils/highcharts/pie-chart-test.ts similarity index 81% rename from tests/unit/utils/highcharts/pie-chart-test.js rename to tests/unit/utils/highcharts/pie-chart-test.ts index dd6ff8d88..7a6e06ac7 100644 --- a/tests/unit/utils/highcharts/pie-chart-test.js +++ b/tests/unit/utils/highcharts/pie-chart-test.ts @@ -1,8 +1,15 @@ +import type { TestContext as BaseTestContext } from '@ember/test-helpers'; import PieChart from 'ember-website/utils/highcharts/pie-chart'; +import type { Chart, RawData } from 'ember-website/utils/highcharts/pie-chart'; import { module, test } from 'qunit'; +interface TestContext extends BaseTestContext { + chart: Chart; + rawData: RawData; +} + module('Unit | Utility | highcharts/pie-chart', function (hooks) { - hooks.beforeEach(function () { + hooks.beforeEach(function (this: TestContext) { this.chart = { title: 'Do you internationalize your applications?', }; @@ -14,17 +21,19 @@ module('Unit | Utility | highcharts/pie-chart', function (hooks) { }); module('highchartsOptions', function () { - test('returns a configuration object that is compatible with Highcharts', function (assert) { + test('returns a configuration object that is compatible with Highcharts', function (this: TestContext, assert) { const { highchartsOptions } = new PieChart({ chart: this.chart, rawData: this.rawData, }); // We tested `series` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.series; assert.deepEqual( highchartsOptions, + // @ts-expect-error: Incorrect type { chart: { backgroundColor: 'transparent', @@ -49,7 +58,7 @@ module('Unit | Utility | highcharts/pie-chart', function (hooks) { }); module('series', function () { - test('transforms rawData into an array that is compatible with Highcharts', function (assert) { + test('transforms rawData into an array that is compatible with Highcharts', function (this: TestContext, assert) { const { series } = new PieChart({ chart: this.chart, rawData: this.rawData, diff --git a/tests/unit/utils/highcharts/spline-chart-test.js b/tests/unit/utils/highcharts/spline-chart-test.ts similarity index 83% rename from tests/unit/utils/highcharts/spline-chart-test.js rename to tests/unit/utils/highcharts/spline-chart-test.ts index ffe667426..79ad0d674 100644 --- a/tests/unit/utils/highcharts/spline-chart-test.js +++ b/tests/unit/utils/highcharts/spline-chart-test.ts @@ -1,8 +1,18 @@ +import type { TestContext as BaseTestContext } from '@ember/test-helpers'; import SplineChart from 'ember-website/utils/highcharts/spline-chart'; +import type { + Chart, + RawData, +} from 'ember-website/utils/highcharts/spline-chart'; import { module, test } from 'qunit'; +interface TestContext extends BaseTestContext { + chart: Chart; + rawData: RawData; +} + module('Unit | Utility | highcharts/spline-chart', function (hooks) { - hooks.beforeEach(function () { + hooks.beforeEach(function (this: TestContext) { this.chart = { categories: [ '1.13', @@ -53,20 +63,23 @@ module('Unit | Utility | highcharts/spline-chart', function (hooks) { }); module('highchartsOptions', function () { - test('returns a configuration object that is compatible with Highcharts', function (assert) { + test('returns a configuration object that is compatible with Highcharts', function (this: TestContext, assert) { const { highchartsOptions } = new SplineChart({ chart: this.chart, rawData: this.rawData, }); // We tested `legend` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.legend; // We tested `series` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.series; assert.deepEqual( highchartsOptions, + // @ts-expect-error: Incorrect type { chart: { backgroundColor: 'transparent', @@ -129,8 +142,8 @@ module('Unit | Utility | highcharts/spline-chart', function (hooks) { }); module('isLegendEnabled', function () { - test('returns true when series has more than 1 element', function (assert) { - const rawData = this.rawData; + test('returns true when series has more than 1 element', function (this: TestContext, assert) { + const rawData: RawData = this.rawData; const { isLegendEnabled } = new SplineChart({ chart: this.chart, @@ -140,8 +153,8 @@ module('Unit | Utility | highcharts/spline-chart', function (hooks) { assert.true(isLegendEnabled, 'We get the correct value.'); }); - test('returns false when series has 1 element', function (assert) { - const rawData = [this.rawData[0]]; + test('returns false when series has 1 element', function (this: TestContext, assert) { + const rawData: RawData = [this.rawData[0]!]; const { isLegendEnabled } = new SplineChart({ chart: this.chart, @@ -151,8 +164,8 @@ module('Unit | Utility | highcharts/spline-chart', function (hooks) { assert.false(isLegendEnabled, 'We get the correct value.'); }); - test('returns false when series has 0 elements', function (assert) { - const rawData = []; + test('returns false when series has 0 elements', function (this: TestContext, assert) { + const rawData: RawData = []; const { isLegendEnabled } = new SplineChart({ chart: this.chart, @@ -164,7 +177,7 @@ module('Unit | Utility | highcharts/spline-chart', function (hooks) { }); module('series', function () { - test('transforms rawData into an array that is compatible with Highcharts', function (assert) { + test('transforms rawData into an array that is compatible with Highcharts', function (this: TestContext, assert) { const { series } = new SplineChart({ chart: this.chart, rawData: this.rawData, diff --git a/tests/unit/utils/highcharts/vertical-bar-chart-test.js b/tests/unit/utils/highcharts/vertical-bar-chart-test.ts similarity index 81% rename from tests/unit/utils/highcharts/vertical-bar-chart-test.js rename to tests/unit/utils/highcharts/vertical-bar-chart-test.ts index cb969cbcb..e570e5958 100644 --- a/tests/unit/utils/highcharts/vertical-bar-chart-test.js +++ b/tests/unit/utils/highcharts/vertical-bar-chart-test.ts @@ -1,8 +1,18 @@ +import type { TestContext as BaseTestContext } from '@ember/test-helpers'; import VerticalBarChart from 'ember-website/utils/highcharts/vertical-bar-chart'; +import type { + Chart, + RawData, +} from 'ember-website/utils/highcharts/vertical-bar-chart'; import { module, test } from 'qunit'; +interface TestContext extends BaseTestContext { + chart: Chart; + rawData: RawData; +} + module('Unit | Utility | highcharts/vertical-bar-chart', function (hooks) { - hooks.beforeEach(function () { + hooks.beforeEach(function (this: TestContext) { this.chart = { categories: ['Beginner', 'Intermediate', 'Advanced'], title: 'Rank your web skills', @@ -33,20 +43,23 @@ module('Unit | Utility | highcharts/vertical-bar-chart', function (hooks) { }); module('highchartsOptions', function () { - test('returns a configuration object that is compatible with Highcharts', function (assert) { + test('returns a configuration object that is compatible with Highcharts', function (this: TestContext, assert) { const { highchartsOptions } = new VerticalBarChart({ chart: this.chart, rawData: this.rawData, }); // We tested `legend` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.legend; // We tested `series` in a separate module + // @ts-expect-error: Incorrect type delete highchartsOptions.series; assert.deepEqual( highchartsOptions, + // @ts-expect-error: Incorrect type { chart: { backgroundColor: 'transparent', @@ -85,8 +98,8 @@ module('Unit | Utility | highcharts/vertical-bar-chart', function (hooks) { }); module('isLegendEnabled', function () { - test('returns true when series has more than 1 element', function (assert) { - const rawData = this.rawData; + test('returns true when series has more than 1 element', function (this: TestContext, assert) { + const rawData: RawData = this.rawData; const { isLegendEnabled } = new VerticalBarChart({ chart: this.chart, @@ -96,8 +109,8 @@ module('Unit | Utility | highcharts/vertical-bar-chart', function (hooks) { assert.true(isLegendEnabled, 'We get the correct value.'); }); - test('returns false when series has 1 element', function (assert) { - const rawData = [this.rawData[0]]; + test('returns false when series has 1 element', function (this: TestContext, assert) { + const rawData: RawData = [this.rawData[0]!]; const { isLegendEnabled } = new VerticalBarChart({ chart: this.chart, @@ -107,8 +120,8 @@ module('Unit | Utility | highcharts/vertical-bar-chart', function (hooks) { assert.false(isLegendEnabled, 'We get the correct value.'); }); - test('returns false when series has 0 elements', function (assert) { - const rawData = []; + test('returns false when series has 0 elements', function (this: TestContext, assert) { + const rawData: RawData = []; const { isLegendEnabled } = new VerticalBarChart({ chart: this.chart, @@ -120,7 +133,7 @@ module('Unit | Utility | highcharts/vertical-bar-chart', function (hooks) { }); module('series', function () { - test('transforms rawData into an array that is compatible with Highcharts', function (assert) { + test('transforms rawData into an array that is compatible with Highcharts', function (this: TestContext, assert) { const { series } = new VerticalBarChart({ chart: this.chart, rawData: this.rawData, diff --git a/tests/unit/utils/navigate-tabs-test.js b/tests/unit/utils/navigate-tabs-test.ts similarity index 58% rename from tests/unit/utils/navigate-tabs-test.js rename to tests/unit/utils/navigate-tabs-test.ts index 27ccfc357..995414605 100644 --- a/tests/unit/utils/navigate-tabs-test.js +++ b/tests/unit/utils/navigate-tabs-test.ts @@ -46,61 +46,25 @@ module('Unit | Utility | navigate-tabs', function () { }); }); - module('modulus', function (hooks) { - hooks.beforeEach(function () { - this.numTabs = 4; - }); - + module('modulus', function () { test('calculates m % n when m is a nonnegative number', function (assert) { - assert.strictEqual( - modulus(0, this.numTabs), - 0, - 'We get the correct output.', - ); + assert.strictEqual(modulus(0, 4), 0, 'We get the correct output.'); - assert.strictEqual( - modulus(1, this.numTabs), - 1, - 'We get the correct output.', - ); + assert.strictEqual(modulus(1, 4), 1, 'We get the correct output.'); - assert.strictEqual( - modulus(2, this.numTabs), - 2, - 'We get the correct output.', - ); + assert.strictEqual(modulus(2, 4), 2, 'We get the correct output.'); - assert.strictEqual( - modulus(3, this.numTabs), - 3, - 'We get the correct output.', - ); + assert.strictEqual(modulus(3, 4), 3, 'We get the correct output.'); }); test('calculates m % n when m is a negative number', function (assert) { - assert.strictEqual( - modulus(-4, this.numTabs), - 0, - 'We get the correct output.', - ); + assert.strictEqual(modulus(-4, 4), 0, 'We get the correct output.'); - assert.strictEqual( - modulus(-3, this.numTabs), - 1, - 'We get the correct output.', - ); + assert.strictEqual(modulus(-3, 4), 1, 'We get the correct output.'); - assert.strictEqual( - modulus(-2, this.numTabs), - 2, - 'We get the correct output.', - ); + assert.strictEqual(modulus(-2, 4), 2, 'We get the correct output.'); - assert.strictEqual( - modulus(-1, this.numTabs), - 3, - 'We get the correct output.', - ); + assert.strictEqual(modulus(-1, 4), 3, 'We get the correct output.'); }); }); }); diff --git a/tests/unit/utils/releases/lts-test.js b/tests/unit/utils/releases/lts-test.ts similarity index 100% rename from tests/unit/utils/releases/lts-test.js rename to tests/unit/utils/releases/lts-test.ts diff --git a/tests/unit/utils/replace-links-test.js b/tests/unit/utils/replace-links-test.ts similarity index 99% rename from tests/unit/utils/replace-links-test.js rename to tests/unit/utils/replace-links-test.ts index d0673ece1..71ad7f162 100644 --- a/tests/unit/utils/replace-links-test.js +++ b/tests/unit/utils/replace-links-test.ts @@ -1,4 +1,4 @@ -import { replaceLinks } from 'ember-website/utils/replace-links'; +import { type Link, replaceLinks } from 'ember-website/utils/replace-links'; import { module, test } from 'qunit'; module('Unit | Utility | replace-links', function () { @@ -9,7 +9,7 @@ module('Unit | Utility | replace-links', function () { See https://github.com/ember-learn/ember-styleguide/blob/ab1d1fc32dd023f287c49d3fd700216ba368771a/addon/constants/links.js */ - const links = [ + const links: Link[] = [ { name: 'Docs', type: 'dropdown', @@ -368,7 +368,7 @@ module('Unit | Utility | replace-links', function () { See https://github.com/ember-learn/ember-website/blob/d08e34a0acd403d16ee78c90ec0ec368762e3e9f/app/links.js */ - const links = [ + const links: Link[] = [ { name: 'Docs', type: 'dropdown', diff --git a/tests/unit/utils/surveys/2016-test.js b/tests/unit/utils/surveys/2016-test.ts similarity index 100% rename from tests/unit/utils/surveys/2016-test.js rename to tests/unit/utils/surveys/2016-test.ts diff --git a/tests/unit/utils/surveys/2017-test.js b/tests/unit/utils/surveys/2017-test.ts similarity index 100% rename from tests/unit/utils/surveys/2017-test.js rename to tests/unit/utils/surveys/2017-test.ts diff --git a/tests/unit/utils/surveys/2018-test.js b/tests/unit/utils/surveys/2018-test.ts similarity index 100% rename from tests/unit/utils/surveys/2018-test.js rename to tests/unit/utils/surveys/2018-test.ts diff --git a/tests/unit/utils/surveys/2019-test.js b/tests/unit/utils/surveys/2019-test.ts similarity index 100% rename from tests/unit/utils/surveys/2019-test.js rename to tests/unit/utils/surveys/2019-test.ts diff --git a/tests/unit/utils/surveys/2020-test.js b/tests/unit/utils/surveys/2020-test.ts similarity index 100% rename from tests/unit/utils/surveys/2020-test.js rename to tests/unit/utils/surveys/2020-test.ts diff --git a/tests/unit/utils/surveys/2022-test.js b/tests/unit/utils/surveys/2022-test.ts similarity index 100% rename from tests/unit/utils/surveys/2022-test.js rename to tests/unit/utils/surveys/2022-test.ts diff --git a/tests/unit/utils/teams/in-team-test.js b/tests/unit/utils/teams/in-team-test.ts similarity index 100% rename from tests/unit/utils/teams/in-team-test.js rename to tests/unit/utils/teams/in-team-test.ts diff --git a/tsconfig.json b/tsconfig.json index 4d305d2c1..c35c750d1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,17 +13,44 @@ ], "rootDir": ".", "target": "esnext", - "types": ["@glint/ember-tsc/types", "@types/qunit", "ember-source/types"] + "types": [ + "@ember-data-types/adapter/unstable-preview-types", + "@ember-data-types/model/unstable-preview-types", + "@ember-data-types/serializer/unstable-preview-types", + "@ember-data-types/store/unstable-preview-types", + "@glint/ember-tsc/types", + "@types/qunit", + "@warp-drive-types/core-types/unstable-preview-types", + "ember-data-types/unstable-preview-types", + "ember-source/types" + ] }, "include": ["app/**/*", "tests/**/*", "types/**/*"], "glint": { "additionalSpecialForms": { - "globals": { - "and": "&&", - "eq": "===", - "not": "!", - "neq": "!==", - "or": "||" + "imports": { + "ember-truth-helpers": { + "and": "&&", + "eq": "===", + "not": "!", + "not-eq": "!==", + "or": "||" + }, + "ember-truth-helpers/helpers/and": { + "default": "&&" + }, + "ember-truth-helpers/helpers/eq": { + "default": "===" + }, + "ember-truth-helpers/helpers/not": { + "default": "!" + }, + "ember-truth-helpers/helpers/not-eq": { + "default": "!==" + }, + "ember-truth-helpers/helpers/or": { + "default": "||" + } } } } diff --git a/types/global.d.ts b/types/global.d.ts index e69de29bb..a1fc83bce 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -0,0 +1,7 @@ +import type StoreService from '@ember-data/store'; + +declare module '@ember/service' { + export interface Registry { + store: StoreService; + } +}