-
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.
- Loading branch information
0 parents
commit 0001c7e
Showing
21 changed files
with
2,612 additions
and
0 deletions.
There are no files selected for viewing
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,39 @@ | ||
name: Build | ||
on: | ||
push: | ||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node-version: [20.x] | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Cache node modules | ||
uses: actions/cache@v4 | ||
with: | ||
path: ~/.npm | ||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | ||
restore-keys: | | ||
${{ runner.os }}-node- | ||
- name: Node ${{ matrix.node-version }} | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
|
||
- name: Run tests & linter | ||
run: | | ||
yarn install | ||
yarn run lint && npm run check | ||
yarn run test:ci | ||
- name: Upload coverage to Codecov | ||
uses: codecov/codecov-action@v4 | ||
with: | ||
token: ${{ secrets.CODECOV_TOKEN }} |
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,21 @@ | ||
node_modules | ||
|
||
# Output | ||
.output | ||
.vercel | ||
/.svelte-kit | ||
/build | ||
|
||
# OS | ||
.DS_Store | ||
Thumbs.db | ||
|
||
# Env | ||
.env | ||
.env.* | ||
!.env.example | ||
!.env.test | ||
|
||
# Vite | ||
vite.config.js.timestamp-* | ||
vite.config.ts.timestamp-* |
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 @@ | ||
engine-strict=true |
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,4 @@ | ||
# Package Managers | ||
package-lock.json | ||
pnpm-lock.yaml | ||
yarn.lock |
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,17 @@ | ||
{ | ||
"useTabs": true, | ||
"singleQuote": true, | ||
"tabWidth": 2, | ||
"semi": false, | ||
"trailingComma": "none", | ||
"printWidth": 100, | ||
"plugins": ["prettier-plugin-svelte"], | ||
"overrides": [ | ||
{ | ||
"files": "*.svelte", | ||
"options": { | ||
"parser": "svelte" | ||
} | ||
} | ||
] | ||
} |
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,8 @@ | ||
{ | ||
"editor.codeActionsOnSave": { | ||
"source.fixAll.eslint": "explicit" | ||
}, | ||
"editor.formatOnSave": true, | ||
"editor.tabSize": 2, | ||
"eslint.validate": ["javascript", "javascriptreact", "svelte"], | ||
} |
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,62 @@ | ||
|
||
# Conversor en Svelte | ||
|
||
Este proyecto representa el clásico ejemplo del conversor de millas a kilómetros, generado con [`sv`](https://github.com/sveltejs/cli), con las siguientes configuraciones: | ||
|
||
- Typescript | ||
- ESlint + prettier + vitest | ||
- agregamos plugins de testing library para tests de front | ||
- y manejamos las dependencias con yarn (es mucho más rápido que usar npm) | ||
|
||
## Implementación | ||
|
||
- El input millas se define como number para evitar valores alfabéticos incorrectos | ||
- También tiene un **binding** contra el estado (la runa `$.state`), llamado _miles_ | ||
- Como los kilómetros se definen en función de las millas, utilizamos la runa `$derived`. Esto automáticamente recalcula el valor cuando cambiamos las millas | ||
- De yapa, utilizamos una función que muestra los kilómetros en formato coma decimal | ||
- Como solo tenemos una página, ubicamos dentro de la carpeta `src/routes` el archivo `+page.svelte` que la define como página principal de nuestra SPA (single page application) | ||
|
||
Lo bueno es que Svelte necesita de esos pocos conceptos dentro de nuestra página: | ||
|
||
```sv | ||
<script lang="ts"> | ||
import { convertMilesToKms } from '$lib' | ||
const formattedNumber = (value: number) => value.toLocaleString('es'); | ||
let miles = $state(0) | ||
let kilometers = $derived(formattedNumber(convertMilesToKms(miles))) | ||
... | ||
</script> | ||
<div class="form"> | ||
... | ||
<div class="row"> | ||
<input type='number' data-testid='millas' bind:value={miles} /> | ||
</div> | ||
<div class="row"> | ||
<span data-testid="kilometers">{kilometers}</span> | ||
``` | ||
|
||
### Botón reset | ||
|
||
Para resetear el valor de las millas contamos con un botón al que le asociamos una función que cambia el estado de millas: | ||
|
||
```sv | ||
<script lang="ts"> | ||
... | ||
const reset = () => { miles = 0 } | ||
</script> | ||
<button class="button secondary" data-testid="reset" onclick={reset}>Resetear</button> | ||
``` | ||
|
||
## Tests | ||
|
||
La propiedad `data-testid` nos sirve para encontrar fácilmente los elementos del DOM y probar | ||
|
||
- que inicialmente el valor del input millas es 0 | ||
- que podemos convertir exitosamente de millas a kilómetros (y también verificamos que la conversión se haga respetando el locale castellano con la coma decimal) | ||
- y por último probamos el botón de Reset | ||
|
||
El lector puede ver los tests y su configuración con Testing Library. |
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,52 @@ | ||
// eslint.config.cjs | ||
|
||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended' | ||
import eslintPluginSvelte from 'eslint-plugin-svelte' | ||
import js from '@eslint/js' | ||
import svelteParser from 'svelte-eslint-parser' | ||
import tsEslint from 'typescript-eslint' | ||
import tsParser from '@typescript-eslint/parser' | ||
|
||
export default [ | ||
js.configs.recommended, | ||
...tsEslint.configs.strict, | ||
...eslintPluginSvelte.configs['flat/recommended'], | ||
eslintPluginPrettierRecommended, // must be last to override conflicting rules. | ||
{ | ||
rules: { | ||
semi: ['warn', 'always'], | ||
quotes: ['warn', 'single', { avoidEscape: true, allowTemplateLiterals: true }], | ||
'semi': 'error', | ||
'no-nested-ternary': 'error', | ||
'linebreak-style': ['error', 'unix'], | ||
'no-cond-assign': ['error', 'always'], | ||
'no-console': 'error', | ||
'@typescript-eslint/sort-type-constituents': 'error', | ||
'sort-imports': [ | ||
'error', | ||
{ | ||
ignoreCase: true, | ||
ignoreDeclarationSort: false, | ||
ignoreMemberSort: false, | ||
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], | ||
allowSeparatedGroups: true | ||
} | ||
] | ||
} | ||
}, | ||
{ | ||
files: ['**/*.svelte'], | ||
languageOptions: { | ||
parser: svelteParser, | ||
parserOptions: { | ||
parser: tsParser | ||
} | ||
}, | ||
rules: { | ||
'svelte/no-target-blank': 'error', | ||
'svelte/no-at-debug-tags': 'error', | ||
'svelte/no-reactive-functions': 'error', | ||
'svelte/no-reactive-literals': 'error' | ||
} | ||
} | ||
] |
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,40 @@ | ||
{ | ||
"name": "eg-conversor-svelte", | ||
"version": "0.0.1", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite dev", | ||
"build": "vite build", | ||
"preview": "vite preview", | ||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", | ||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", | ||
"format": "prettier --write .", | ||
"lint": "eslint && prettier --check .", | ||
"lint:fix": "eslint && prettier --write .", | ||
"test:unit": "vitest", | ||
"test": "npm run test:unit -- --run", | ||
"test:ci": "npm run test:unit -- --run --coverage" | ||
}, | ||
"devDependencies": { | ||
"@sveltejs/adapter-auto": "^3.0.0", | ||
"@sveltejs/kit": "^2.0.0", | ||
"@sveltejs/vite-plugin-svelte": "^4.0.0", | ||
"@testing-library/jest-dom": "^6.6.3", | ||
"@testing-library/svelte": "^5.2.4", | ||
"@testing-library/user-event": "^14.5.2", | ||
"@types/eslint": "^9.6.0", | ||
"eslint": "^9.7.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-svelte": "^2.36.0", | ||
"globals": "^15.0.0", | ||
"jsdom": "^25.0.1", | ||
"prettier": "^3.3.2", | ||
"prettier-plugin-svelte": "^3.2.6", | ||
"svelte": "^5.0.0", | ||
"svelte-check": "^4.0.0", | ||
"typescript": "^5.0.0", | ||
"typescript-eslint": "^8.0.0", | ||
"vite": "^5.0.3", | ||
"vitest": "^2.0.4" | ||
} | ||
} |
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,13 @@ | ||
// See https://svelte.dev/docs/kit/types#app.d.ts | ||
// for information about these interfaces | ||
declare global { | ||
namespace App { | ||
// interface Error {} | ||
// interface Locals {} | ||
// interface PageData {} | ||
// interface PageState {} | ||
// interface Platform {} | ||
} | ||
} | ||
|
||
export {} |
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,18 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
|
||
<link rel="preconnect" href="https://fonts.googleapis.com"> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
<link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet"> | ||
<link rel="icon" type="image/x-icon" href="favicon.ico"> | ||
|
||
%sveltekit.head% | ||
</head> | ||
<body data-sveltekit-preload-data="hover"> | ||
<div style="display: contents">%sveltekit.body%</div> | ||
</body> | ||
</html> |
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,42 @@ | ||
import { describe, it, expect } from 'vitest' | ||
import { fireEvent, render, screen } from '@testing-library/svelte' | ||
import userEvent from '@testing-library/user-event' | ||
|
||
import Conversor from './routes/+page.svelte' | ||
|
||
describe('Conversor', () => { | ||
|
||
it('should start with 0 miles & kilometers', () => { | ||
render(Conversor) | ||
|
||
const miles = screen.getByTestId('millas') as HTMLInputElement | ||
expect(miles.value).to.equal('0') | ||
|
||
const kilometers = screen.getByTestId('kilometers') | ||
expect(+kilometers.innerHTML).to.equal(0) | ||
}) | ||
|
||
it('should convert valid miles to kilometers to locale es', async () => { | ||
render(Conversor) | ||
|
||
const miles = screen.getByTestId('millas') as HTMLInputElement | ||
await userEvent.type(miles, '100') | ||
const kilometers = screen.getByTestId('kilometers') | ||
expect(kilometers.innerHTML).to.equal('160,934') | ||
}) | ||
|
||
it('reset puts miles value back to zero', async () => { | ||
render(Conversor) | ||
|
||
const miles = screen.getByTestId('millas') as HTMLInputElement | ||
await userEvent.type(miles, '100') | ||
const user = userEvent.setup() | ||
|
||
await user.click(screen.getByTestId('reset')) | ||
|
||
expect(miles.value).to.equal('0') | ||
const kilometers = screen.getByTestId('kilometers') | ||
expect(kilometers.innerHTML).to.equal('0') | ||
}) | ||
|
||
}) |
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,2 @@ | ||
// place files you want to import through the `$lib` alias in this folder. | ||
export const convertMilesToKms = (millas: number) => millas * 1.609344 |
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 @@ | ||
<script lang="ts"> | ||
import './styles.css' | ||
import { convertMilesToKms } from '$lib' | ||
const formattedNumber = (value: number) => value.toLocaleString('es'); | ||
let miles = $state(0) | ||
let kilometers = $derived(formattedNumber(convertMilesToKms(miles))) | ||
const reset = () => { miles = 0 } | ||
</script> | ||
|
||
<div class="form"> | ||
<h1>Conversor millas a kms</h1> | ||
<div class="row"> | ||
<label for="millas" class="label">Millas</label> | ||
<input type='number' data-testid='millas' bind:value={miles} /> | ||
</div> | ||
<div class="row"> | ||
<label for="kilometros" class="label">Kilómetros</label> | ||
<span data-testid="kilometers">{kilometers}</span> | ||
</div> | ||
<div class="row"> | ||
<button class="button secondary" data-testid="reset" onclick={reset}>Resetear</button> | ||
</div> | ||
</div> |
Oops, something went wrong.