/**
 * Internal dependencies
 */

import { count } from '../';
import type { UserSettings, Strategy } from '../types';

const mockData: UserSettings = {
	l10n: {
		shortcodes: [ 'shortcode' ],
	},
};

interface TestDataItem {
	message: string;
	string: string;
	words: number;
	characters_excluding_spaces: number;
	characters_including_spaces: number;
}

describe( 'WordCounter', () => {
	const dataProvider: TestDataItem[] = [
		{
			message: 'Basic test.',
			string: 'one two three',
			words: 3,
			characters_excluding_spaces: 11,
			characters_including_spaces: 13,
		},
		{
			message: 'HTML tags.',
			string: 'one <em class="test">two</em><br />three',
			words: 3,
			characters_excluding_spaces: 11,
			characters_including_spaces: 12,
		},
		{
			message: 'Line breaks.',
			string: 'one\ntwo\nthree',
			words: 3,
			characters_excluding_spaces: 11,
			characters_including_spaces: 11,
		},
		{
			message: 'Encoded spaces.',
			string: 'one&nbsp;two&#160;three',
			words: 3,
			characters_excluding_spaces: 11,
			characters_including_spaces: 13,
		},
		{
			message: 'Punctuation.',
			string: 'It’s two three \u2026 4?',
			words: 4,
			characters_excluding_spaces: 15,
			characters_including_spaces: 19,
		},
		{
			message: 'Numbers as word',
			string: 'Should be 4 words',
			words: 4,
			characters_excluding_spaces: 14,
			characters_including_spaces: 17,
		},
		{
			message: 'Em dash.',
			string: 'one\u2014two--three',
			words: 3,
			characters_excluding_spaces: 14,
			characters_including_spaces: 14,
		},
		{
			message: 'Shortcodes.',
			string: 'one [shortcode attribute="value"]two[/shortcode]three',
			words: 3,
			characters_excluding_spaces: 11,
			characters_including_spaces: 12,
		},
		{
			message: 'Astrals.',
			string: '\uD83D\uDCA9',
			words: 1,
			characters_excluding_spaces: 1,
			characters_including_spaces: 1,
		},
		{
			message: 'HTML comment.',
			string: 'one<!-- comment -->two three',
			words: 2,
			characters_excluding_spaces: 11,
			characters_including_spaces: 12,
		},
		{
			message: 'HTML entity.',
			string: '&gt; test',
			words: 1,
			characters_excluding_spaces: 5,
			characters_including_spaces: 6,
		},
		{
			message: 'Empty tags',
			string: '<p></p>',
			words: 0,
			characters_excluding_spaces: 0,
			characters_including_spaces: 0,
		},
		{
			message: 'Empty string',
			string: '',
			words: 0,
			characters_excluding_spaces: 0,
			characters_including_spaces: 0,
		},
	];

	const types: Strategy[] = [
		'words',
		'characters_excluding_spaces',
		'characters_including_spaces',
	];

	dataProvider.forEach( ( item ) => {
		types.forEach( ( type ) => {
			const result = count( item.string, type, mockData );
			test( item.message + ' (' + type + ')', () => {
				expect( result ).toBe( item[ type ] );
			} );
		} );
	} );
} );
