feat: unit tests for utils (#92)
* init * get unit test working for course.ts file * added some other tests * tests halfway + change config to accomodate js files * utility functions tests done * fix: config file + miscellaneous fixes * fix: prepare script * fix lock file --------- Co-authored-by: Rotimi Best <[email protected]>
This commit is contained in:
co-authored by
Rotimi Best
parent
4b2e58b1de
commit
6d689ede45
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* For a detailed explanation regarding each configuration property, visit:
|
||||
* https://jestjs.io/docs/configuration
|
||||
*/
|
||||
|
||||
import type { Config } from 'jest';
|
||||
|
||||
const config: Config = {};
|
||||
|
||||
export default config;
|
||||
|
||||
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.svelte$': 'svelte-jester',
|
||||
'^.+\\.ts$': 'ts-jest',
|
||||
'\\.[jt]sx?$': 'babel-jest'
|
||||
}
|
||||
};
|
||||
@@ -13,7 +13,9 @@
|
||||
"export": "vite build --entry \"/ /404 login signup forgot onboarding courses org lms course\"",
|
||||
"postexport": "mv __sapper__/export/404/index.html __sapper__/export/404.html",
|
||||
"start": "node build",
|
||||
"prepare": "svelte-kit sync"
|
||||
"prepare": "svelte-kit sync",
|
||||
"test": "jest",
|
||||
"test:watch": "pnpm run test --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.386.0",
|
||||
@@ -58,16 +60,22 @@
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.22.9",
|
||||
"@babel/preset-env": "^7.22.9",
|
||||
"@babel/preset-typescript": "^7.23.3",
|
||||
"@babel/runtime": "^7.22.6",
|
||||
"@sveltejs/kit": "^1.29.0",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"@testing-library/jest-dom": "^6.1.5",
|
||||
"@testing-library/svelte": "^4.0.5",
|
||||
"@types/jest": "^29.5.10",
|
||||
"@types/lodash": "^4.14.196",
|
||||
"@types/nodemailer": "^6.4.11",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"babel-jest": "^29.7.0",
|
||||
"carbon-components-svelte": "^0.79.0",
|
||||
"carbon-icons-svelte": "^12.1.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"jest": "^29.7.0",
|
||||
"postcss": "^8.4.24",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"sass": "^1.64.2",
|
||||
@@ -75,9 +83,12 @@
|
||||
"svelte": "^4.1.2",
|
||||
"svelte-calendar": "^3.1.6",
|
||||
"svelte-dnd-action": "^0.9.24",
|
||||
"svelte-jester": "^3.0.0",
|
||||
"svelte-loading-spinners": "^0.3.4",
|
||||
"svelte-preprocess": "^5.0.4",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsconfig": "workspace:*",
|
||||
"tslib": "^2.6.1",
|
||||
"typescript": "^5.1.6",
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/environment';
|
||||
import Modal from '$lib/components/Modal/index.svelte';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
@@ -98,7 +99,7 @@
|
||||
}, 500);
|
||||
}
|
||||
|
||||
$: note = getTextFromHTML($lesson?.materials?.note || '');
|
||||
$: note = browser ? getTextFromHTML($lesson?.materials?.note || '') : '';
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/environment';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { useCompletion } from 'ai/svelte';
|
||||
import MODES from '$lib/utils/constants/mode.js';
|
||||
@@ -84,7 +85,7 @@
|
||||
|
||||
if (!document) return false;
|
||||
|
||||
return getTextFromHTML(note) === '';
|
||||
return browser ? getTextFromHTML(note) === '' : false;
|
||||
}
|
||||
|
||||
function isMaterialsEmpty(materials: LessonPage['materials']) {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import isSubmissionEarly from './isSubmissionEarly';
|
||||
|
||||
describe('isSubmissionEarly', () => {
|
||||
test('should return true when createdAt is earlier than dueDate', () => {
|
||||
const dueDate = Date.now();
|
||||
const createdAt = new Date('2023-12-15');
|
||||
const result = isSubmissionEarly(createdAt, dueDate);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
test('should return true when both createdAt and dueDate are null', () => {
|
||||
const dueDate = null;
|
||||
const createdAt = null;
|
||||
const result = isSubmissionEarly(createdAt, dueDate);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
test('should return true when createdAt is the same as dueDate', () => {
|
||||
const dueDate = new Date('2023-12-15');
|
||||
const createdAt = new Date('2023-12-15');
|
||||
const result = isSubmissionEarly(createdAt, dueDate);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
test('should return false when createdAt is later than dueDate', () => {
|
||||
const dueDate = new Date('2023-12-15');
|
||||
const createdAt = new Date('2023-12-16');
|
||||
const result = isSubmissionEarly(createdAt, dueDate);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
import { isCourseFree } from './course';
|
||||
|
||||
describe('course.ts', () => {
|
||||
test('Should return True when cost is 0', () => {
|
||||
const result = isCourseFree(0);
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
test('Should return true when cost is negative', () => {
|
||||
const result = isCourseFree(-10);
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
test('Should return True when cost is Not A Number', () => {
|
||||
const result = isCourseFree(NaN);
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,3 @@
|
||||
import { browser } from '$app/environment';
|
||||
import type { Course } from '../types';
|
||||
|
||||
export const isCourseFree = (cost: number) => !(Number(cost) > 0);
|
||||
@@ -19,8 +18,6 @@ export const getStudentInviteLink = (_course: Course, orgSiteName: string, origi
|
||||
};
|
||||
|
||||
export const getTextFromHTML = (html: string): string => {
|
||||
if (!browser) return html;
|
||||
|
||||
const dummyDiv = document.createElement('div');
|
||||
dummyDiv.innerHTML = html;
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { calDateDiff, getGreeting } from './date';
|
||||
|
||||
describe('calDateDiff', () => {
|
||||
test('should return the correct time difference when the input date is in the past', () => {
|
||||
const inputDate = new Date('2022-01-01');
|
||||
const expectedOutput = '2 years ago';
|
||||
|
||||
const result = calDateDiff(inputDate);
|
||||
|
||||
expect(result).toBe(expectedOutput);
|
||||
});
|
||||
|
||||
test('should return the correct time difference when the input date is a number', () => {
|
||||
const inputDate = new Date(1640995200000); // January 1, 2022
|
||||
const expectedOutput = '2 years ago';
|
||||
|
||||
const result = calDateDiff(inputDate);
|
||||
|
||||
expect(result).toBe(expectedOutput);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getGreeting', () => {
|
||||
test("should return 'Good Morning' when the current time is before 12pm", () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2023-12-10T00:21:01.691Z'));
|
||||
expect(getGreeting()).toBe('Good Morning');
|
||||
});
|
||||
test("should return 'Good Afternoon' when the current time is after 12pm", () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2023-12-10T14:21:01.691Z'));
|
||||
expect(getGreeting()).toBe('Good Afternoon');
|
||||
});
|
||||
test("should return 'Good Evening' when the current time is after 6pm", () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2023-12-10T19:21:01.691Z'));
|
||||
expect(getGreeting()).toBe('Good Evening');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import { formatYoutubeVideo, getEmbedId } from './formatYoutubeVideo';
|
||||
|
||||
describe('format youtube video', () => {
|
||||
test('should return the same url when given a valid youtube embed url', () => {
|
||||
const url = 'https://www.youtube.com/embed/qajK1J1neAM';
|
||||
const errors = { video: '' };
|
||||
const result = formatYoutubeVideo(url, errors);
|
||||
expect(result).toBe(url);
|
||||
});
|
||||
|
||||
test('should return the correct embed url when given a youtube url with a start time parameter', () => {
|
||||
const url = 'https://www.youtube.com/watch?v=qajK1J1neAM&start=123';
|
||||
const errors = { video: '' };
|
||||
const result = formatYoutubeVideo(url, errors);
|
||||
expect(result).toBe('https://www.youtube.com/embed/qajK1J1neAM');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getEmbedId', () => {
|
||||
test('should return the correct embed id when the url contains "embed"', () => {
|
||||
const url = 'https://www.youtube.com/embed/qajK1J1neAM';
|
||||
const expectedEmbedId = 'qajK1J1neAM';
|
||||
|
||||
const result = getEmbedId(url);
|
||||
|
||||
expect(result).toBe(expectedEmbedId);
|
||||
});
|
||||
|
||||
test('should return an empty string when the url does not contain "watch" or "embed" and is not in the format "youtu.be/"', () => {
|
||||
const url = 'https://www.youtube.com/invalid-url';
|
||||
const expectedEmbedId = '';
|
||||
|
||||
const result = getEmbedId(url);
|
||||
|
||||
expect(result).toBe(expectedEmbedId);
|
||||
});
|
||||
|
||||
test('should return an empty string when the url is an empty string', () => {
|
||||
const url = '';
|
||||
const expectedEmbedId = '';
|
||||
|
||||
const result = getEmbedId(url);
|
||||
|
||||
expect(result).toBe(expectedEmbedId);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import genUniqueId from './genUniqueId';
|
||||
|
||||
describe('Generate Unique Ids', () => {
|
||||
test('should start with letter', () => {
|
||||
const result = genUniqueId();
|
||||
const firstChar = result.charAt(0);
|
||||
expect(firstChar).toMatch(/[a-zA-Z]/);
|
||||
});
|
||||
|
||||
test('should not contain special characters', () => {
|
||||
const result = genUniqueId();
|
||||
expect(result).toMatch(/^[a-zA-Z0-9]+$/);
|
||||
});
|
||||
|
||||
test('should return different ids on multiple calls', () => {
|
||||
const result1 = genUniqueId();
|
||||
const result2 = genUniqueId();
|
||||
expect(result1).not.toEqual(result2);
|
||||
});
|
||||
test('multiple calls in closer time frames should have same first 3 letters', () => {
|
||||
const result1 = genUniqueId();
|
||||
const result2 = genUniqueId();
|
||||
expect(result1.substring(0, 4)).toEqual(result2.substring(0, 4));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import generateSlug from './generateSlug';
|
||||
|
||||
describe('generateSlug', () => {
|
||||
test('should return a string with lowercase letters and hyphens when given a valid title', () => {
|
||||
const title = 'This is a Valid Title';
|
||||
const expected = 'this-is-a-valid-title' + `-${new Date().getTime()}`;
|
||||
const result = generateSlug(title);
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
test('should include the current timestamp at the end of the string', () => {
|
||||
const title = 'This is a Valid Title';
|
||||
const result = generateSlug(title);
|
||||
const timestamp = result.split('-').pop();
|
||||
expect(Number(timestamp)).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import generateUUID from './generateUUID';
|
||||
import { isUUID } from './isUUID';
|
||||
|
||||
// This test suite tests both the generateUUID and isUUID functions
|
||||
describe('GenerateUUID', () => {
|
||||
test('should be true when tested with the uuid function', () => {
|
||||
const result = generateUUID();
|
||||
expect(isUUID(result)).toBe(true);
|
||||
});
|
||||
|
||||
test('should generate unique UUIDs each time', () => {
|
||||
const uuid1 = generateUUID();
|
||||
const uuid2 = generateUUID();
|
||||
expect(uuid1).not.toBe(uuid2);
|
||||
});
|
||||
|
||||
test('should return true for a valid UUID', () => {
|
||||
const uuid = '123e4567-e89b-12d3-a456-426614174000';
|
||||
expect(isUUID(uuid)).toBe(true);
|
||||
});
|
||||
|
||||
test('should return false for an invalid UUID', () => {
|
||||
const uuid = 'invalid-uuid';
|
||||
expect(isUUID(uuid)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import getCurrencyFormatter from './getCurrencyFormatter';
|
||||
|
||||
describe('GetCurrencyFormatter', () => {
|
||||
test('should return a new instance of Intl.NumberFormat with the correct locale and currency options when currency is "NGN"', () => {
|
||||
const result = getCurrencyFormatter('NGN');
|
||||
expect(result).toBeInstanceOf(Intl.NumberFormat);
|
||||
expect(result.resolvedOptions().locale).toBe('en-NG');
|
||||
expect(result.resolvedOptions().currency).toBe('NGN');
|
||||
expect(result.resolvedOptions().minimumFractionDigits).toBe(2);
|
||||
});
|
||||
|
||||
test('should return a new instance of Intl.NumberFormat with the correct locale and currency options when currency is "USD"', () => {
|
||||
const result = getCurrencyFormatter('USD');
|
||||
expect(result).toBeInstanceOf(Intl.NumberFormat);
|
||||
expect(result.resolvedOptions().locale).toBe('en-US');
|
||||
expect(result.resolvedOptions().currency).toBe('USD');
|
||||
expect(result.resolvedOptions().minimumFractionDigits).toBe(2);
|
||||
});
|
||||
|
||||
test('should return a new instance of Intl.NumberFormat with the correct locale and currency options when currency is "EUR"', () => {
|
||||
const result = getCurrencyFormatter('EUR');
|
||||
expect(result).toBeInstanceOf(Intl.NumberFormat);
|
||||
expect(result.resolvedOptions().locale).toBe('en-US');
|
||||
expect(result.resolvedOptions().currency).toBe('EUR');
|
||||
expect(result.resolvedOptions().minimumFractionDigits).toBe(2);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { isObject } from './isObject';
|
||||
|
||||
describe('isObject', () => {
|
||||
test('should return true for an empty object', () => {
|
||||
const obj = {};
|
||||
expect(isObject(obj)).toBe(true);
|
||||
});
|
||||
|
||||
test('should return false for a non-object', () => {
|
||||
const obj = 'not an object';
|
||||
expect(isObject(obj)).toBe(false);
|
||||
});
|
||||
|
||||
test('should return true for a nested object', () => {
|
||||
const obj = { prop1: { prop2: 'value2' } };
|
||||
expect(isObject(obj)).toBe(true);
|
||||
});
|
||||
|
||||
test('should return true for an object with properties', () => {
|
||||
const obj = { prop1: 'value1', prop2: 'value2' };
|
||||
expect(isObject(obj)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,4 @@
|
||||
//
|
||||
export function isObject(obj) {
|
||||
return obj === Object(obj);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { genQuizPin, generateSitename } from './org';
|
||||
|
||||
describe('Generate Quiz Pin', () => {
|
||||
test('should return a random 6-digit pin', () => {
|
||||
const result = genQuizPin();
|
||||
expect(result.toString().length).toBe(6);
|
||||
});
|
||||
|
||||
test('should return random pin each time', () => {
|
||||
const result1 = genQuizPin();
|
||||
const result2 = genQuizPin();
|
||||
expect(result1).not.toBe(result2);
|
||||
});
|
||||
|
||||
test('should generate a pin between 100000 and 999999', () => {
|
||||
const result = genQuizPin();
|
||||
expect(result).toBeGreaterThanOrEqual(100000);
|
||||
expect(result).toBeLessThanOrEqual(999999);
|
||||
});
|
||||
|
||||
test('should not generate a negative pin', () => {
|
||||
const result = genQuizPin();
|
||||
expect(result).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
test('should generate an integer pin', () => {
|
||||
const result = genQuizPin();
|
||||
expect(Number.isInteger(result)).toBe(true);
|
||||
});
|
||||
|
||||
test('should not generate a zero pin', () => {
|
||||
const result = genQuizPin();
|
||||
expect(result).not.toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Generate Site name', () => {
|
||||
test('should return slug-like string', () => {
|
||||
const result = generateSitename('classroom org international');
|
||||
const expected = 'classroom-org-international';
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
test('should remove special characters', () => {
|
||||
const result = generateSitename('classroom@ org! international');
|
||||
const expected = 'classroom-org-international';
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
test('should return empty string when orgName is an empty string', () => {
|
||||
const result = generateSitename('');
|
||||
const expected = '';
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
|
||||
test('should return slug-like string with all uppercase characters converted to lowercase', () => {
|
||||
const result = generateSitename('Classroom Org International');
|
||||
const expected = 'classroom-org-international';
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { removeDuplicate } from './removeDuplicate';
|
||||
|
||||
describe('removeDuplicate', () => {
|
||||
test('should remove duplicate elements of an array', () => {
|
||||
const result = removeDuplicate([1, 1, 2, 3, 3, 4, 5]);
|
||||
const expected = [1, 2, 3, 4, 5];
|
||||
expect(result).toStrictEqual(expected);
|
||||
expect(result.length).toBe(5);
|
||||
});
|
||||
|
||||
test('should return an empty array', () => {
|
||||
const result = removeDuplicate([]);
|
||||
const expected = [];
|
||||
expect(result).toStrictEqual(expected);
|
||||
expect(result.length).toBe(0);
|
||||
});
|
||||
|
||||
test('should return an array with the same element', () => {
|
||||
const result = removeDuplicate([1]);
|
||||
const expected = [1];
|
||||
expect(result).toStrictEqual(expected);
|
||||
expect(result.length).toBe(1);
|
||||
});
|
||||
|
||||
test('should return an array with only one element', () => {
|
||||
const result = removeDuplicate([1, 1, 1, 1]);
|
||||
const expected = [1];
|
||||
expect(result).toStrictEqual(expected);
|
||||
expect(result.length).toBe(1);
|
||||
});
|
||||
|
||||
test('should return an array with the unique elements in the same order as the original array', () => {
|
||||
const result = removeDuplicate([1, 2, 3, 4, 5, 1, 2, 3, 4, 5]);
|
||||
const expected = [1, 2, 3, 4, 5];
|
||||
expect(result).toStrictEqual(expected);
|
||||
expect(result.length).toBe(5);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import showAppsSideBar from './showAppsSideBar';
|
||||
describe('ShowAppSideBar', () => {
|
||||
test("should return true when path includes '/lessons/' and does not include 'landingpage'", () => {
|
||||
const path = '/lessons/example';
|
||||
const result = showAppsSideBar(path);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
test("should return false when path does not include '/lessons/'", () => {
|
||||
const path = '/home';
|
||||
const result = showAppsSideBar(path);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
test("should return false when path includes 'landingpage'", () => {
|
||||
const path = '/lessons/landingpage';
|
||||
const result = showAppsSideBar(path);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
test('should return false when path is empty', () => {
|
||||
const path = '';
|
||||
const result = showAppsSideBar(path);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { capitalizeFirstLetter } from './string';
|
||||
|
||||
describe('capitalize first letter', () => {
|
||||
test('should return the same string with the first letter capitalized', () => {
|
||||
const result = capitalizeFirstLetter('classroom');
|
||||
expect(result).toEqual('Classroom');
|
||||
});
|
||||
|
||||
test('should return an empty string when given an empty string', () => {
|
||||
const result = capitalizeFirstLetter('');
|
||||
expect(result).toEqual('');
|
||||
});
|
||||
|
||||
test('should return the same string when given a string with all uppercase letters', () => {
|
||||
const result = capitalizeFirstLetter('UPPERCASE');
|
||||
expect(result).toEqual('UPPERCASE');
|
||||
});
|
||||
|
||||
test('should return the same string when given a string with a non-alphabetical first character', () => {
|
||||
const result = capitalizeFirstLetter('123abc');
|
||||
expect(result).toEqual('123abc');
|
||||
});
|
||||
|
||||
test('should return the first letter of the first word capitalized when given a sentence', () => {
|
||||
const result = capitalizeFirstLetter('classroomio is an open source project');
|
||||
expect(result).toEqual('Classroomio is an open source project');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { validateEmail } from './validateEmail';
|
||||
|
||||
describe('validate email', () => {
|
||||
test('should return true for a valid email format', () => {
|
||||
const result = validateEmail('[email protected]');
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should return false for an empty email', () => {
|
||||
const result = validateEmail('');
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should return true for a valid email with uppercase letters', () => {
|
||||
const result = validateEmail('[email protected]');
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should return false for an invalid email format', () => {
|
||||
const result = validateEmail('test@example');
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should return true for a valid email with special characters', () => {
|
||||
const result = validateEmail('[email protected]');
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,11 @@
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true
|
||||
"strict": true,
|
||||
"target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": false
|
||||
}
|
||||
|
||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||
|
||||
Generated
+1816
-28
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user