From b9406a492d49a4a30991792f6b2e24a2c149c853 Mon Sep 17 00:00:00 2001 From: Seb <144435+rmtsrc@users.noreply.github.com> Date: Sun, 18 Jun 2023 17:24:39 +0100 Subject: [PATCH] feat(new-tool): percentage calculator (#456) * feat(new tool): percentage calculator * Apply suggestions from code review Co-authored-by: Corentin THOMASSET --------- Co-authored-by: Corentin THOMASSET --- components.d.ts | 1 + src/tools/index.ts | 3 +- src/tools/percentage-calculator/index.ts | 12 +++ .../percentage-calculator.e2e.spec.ts | 36 +++++++++ .../percentage-calculator.vue | 78 +++++++++++++++++++ 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/tools/percentage-calculator/index.ts create mode 100644 src/tools/percentage-calculator/percentage-calculator.e2e.spec.ts create mode 100644 src/tools/percentage-calculator/percentage-calculator.vue diff --git a/components.d.ts b/components.d.ts index dbbeb8a0..0c49b7bb 100644 --- a/components.d.ts +++ b/components.d.ts @@ -135,6 +135,7 @@ declare module '@vue/runtime-core' { NUpload: typeof import('naive-ui')['NUpload'] NUploadDragger: typeof import('naive-ui')['NUploadDragger'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] + PercentageCalculator: typeof import('./src/tools/percentage-calculator/percentage-calculator.vue')['default'] PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default'] QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default'] RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default'] diff --git a/src/tools/index.ts b/src/tools/index.ts index 319ac113..4c3caa62 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -33,6 +33,7 @@ import { tool as dateTimeConverter } from './date-time-converter'; import { tool as deviceInformation } from './device-information'; import { tool as cypher } from './encryption'; import { tool as etaCalculator } from './eta-calculator'; +import { tool as percentageCalculator } from './percentage-calculator'; import { tool as gitMemo } from './git-memo'; import { tool as hashText } from './hash-text'; import { tool as hmacGenerator } from './hmac-generator'; @@ -126,7 +127,7 @@ export const toolsByCategory: ToolCategory[] = [ }, { name: 'Math', - components: [mathEvaluator, etaCalculator], + components: [mathEvaluator, etaCalculator, percentageCalculator], }, { name: 'Measurement', diff --git a/src/tools/percentage-calculator/index.ts b/src/tools/percentage-calculator/index.ts new file mode 100644 index 00000000..736f5706 --- /dev/null +++ b/src/tools/percentage-calculator/index.ts @@ -0,0 +1,12 @@ +import { Percentage } from '@vicons/tabler'; +import { defineTool } from '../tool'; + +export const tool = defineTool({ + name: 'Percentage calculator', + path: '/percentage-calculator', + description: 'Easily calculate percentages from a value to another value, or from a percentage to a value.', + keywords: ['percentage', 'calculator', 'calculate', 'value', 'number', '%'], + component: () => import('./percentage-calculator.vue'), + icon: Percentage, + createdAt: new Date('2023-06-18'), +}); diff --git a/src/tools/percentage-calculator/percentage-calculator.e2e.spec.ts b/src/tools/percentage-calculator/percentage-calculator.e2e.spec.ts new file mode 100644 index 00000000..a8ef2d48 --- /dev/null +++ b/src/tools/percentage-calculator/percentage-calculator.e2e.spec.ts @@ -0,0 +1,36 @@ +import { expect, test } from '@playwright/test'; + +test.describe('Tool - Percentage calculator', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/percentage-calculator'); + }); + + test('Has correct title', async ({ page }) => { + await expect(page).toHaveTitle('Percentage calculator - IT Tools'); + }); + + test('Correctly works out percentages', async ({ page }) => { + await page.getByTestId('percentageX').locator('input').fill('123'); + await page.getByTestId('percentageY').locator('input').fill('456'); + await expect(page.getByTestId('percentageResult').locator('input')).toHaveValue('560.88'); + + await page.getByTestId('numberX').locator('input').fill('123'); + await page.getByTestId('numberY').locator('input').fill('456'); + await expect(page.getByTestId('numberResult').locator('input')).toHaveValue('26.973684210526315'); + + await page.getByTestId('numberFrom').locator('input').fill('123'); + await page.getByTestId('numberTo').locator('input').fill('456'); + await expect(page.getByTestId('percentageIncreaseDecrease').locator('input')).toHaveValue('270.7317073170732'); + }); + + test('Displays empty results for incomplete input', async ({ page }) => { + await page.getByTestId('percentageX').locator('input').fill('123'); + await expect(page.getByTestId('percentageResult').locator('input')).toHaveValue(''); + + await page.getByTestId('numberY').locator('input').fill('456'); + await expect(page.getByTestId('numberResult').locator('input')).toHaveValue(''); + + await page.getByTestId('numberFrom').locator('input').fill('123'); + await expect(page.getByTestId('percentageIncreaseDecrease').locator('input')).toHaveValue(''); + }); +}); diff --git a/src/tools/percentage-calculator/percentage-calculator.vue b/src/tools/percentage-calculator/percentage-calculator.vue new file mode 100644 index 00000000..c0362d20 --- /dev/null +++ b/src/tools/percentage-calculator/percentage-calculator.vue @@ -0,0 +1,78 @@ + + +