Skip to content

Commit 83adf78

Browse files
committed
feat: tests/specification for range
1 parent 1d653ab commit 83adf78

File tree

3 files changed

+225
-4
lines changed

3 files changed

+225
-4
lines changed

docs/ru/inputs/input-range.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<script setup>
2+
import {FormField, Form, useFormValues} from '../../../src';
3+
4+
const form = new Form();
5+
const values = useFormValues(form);
6+
7+
</script>
8+
9+
# Поле number
10+
11+
Поле используется для ввода численных значений.
12+
13+
- Ключевое слово `range`.
14+
- WhatWG [Спецификация](https://html.spec.whatwg.org/multipage/input.html#range-state-(type=range)).
15+
16+
17+
## Параметры
18+
19+
### autofocus <Badge type = "info">Необязательный</Badge>
20+
21+
- Тип `boolean | 'true' | 'false'`
22+
23+
Если данный параметр передаётся, при установке данного поля, на него будет автоматически передано управление.
24+
25+
### step <Badge type = "info">Необязательный</Badge>
26+
- Тип `number | string`
27+
Данное поле имеет механизм увеличения или уменьшения введённого числа на 1. Для изменения этого параметра
28+
необходимо задать атрибут `step`.
29+
30+
### min <Badge type = "info">Необязательный</Badge>
31+
- Тип `number | string`
32+
33+
Установка нижней границы значения.
34+
35+
36+
### max <Badge type = "info">Необязательный</Badge>
37+
- Тип `number | string`
38+
39+
Установка верхней границы значения.
40+
41+
____
42+
43+
Так же все параметры, общие для всех `FormField`. Информацию о них можно посмотреть на [этой странице](./form-field.md#params).
44+
45+
## Значение
46+
Данное поле работает со строковым значением.
47+
48+
## Спецификация
49+
50+
- Поле доступно при использовании `Tab` и `Shift + Tab`.
51+
- Блокировка отменяет навигацию через `Tab`.
52+
- Блокировка поля изменяет стилистику `range`.
53+
- Ошибка валидации изменяет стилистику `range`.
54+
- Для ограничения ввода используется `min` и `max` атрибуты.
55+
56+
## Пример
57+
58+
Для данного поля нет дополнительных обязательных параметров, по этому нам необходимо
59+
указать лишь `type` и `name`:
60+
61+
::: code-group
62+
```html
63+
<form-field name = "volume" type="range"/>
64+
```
65+
66+
```ts
67+
import {FormField} from "jenesius-vue-form";
68+
```
69+
:::
70+
71+
72+
Поле по умолчанию:
73+
<FormField type = "range" name = "volume" label = "Установите значение" />
74+
75+
____
76+
77+
В заблокированном состоянии:
78+
<FormField type = "range" name = "volume" disabled label = "Заблокированное" />
79+
80+
____
81+
82+
Поле не прошло валидацию:
83+
<FormField type = "range" name = "volume" :errors = "['The password is too simple']" label = "С ошибкой" />
84+
85+
____
86+
87+
Установка границ через `max` и `min`:
88+
<FormField type = "range" name = "volume" max = "10" min= "0" label = "От 0 до 10" />
89+
90+
____
91+
92+
Установка `step` в значение 2:
93+
<FormField type = "range" name = "volume" step = "2" label = "С шагом 2" />
94+
95+
____
96+
97+
Текущее состояние формы:
98+
```ts-vue
99+
{{values}}
100+
```

src/widgets/inputs/input-range/widget-input-range.vue

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@
1717
import FieldWrap from "../field-wrap.vue";
1818
import {computed, ref} from "vue";
1919
20+
21+
2022
interface RangeProps {
21-
max?: number | string,
22-
min?: number | string,
23-
step?: number | string,
2423
label?: string,
2524
errors: string[],
2625
modelValue: any,
2726
disabled: boolean,
28-
autofocus: boolean
27+
28+
max?: number | string,
29+
min?: number | string,
30+
step?: number | string,
31+
autofocus?: boolean
2932
// thumb?: boolean
3033
}
3134
const props = withDefaults(defineProps<RangeProps>(), {
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import {DOMWrapper, mount, VueWrapper} from "@vue/test-utils";
2+
import EmptyApp from "../components/EmptyApp.vue";
3+
import {defineComponent} from "vue";
4+
import {Form, FormField} from "../../../src/index";
5+
import STORE from "./../../../src/config/store";
6+
7+
const name = 'volume'
8+
const label = `Your ${name}`
9+
function defineRangeComponent(bindProps = {}) {
10+
return defineComponent({
11+
data: () => ({bindProps}),
12+
template: `<div><form-field v-bind = "bindProps" type = "range" name = "${name}" required label = "${label}"/></div>`,
13+
components: {FormField}
14+
})
15+
}
16+
function defaultMount(component = defineRangeComponent()) {
17+
return mount(EmptyApp, {
18+
slots: { default: component },
19+
attachTo: document.body
20+
})
21+
}
22+
23+
describe("Input range", () => {
24+
let app: VueWrapper<any>;
25+
let form: Form
26+
let input: DOMWrapper<HTMLInputElement>
27+
beforeEach(() => {
28+
app = defaultMount()
29+
form = (app.vm as any).form
30+
input = app.find('input')
31+
})
32+
33+
test("Значение поля по умолчанию пустое", async () => {
34+
expect(input.element.value).toBe("50") // по умолчанию на середине
35+
})
36+
test("Для пустого поля должна отображаться только метка", async () => {
37+
console.log(app.html())
38+
expect(app.text()).toBe(label)
39+
})
40+
test("При вводе значения в поле - форма должна меняться", async () => {
41+
await input.setValue(40)
42+
expect(form.getValueByName(name)).toBe("40")
43+
})
44+
test("При изменении формы - поле должно меняться", async () => {
45+
form.setValues({[name]: 13});
46+
await app.vm.$nextTick()
47+
expect(input.element.value).toBe("13")
48+
})
49+
test("Блокировка элемента изменяет его стилистику", async () => {
50+
form.disable()
51+
await app.vm.$nextTick()
52+
expect(input.element.disabled).toBe(true);
53+
})
54+
test("Блокировка элемента не даёт ввести значение", async () => {
55+
await input.setValue(20)
56+
form.disable()
57+
await app.vm.$nextTick()
58+
await input.setValue(40)
59+
expect(form.getValueByName(name)).toBe("20")
60+
})
61+
test("Ошибка валидации отображается на поле", async () => {
62+
form.validate()
63+
await app.vm.$nextTick()
64+
expect(app.text()).toBe(label + STORE.requiredMessage)
65+
})
66+
67+
68+
test("Установка max", async () => {
69+
const app = defaultMount(defineRangeComponent({
70+
max: 10
71+
}))
72+
const input = app.find('input');
73+
const form = (app.vm as any).form as Form;
74+
expect(input.element.value).toBe("5");
75+
await input.setValue(20);
76+
expect(input.element.value).toBe("10")
77+
expect(form.getValueByName(name)).toBe("10")
78+
})
79+
test("Установка min", async () => {
80+
const app = defaultMount(defineRangeComponent({
81+
min: 50
82+
}))
83+
const input = app.find('input');
84+
const form = (app.vm as any).form as Form;
85+
expect(input.element.value).toBe("75");
86+
await input.setValue(20);
87+
expect(input.element.value).toBe("50")
88+
expect(form.getValueByName(name)).toBe("50")
89+
})
90+
test("Установка max/min", async () => {
91+
const app = defaultMount(defineRangeComponent({
92+
min: 50, max: 60
93+
}))
94+
const input = app.find('input');
95+
expect(input.element.value).toBe("55");
96+
})
97+
98+
/*
99+
test("Поле должно реагировать на нажатие стрелок", async () =>{
100+
await input.trigger('keydown.down');
101+
expect(input.element.value).toBe("49");
102+
await input.trigger('keydown.down');
103+
expect(input.element.value).toBe("48");
104+
105+
await input.trigger('keydown.up');
106+
expect(input.element.value).toBe("49");
107+
expect(form.getValueByName(name)).toBe("49")
108+
})
109+
test("Установка step", async () => {
110+
const app = defaultMount(defineRangeComponent({
111+
step: 15
112+
}))
113+
const input = app.find('input');
114+
await input.trigger('keydown.down');
115+
expect(input.element.value).toBe("35");
116+
})
117+
*/
118+
})

0 commit comments

Comments
 (0)