Skip to content

Commit

Permalink
Added task Отмеченные Email-ы
Browse files Browse the repository at this point in the history
  • Loading branch information
jsru-1 committed Dec 24, 2024
1 parent 60fb987 commit f827d6c
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 0 deletions.
3 changes: 3 additions & 0 deletions 02-basics-2/40-marked-emails/MarkedEmailsApp.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.marked {
color: #efc14e;
}
52 changes: 52 additions & 0 deletions 02-basics-2/40-marked-emails/MarkedEmailsApp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { computed, defineComponent, ref } from 'vue'

// Значения взяты из https://jsonplaceholder.typicode.com/comments
export const emails = [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
]

export default defineComponent({
name: 'MarkedEmailsApp',

setup() {},

template: `
<div>
<div class="form-group">
<input type="search" aria-label="Search" />
</div>
<ul aria-label="Emails">
<li>
[email protected]
</li>
<li class="marked">
[email protected]
</li>
</ul>
</div>
`,
})
29 changes: 29 additions & 0 deletions 02-basics-2/40-marked-emails/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Отмеченные Email-ы

👷🏻 _Задача нормальной сложности_\
📚 _Закрепление материала_

<!--start_statement-->

Требуется создать Vue приложение, которое выводит список Email-ов из массива `emails` и позволяет выполнять поиск по
этому списку. Адреса в списке, содержащие строку поиска, должны выделяться классом `.marked`.

_**Примечание:** задачу можно решить, проверяя Email прямо в шаблоне. Но в этом случае решение получается менее декларативным, возможно, с перегруженным шаблоном. Попробуйте
использовать **вычисляемое свойство** `computed` так, чтобы в шаблоне можно было сразу вывести Email и знать, требуется ли ему маркировка._

### Результат

<img src="https://i.imgur.com/DA8l8pP.gif" alt="Example">

<!--end_statement-->

---

### Инструкция

📝 Для решения задачи отредактируйте файл: `MarkedEmailsApp.js`.

🚀 Команда запуска для ручного тестирования: `npm run dev`\
Приложение будет доступно на [http://localhost:5173/02-basics-2/40-marked-emails/](http://localhost:5173/02-basics-2/40-marked-emails/).

✅ Доступно автоматическое тестирование: `npm test marked-emails`
43 changes: 43 additions & 0 deletions 02-basics-2/40-marked-emails/__tests__/marked-emails.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { describe, it, expect, beforeEach } from 'vitest'
import { mount } from '@vue/test-utils'
import type { VueWrapper, DOMWrapper } from '@vue/test-utils'
import MarkedEmailsApp, { emails } from '@/MarkedEmailsApp.js'

describe('MarkedEmailsApp', () => {
let wrapper: VueWrapper
let input: DOMWrapper<HTMLInputElement>
let list: DOMWrapper<HTMLElement>[]

beforeEach(() => {
wrapper = mount(MarkedEmailsApp)
input = wrapper.find('input[aria-label="Search"]')
list = wrapper.findAll('ul[aria-label="Emails"] li')
})

it('должно рендерить поле поиска и список Email-ов', () => {
expect(wrapper.exists()).toBe(true)
expect(list).toHaveLength(emails.length)
for (let i = 0; i < emails.length; i++) {
expect(list[i].text()).toBe(emails[i])
}
})

it('не должно отмечать ни один email классом маркировки .marked, когда запрос поиска пустой', async () => {
expect(list.every(item => item.classes('marked'))).toBeFalsy()
})

it('должно отмечать [email protected] и [email protected] классом маркировки .marked при поиске "all"', async () => {
await input.setValue('all')
expect(list).toHaveLength(emails.length)
for (let i = 0; i < emails.length; i++) {
const shouldMark = emails[i].includes('all')
expect(list[i].classes('marked')).toBe(shouldMark)
}
})

it('должно отметить все email-ы классом маркировки .marked, когда запрос поиска "@"', async () => {
await input.setValue('@')
expect(list).toHaveLength(emails.length)
expect(list.every(item => item.classes('marked'))).toBeTruthy()
})
})
16 changes: 16 additions & 0 deletions 02-basics-2/40-marked-emails/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>marked-emails</title>
</head>
<body>
<div class="wrapper">
<div class="container">
<h1>Отмеченные Email-ы</h1>
<div id="app"></div>
</div>
</div>
<script type="module" src="./main.js"></script>
</body>
</html>
6 changes: 6 additions & 0 deletions 02-basics-2/40-marked-emails/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import '@shgk/vue-course-ui/meetups/style.css'
import { createApp } from 'vue'
import MarkedEmailsApp from './MarkedEmailsApp.js'
import './MarkedEmailsApp.css'

createApp(MarkedEmailsApp).mount('#app')
11 changes: 11 additions & 0 deletions 02-basics-2/40-marked-emails/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "@shgk/vue-course-taskbook/configs/tsconfig.json",
"include": ["**/*", "**/*.vue"],
"files": [],
"compilerOptions": {
"outDir": "dist",
"paths": {
"@/*": ["./*"]
}
}
}

0 comments on commit f827d6c

Please sign in to comment.