Skip to content

Commit

Permalink
test: test cases for order
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed Oct 7, 2024
1 parent cba3be5 commit dabe5a5
Showing 1 changed file with 222 additions and 103 deletions.
325 changes: 222 additions & 103 deletions packages/astro/src/default/utils/content.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as content from 'astro:content';
import { expect, test, vi, type TaskContext } from 'vitest';
import { describe, expect, test, vi, type TaskContext } from 'vitest';
import { getTutorial, type CollectionEntryTutorial } from './content';

const getCollection = vi.mocked(content.getCollection);
const getCollection = vi.mocked<() => Omit<CollectionEntryTutorial, 'render'>[]>(content.getCollection);
vi.mock('astro:content', () => ({ getCollection: vi.fn() }));

// mock DEFAULT_LOCALIZATION so that we don't need to update test results everytime new keys are added there
Expand Down Expand Up @@ -95,116 +95,235 @@ test('multiple parts', async (ctx) => {
await expect(collection).toMatchFileSnapshot(snapshotName(ctx));
});

test('lesson inherits metadata from tutorial', async () => {
const data: CollectionEntryTutorial['data'] = {
type: 'tutorial',
autoReload: true,
editor: { fileTree: { allowEdits: ['some-pattern/**'] } },
editPageLink: 'example-link',
filesystem: { watch: true },
focus: '/index.js',
i18n: { confirmationText: 'example' },
mainCommand: 'ls',
prepareCommands: ['npm i'],
openInStackBlitz: { projectTitle: 'example' },
previews: ['8080', '3000'],
template: 'vite',
terminal: { panels: ['output', 'terminal'] },
};

getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial, data },
{ id: '1-part/meta.md', ...part },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/1-lesson/content.md', ...lesson },
]);

const collection = await getTutorial();
const { data: lessonData } = collection.parts['1-part'].chapters['1-chapter'].lessons['1-lesson'];

expect(lessonData).toStrictEqual({ ...data, type: 'lesson', title: lesson.data.title });
});

test('lesson inherits metadata cascaded form all higher levels', async () => {
getCollection.mockReturnValueOnce([
{
id: 'meta.md',
...tutorial,
data: {
...tutorial.data,
editPageLink: 'edit link from tutorial',
focus: 'this should be overwritten',
mainCommand: 'this should be overwritten',
template: 'this should be overwritten',
describe('metadata inheriting', () => {
test('lesson inherits metadata from tutorial', async () => {
const data: CollectionEntryTutorial['data'] = {
type: 'tutorial',
autoReload: true,
editor: { fileTree: { allowEdits: ['some-pattern/**'] } },
editPageLink: 'example-link',
filesystem: { watch: true },
focus: '/index.js',
i18n: { confirmationText: 'example' },
mainCommand: 'ls',
prepareCommands: ['npm i'],
openInStackBlitz: { projectTitle: 'example' },
previews: ['8080', '3000'],
template: 'vite',
terminal: { panels: ['output', 'terminal'] },
};

getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial, data },
{ id: '1-part/meta.md', ...part },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/1-lesson/content.md', ...lesson },
]);

const collection = await getTutorial();
const { data: lessonData } = collection.parts['1-part'].chapters['1-chapter'].lessons['1-lesson'];

expect(lessonData).toStrictEqual({ ...data, type: 'lesson', title: lesson.data.title });
});

test('lesson inherits metadata cascaded from all higher levels', async () => {
getCollection.mockReturnValueOnce([
{
id: 'meta.md',
...tutorial,
data: {
...tutorial.data,
editPageLink: 'edit link from tutorial',
focus: 'this should be overwritten',
mainCommand: 'this should be overwritten',
template: 'this should be overwritten',
},
},
},
{
id: '1-part/meta.md',
...part,
data: {
...part.data,
focus: 'focus from part',
mainCommand: 'this should be overwritten',
template: 'this should be overwritten',
{
id: '1-part/meta.md',
...part,
data: {
...part.data,
focus: 'focus from part',
mainCommand: 'this should be overwritten',
template: 'this should be overwritten',
},
},
},
{
id: '1-part/1-chapter/meta.md',
...chapter,
data: {
...chapter.data,
mainCommand: 'main command from chapter',
template: 'this should be overwritten',
{
id: '1-part/1-chapter/meta.md',
...chapter,
data: {
...chapter.data,
mainCommand: 'main command from chapter',
template: 'this should be overwritten',
},
},
},
{
id: '1-part/1-chapter/1-lesson/content.md',
...lesson,
data: { ...lesson.data, template: 'template from lesson' },
},
]);
{
id: '1-part/1-chapter/1-lesson/content.md',
...lesson,
data: { ...lesson.data, template: 'template from lesson' },
},
]);

const collection = await getTutorial();
const { data: lessonData } = collection.parts['1-part'].chapters['1-chapter'].lessons['1-lesson'];
const collection = await getTutorial();
const { data: lessonData } = collection.parts['1-part'].chapters['1-chapter'].lessons['1-lesson'];

expect(lessonData.editPageLink).toBe('edit link from tutorial');
expect(lessonData.focus).toBe('focus from part');
expect(lessonData.mainCommand).toBe('main command from chapter');
expect(lessonData.template).toBe('template from lesson');
expect(lessonData.editPageLink).toBe('edit link from tutorial');
expect(lessonData.focus).toBe('focus from part');
expect(lessonData.mainCommand).toBe('main command from chapter');
expect(lessonData.template).toBe('template from lesson');
});
});

test('throws when tutorial metadata not found', async () => {
getCollection.mockReturnValueOnce([
{ id: '1-part/meta.md', ...part },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/1-first/content.md', ...lesson },
]);

await expect(getTutorial).rejects.toThrowErrorMatchingInlineSnapshot(
`[Error: Could not find tutorial 'meta.md' file]`,
);
});

test('throws when part not found', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '2-part/meta.md', ...part },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/1-first/content.md', ...lesson },
]);

await expect(getTutorial).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: Could not find part '1-part']`);
describe('ordering', () => {
test('parts are ordered by default', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '2-part/meta.md', ...part },
{ id: '3-part/meta.md', ...part },
{ id: '1-part/meta.md', ...part },
]);

const collection = await getTutorial();
const parts = collection.parts;

expect(parts['1-part'].order).toBe(0);
expect(parts['2-part'].order).toBe(1);
expect(parts['3-part'].order).toBe(2);
});

test('parts are ordered by metadata', async () => {
getCollection.mockReturnValueOnce([
{
id: 'meta.md',
...tutorial,
data: { ...tutorial.data, parts: ['3-part', '1-part', '2-part'] },
},
{ id: '2-part/meta.md', ...part },
{ id: '3-part/meta.md', ...part },
{ id: '1-part/meta.md', ...part },
]);

const collection = await getTutorial();
const parts = collection.parts;

expect(parts['3-part'].order).toBe(0);
expect(parts['1-part'].order).toBe(1);
expect(parts['2-part'].order).toBe(2);
});

test('chapters are ordered by default', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '1-part/meta.md', ...part },
{ id: '1-part/3-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/2-chapter/meta.md', ...chapter },
]);

const collection = await getTutorial();
const chapters = collection.parts['1-part'].chapters;

expect(chapters['1-chapter'].order).toBe(0);
expect(chapters['2-chapter'].order).toBe(1);
expect(chapters['3-chapter'].order).toBe(2);
});

test('chapters are ordered by metadata', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '1-part/meta.md', ...part, data: { ...part.data, chapters: ['3-chapter', '1-chapter', '2-chapter'] } },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/2-chapter/meta.md', ...chapter },
{ id: '1-part/3-chapter/meta.md', ...chapter },
]);

const collection = await getTutorial();
const chapters = collection.parts['1-part'].chapters;

expect(chapters['3-chapter'].order).toBe(0);
expect(chapters['1-chapter'].order).toBe(1);
expect(chapters['2-chapter'].order).toBe(2);
});

test('lessons are ordered by default', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '1-part/meta.md', ...part },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/2-lesson/meta.md', ...lesson },
{ id: '1-part/1-chapter/3-lesson/meta.md', ...lesson },
{ id: '1-part/1-chapter/1-lesson/meta.md', ...lesson },
]);

const collection = await getTutorial();
const lessons = collection.parts['1-part'].chapters['1-chapter'].lessons;

expect(lessons['1-lesson'].order).toBe(0);
expect(lessons['2-lesson'].order).toBe(1);
expect(lessons['3-lesson'].order).toBe(2);
});

test('lessons are ordered by metadata', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '1-part/meta.md', ...part },
{
id: '1-part/1-chapter/meta.md',
...chapter,
data: {
...chapter.data,
lessons: ['3-lesson', '1-lesson', '2-lesson'],
},
},
{ id: '1-part/1-chapter/2-lesson/meta.md', ...lesson },
{ id: '1-part/1-chapter/3-lesson/meta.md', ...lesson },
{ id: '1-part/1-chapter/1-lesson/meta.md', ...lesson },
]);

const collection = await getTutorial();
const lessons = collection.parts['1-part'].chapters['1-chapter'].lessons;

expect(lessons['3-lesson'].order).toBe(0);
expect(lessons['1-lesson'].order).toBe(1);
expect(lessons['2-lesson'].order).toBe(2);
});
});

test('throws when chapter not found', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '1-part/meta.md', ...part },
{ id: '1-part/2-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/1-first/content.md', ...lesson },
]);

await expect(getTutorial).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: Could not find chapter '1-chapter']`);
describe('missing parts', () => {
test('throws when tutorial metadata not found', async () => {
getCollection.mockReturnValueOnce([
{ id: '1-part/meta.md', ...part },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/1-first/content.md', ...lesson },
]);

await expect(getTutorial).rejects.toThrowErrorMatchingInlineSnapshot(
`[Error: Could not find tutorial 'meta.md' file]`,
);
});

test('throws when part not found', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '2-part/meta.md', ...part },
{ id: '1-part/1-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/1-first/content.md', ...lesson },
]);

await expect(getTutorial).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: Could not find part '1-part']`);
});

test('throws when chapter not found', async () => {
getCollection.mockReturnValueOnce([
{ id: 'meta.md', ...tutorial },
{ id: '1-part/meta.md', ...part },
{ id: '1-part/2-chapter/meta.md', ...chapter },
{ id: '1-part/1-chapter/1-first/content.md', ...lesson },
]);

await expect(getTutorial).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: Could not find chapter '1-chapter']`);
});
});

const tutorial = {
Expand Down

0 comments on commit dabe5a5

Please sign in to comment.