forked from oliverschwendener/ueli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: currency conversion (oliverschwendener#1215)
- Loading branch information
1 parent
e8803eb
commit 6f5b95f
Showing
5 changed files
with
157 additions
and
15 deletions.
There are no files selected for viewing
84 changes: 84 additions & 0 deletions
84
src/main/Extensions/CurrencyConversion/CurrencyConversion.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import type { AssetPathResolver } from "@Core/AssetPathResolver"; | ||
import { describe, expect, it, vi } from "vitest"; | ||
import { CurrencyConversion } from "./CurrencyConversion"; | ||
import type { Rates } from "./Rates"; | ||
|
||
describe(CurrencyConversion, () => { | ||
describe(CurrencyConversion.prototype.getInstantSearchResultItems, () => { | ||
const testSuccessfulConversion = ({ | ||
expectedResult, | ||
userInput, | ||
rates, | ||
}: { | ||
expectedResult: string; | ||
userInput: string; | ||
rates: Rates; | ||
}) => { | ||
const imageFilePath = "/path/to/image"; | ||
const getExtensionAssetPathMock = vi.fn().mockReturnValue(imageFilePath); | ||
|
||
const assetPathResolver = <AssetPathResolver>{ | ||
getExtensionAssetPath: (i, f) => getExtensionAssetPathMock(i, f), | ||
getModuleAssetPath: () => null, | ||
}; | ||
|
||
const currencyConversion = new CurrencyConversion(null, null, assetPathResolver); | ||
|
||
currencyConversion["rates"] = rates; | ||
|
||
const actual = currencyConversion.getInstantSearchResultItems(userInput); | ||
|
||
expect(actual[0].name).toEqual(expectedResult); | ||
expect(actual[0].image).toEqual({ url: `file://${imageFilePath}` }); | ||
expect(getExtensionAssetPathMock).toHaveBeenCalledWith(currencyConversion.id, "currency-conversion.png"); | ||
}; | ||
|
||
it("should return empty array when user input does not contain 4 parts", () => { | ||
const currencyConversion = new CurrencyConversion(null, null, null); | ||
|
||
currencyConversion["rates"] = { chf: { usd: 2 } }; | ||
|
||
expect(currencyConversion.getInstantSearchResultItems("1 CHF to")).toEqual([]); | ||
}); | ||
|
||
it("should return empty array when first part in user input is not numerical", () => { | ||
const currencyConversion = new CurrencyConversion(null, null, null); | ||
|
||
currencyConversion["rates"] = { chf: { usd: 2 } }; | ||
|
||
expect(currencyConversion.getInstantSearchResultItems("abc CHF to USD")).toEqual([]); | ||
}); | ||
|
||
it("should return empty array when base currency does not exist", () => { | ||
const currencyConversion = new CurrencyConversion(null, null, null); | ||
|
||
currencyConversion["rates"] = { chf: { usd: 2 } }; | ||
|
||
expect(currencyConversion.getInstantSearchResultItems("1 EUR to USD")).toEqual([]); | ||
}); | ||
|
||
it("should return empty array when second part of user input is not 'in' or 'to'", () => { | ||
const currencyConversion = new CurrencyConversion(null, null, null); | ||
|
||
currencyConversion["rates"] = { chf: { usd: 2 } }; | ||
|
||
expect(currencyConversion.getInstantSearchResultItems("1 CHF inn USD")).toEqual([]); | ||
expect(currencyConversion.getInstantSearchResultItems("1 CHF t USD")).toEqual([]); | ||
}); | ||
|
||
it("should return empty array when target currency is not found", () => { | ||
const currencyConversion = new CurrencyConversion(null, null, null); | ||
|
||
currencyConversion["rates"] = { chf: { usd: 2 } }; | ||
|
||
expect(currencyConversion.getInstantSearchResultItems("1 CHF to EUR")).toEqual([]); | ||
}); | ||
|
||
it("should convert currencies based on the rates when user input matches expected pattern", () => { | ||
const rates: Rates = { chf: { usd: 2, eur: 0.5 } }; | ||
|
||
testSuccessfulConversion({ expectedResult: "2.00 USD", userInput: "1 CHF to USD", rates }); | ||
testSuccessfulConversion({ expectedResult: "0.50 EUR", userInput: "1 CHF in EUR", rates }); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export type Rates = Record<string, Record<string, number>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { describe, expect, it } from "vitest"; | ||
import { convert } from "./convert"; | ||
import type { Rates } from "./Rates"; | ||
|
||
describe(convert, () => { | ||
it("should convert the base currency to the target according to the rates", () => { | ||
const rates: Rates = { | ||
chf: { | ||
usd: 2, | ||
eur: 0.5, | ||
}, | ||
usd: { | ||
chf: 0.5, | ||
eur: 0.25, | ||
}, | ||
}; | ||
|
||
expect(convert({ base: "CHF", rates, target: "USD", value: 1 })).toEqual({ result: 2, target: "USD" }); | ||
expect(convert({ base: "CHF", rates, target: "EUR", value: 10 })).toEqual({ result: 5, target: "EUR" }); | ||
}); | ||
|
||
it("should throw an error if the base currency is not found", () => { | ||
expect(() => convert({ base: "CHF", rates: { usd: { chf: 0.5 } }, target: "USD", value: 1 })).toThrowError( | ||
"Base currency not found", | ||
); | ||
}); | ||
|
||
it("should throw an error if the target currency is not found", () => { | ||
expect(() => convert({ base: "CHF", rates: { chf: { eur: 0.5 } }, target: "USD", value: 1 })).toThrowError( | ||
"Target currency not found", | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type { Rates } from "./Rates"; | ||
|
||
export const convert = ({ | ||
value, | ||
base, | ||
target, | ||
rates, | ||
}: { | ||
value: number; | ||
base: string; | ||
target: string; | ||
rates: Rates; | ||
}): { result: number; target: string } => { | ||
if (!Object.keys(rates).includes(base.toLowerCase())) { | ||
throw new Error("Base currency not found"); | ||
} | ||
|
||
if (!Object.keys(rates[base.toLowerCase()]).includes(target.toLowerCase())) { | ||
throw new Error("Target currency not found"); | ||
} | ||
|
||
return { | ||
result: value * rates[base.toLowerCase()][target.toLowerCase()], | ||
target, | ||
}; | ||
}; |