import { flushSync, track, effect, bindValue, bindChecked } from 'ripple';

describe('use value()', () => {
	it('should update value on input', () => {
		const logs: string[] = [];

		component App() {
			const text = track('');

			effect(() => {
				logs.push('text changed', @text);
			});

			<input type="text" {ref bindValue(text)} />
		}
		render(App);
		flushSync();

		const input = container.querySelector('input') as HTMLInputElement;
		input.value = 'Hello';
		input.dispatchEvent(new Event('input'));
		flushSync();
		expect(input.value).toBe('Hello');
		expect(logs).toEqual(['text changed', '', 'text changed', 'Hello']);
	});

	it('should update value on input with a predefined value', () => {
		const logs: string[] = [];

		component App() {
			const text = track('foo');

			effect(() => {
				logs.push('text changed', @text);
			});

			<input type="text" {ref bindValue(text)} />
		}
		render(App);
		flushSync();

		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.value).toBe('foo');
		input.value = 'Hello';
		input.dispatchEvent(new Event('input'));
		flushSync();
		expect(input.value).toBe('Hello');
		expect(logs).toEqual(['text changed', 'foo', 'text changed', 'Hello']);
	});

	it('should update checked on input', () => {
		const logs: string[] = [];

		component App() {
			const value = track(false);

			effect(() => {
				logs.push('checked changed', @value);
			});

			<input type="checkbox" {ref bindChecked(value)} />
		}
		render(App);
		flushSync();

		const input = container.querySelector('input') as HTMLInputElement;
		input.checked = true;
		input.dispatchEvent(new Event('change'));
		flushSync();

		expect(input.checked).toBe(true);
		expect(logs).toEqual(['checked changed', false, 'checked changed', true]);
	});

	it('should update select value on change', () => {
		const logs: string[] = [];

		component App() {
			const select = track('2');

			effect(() => {
				logs.push('select changed', @select);
			});

			<select {ref bindValue(select)}>
				<option value="1">{'One'}</option>
				<option value="2">{'Two'}</option>
				<option value="3">{'Three'}</option>
			</select>
		}

		render(App);
		flushSync();

		const select = container.querySelector('select') as HTMLSelectElement;
		select.value = '3';
		select.dispatchEvent(new Event('change'));
		flushSync();

		expect(select.value).toBe('3');
		expect(logs).toEqual(['select changed', '2', 'select changed', '3']);
	});
});
