mirror of
https://github.com/spliit-app/spliit.git
synced 2025-12-06 01:19:29 +01:00
Fix amount preview for scanned receipts (#227)
* no division of amount * use gpt-4-turbo * testing setup and naive test * test multiple variants * document * correct locale names * test large amounts * test wth strings * prettier
This commit is contained in:
18
jest.config.ts
Normal file
18
jest.config.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import type { Config } from 'jest'
|
||||||
|
import nextJest from 'next/jest.js'
|
||||||
|
|
||||||
|
const createJestConfig = nextJest({
|
||||||
|
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
|
||||||
|
dir: './',
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add any custom config to be passed to Jest
|
||||||
|
const config: Config = {
|
||||||
|
coverageProvider: 'v8',
|
||||||
|
testEnvironment: 'jsdom',
|
||||||
|
// Add more setup options before each test is run
|
||||||
|
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||||
|
}
|
||||||
|
|
||||||
|
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
|
||||||
|
export default createJestConfig(config)
|
||||||
4080
package-lock.json
generated
4080
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -12,7 +12,8 @@
|
|||||||
"prettier": "prettier -w src",
|
"prettier": "prettier -w src",
|
||||||
"postinstall": "prisma migrate deploy && prisma generate",
|
"postinstall": "prisma migrate deploy && prisma generate",
|
||||||
"build-image": "./scripts/build-image.sh",
|
"build-image": "./scripts/build-image.sh",
|
||||||
"start-container": "docker compose --env-file container.env up"
|
"start-container": "docker compose --env-file container.env up",
|
||||||
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formatjs/intl-localematcher": "^0.5.4",
|
"@formatjs/intl-localematcher": "^0.5.4",
|
||||||
@@ -62,8 +63,12 @@
|
|||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@testing-library/dom": "^10.4.0",
|
||||||
|
"@testing-library/jest-dom": "^6.4.8",
|
||||||
|
"@testing-library/react": "^16.0.0",
|
||||||
"@total-typescript/ts-reset": "^0.5.1",
|
"@total-typescript/ts-reset": "^0.5.1",
|
||||||
"@types/content-disposition": "^0.5.8",
|
"@types/content-disposition": "^0.5.8",
|
||||||
|
"@types/jest": "^29.5.12",
|
||||||
"@types/negotiator": "^0.6.3",
|
"@types/negotiator": "^0.6.3",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/pg": "^8.10.9",
|
"@types/pg": "^8.10.9",
|
||||||
@@ -74,10 +79,13 @@
|
|||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "^14.1.0",
|
"eslint-config-next": "^14.1.0",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.0.3",
|
||||||
"prettier-plugin-organize-imports": "^3.2.3",
|
"prettier-plugin-organize-imports": "^3.2.3",
|
||||||
"tailwindcss": "^3",
|
"tailwindcss": "^3",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
"tsconfig-paths": "^4.2.0",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export async function extractExpenseInformationFromImage(imageUrl: string) {
|
|||||||
const categories = await getCategories()
|
const categories = await getCategories()
|
||||||
|
|
||||||
const body: ChatCompletionCreateParamsNonStreaming = {
|
const body: ChatCompletionCreateParamsNonStreaming = {
|
||||||
model: 'gpt-4-vision-preview',
|
model: 'gpt-4-turbo',
|
||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
role: 'user',
|
role: 'user',
|
||||||
|
|||||||
66
src/lib/utils.test.ts
Normal file
66
src/lib/utils.test.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { formatCurrency } from './utils'
|
||||||
|
|
||||||
|
describe('formatCurrency', () => {
|
||||||
|
const currency = 'CUR'
|
||||||
|
/** For testing decimals */
|
||||||
|
const partialAmount = 1.23
|
||||||
|
/** For testing small full amounts */
|
||||||
|
const smallAmount = 1
|
||||||
|
/** For testing large full amounts */
|
||||||
|
const largeAmount = 10000
|
||||||
|
|
||||||
|
/** Non-breaking space */
|
||||||
|
const nbsp = '\xa0'
|
||||||
|
|
||||||
|
interface variation {
|
||||||
|
amount: number
|
||||||
|
locale: string
|
||||||
|
result: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variations to be tested, chosen as follows
|
||||||
|
* - `en-US` is a very common i18n fallback
|
||||||
|
* - `de-DE` exhibited faulty behavior in previous versions
|
||||||
|
*/
|
||||||
|
const variations: variation[] = [
|
||||||
|
{
|
||||||
|
amount: partialAmount,
|
||||||
|
locale: `en-US`,
|
||||||
|
result: `${currency}1.23`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: smallAmount,
|
||||||
|
locale: `en-US`,
|
||||||
|
result: `${currency}1.00`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: largeAmount,
|
||||||
|
locale: `en-US`,
|
||||||
|
result: `${currency}10,000.00`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: partialAmount,
|
||||||
|
locale: `de-DE`,
|
||||||
|
result: `1,23${nbsp}${currency}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: smallAmount,
|
||||||
|
locale: `de-DE`,
|
||||||
|
result: `1,00${nbsp}${currency}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: largeAmount,
|
||||||
|
locale: `de-DE`,
|
||||||
|
result: `10.000,00${nbsp}${currency}`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const variation of variations) {
|
||||||
|
it(`formats ${variation.amount} in ${variation.locale}`, () => {
|
||||||
|
expect(formatCurrency(currency, variation.amount, variation.locale)).toBe(
|
||||||
|
variation.result,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -40,7 +40,7 @@ export function formatCurrency(
|
|||||||
// '€' will be placed in correct position
|
// '€' will be placed in correct position
|
||||||
currency: 'EUR',
|
currency: 'EUR',
|
||||||
})
|
})
|
||||||
const formattedAmount = format.format(amount / 100)
|
const formattedAmount = format.format(amount)
|
||||||
return formattedAmount.replace('€', currency)
|
return formattedAmount.replace('€', currency)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user