<?php

// test convert_smilies and related functions


/* Skip test? */
function test_smilies_skip() {
	global $wpsmiliestrans;

	return ( count($wpsmiliestrans) == 0);
}

/* Parse text for image strings.
 * 
 * Returns array of results with [0] as whole match including tag, [1] is src.
 */
function test_smilies_match_in_img($text) {
	$match = "/<img.*src=(?:'|\")(.*)(?:'|\").*>/U";
	preg_match_all($match, $text, $result, PREG_SET_ORDER);
	return $result;
}

/*
 * Create a random printable string of specified length, htmlentities-ed. More
 * "aggressive" than rand_str().
 */
function test_smilies_random_string($length) {
	$start_ascii_printable = 33;
	$end_ascii_printable = 126;

	$result = '';
	while ($length--) {
		$result .= chr(rand($start_ascii_printable, $end_ascii_printable));
	}
	return htmlentities($result);
}

/* Create a number of random words */
function test_smilies_random_words($words, $strip_smilies=true, $min_length=3, $max_length=10) {
	$result = ' ';
	while($words--) {
		$result .= test_smilies_random_string(rand($min_length, $max_length)) . ' ';
	}
	return ($strip_smilies ? test_smilies_strip_smilies($result) : $result);
}

/* Brute force strip smilies from string */
function test_smilies_strip_smilies($text) {
	global $wpsmiliestrans;
	return str_replace(array_keys($wpsmiliestrans), '', $text);
}

/* 
 * Get specified number of random smilies from $wpsmiliestrans. Returns same
 * format: <smilie> => <filename>
 */
function test_smilies_get_random_smilies($nr) {
	global $wpsmiliestrans;

	$keys = array_keys($wpsmiliestrans);
	$values = array_values($wpsmiliestrans);

	$count = count($keys);
	while ($nr--) {
		$i = rand(0, $count-1);
		$result[$keys[$i]] = $values[$i];
	}
	return $result;
}

/* Get filename for smilie (as returned from test_smilies_match_in_img() */
function test_smilies_get_filename($s) {
	if (is_array($s)) {
		$s = pathinfo($s[1]);
		return $s['basename'];
	} else {
		return $s;
	}
}

/*
 * Convert $text using convert_smilies, and check that any smilies in converted
 * text match one to one against array of smilie filenames supplied.
 */
function test_smilies_test_text($text, $smilies) {
	$smilies_arr = test_smilies_match_in_img(convert_smilies($text));

	if (count($smilies_arr) != count($smilies)) {
		return FALSE;
	}

	/* make sure the filenames match */
	$s = reset($smilies_arr);
	$sfile = reset($smilies);
	while ($s && $sfile) {
		if (strcmp(test_smilies_get_filename($s), $sfile) != 0) {
			echo($s . ' / ' . test_smilies_get_filename($s) . '/' . $sfile);
			return FALSE;
		}

		$s = next($smilies_arr);
		$sfile = next($smilies);
	}

	return TRUE;
}


class WPTestSmilies extends WPTestCase {
	/*
	 * Test a few smilies among random text
	 */
	function test_smilies_in_text() {
		if (test_smilies_skip()) {
			$this->markTestSkipped();
		}

		$nr_of_smilies = 5;
		$smilies = test_smilies_get_random_smilies($nr_of_smilies);

		$text = '';
		for ( $v = reset($smilies), $k = key($smilies);
			  $v;
			  $v = next($smilies), $k = key($smilies)) {
			$text .= test_smilies_random_words(rand(0, 15)) . $k . test_smilies_random_words(rand(0, 15));
		}

		$this->assertTrue(test_smilies_test_text($text, array_values($smilies)));
	}

	/*
	 * Test a smilie inside html tag
	 */
	function test_smilies_in_tag() {
		if (test_smilies_skip()) {
			$this->markTestSkipped();
		}

		$nr_of_smilies = 2;
		$smilies = test_smilies_get_random_smilies($nr_of_smilies);

		$text = '';
		for ( $v = reset($smilies), $k = key($smilies);
			  $v;
			  $v = next($smilies), $k = key($smilies)) {
			$text .= '<label name="'. $k . '">';
		}

		// check against empty array
		$this->assertTrue(test_smilies_test_text($text, array()));
	}

	/*
	 * Test a few smilies among html tags
	 */
	function test_smilies_among_tags() {
		if (test_smilies_skip()) {
			$this->markTestSkipped();
		}

		$nr_of_smilies = 5;
		$smilies = test_smilies_get_random_smilies($nr_of_smilies);

		$text = '';
		for ( $v = reset($smilies), $k = key($smilies);
			  $v;
			  $v = next($smilies), $k = key($smilies)) {
			$text .=  '<p>' . $k . '</p>';
		}

		$this->assertTrue(test_smilies_test_text($text, array_values($smilies)));
	}

	/*
	 * Test one of each smilie
	 */
	function test_all_smiles_and_filenames() {
		if (test_smilies_skip()) {
			$this->markTestSkipped();
		}

		global $wpsmiliestrans;

		/* make string with one of each smiley */
		$smilies_text = '';
		foreach (array_keys($wpsmiliestrans) as $smiley) {
			$smilies_text .= " $smiley ";
		}

		$this->assertTrue(test_smilies_test_text($smilies_text, array_values($wpsmiliestrans)));
	}

	/*
	 * Test a new $wpsmiliestrans with some random smilies
	 */
	function test_smilies_new_wpsmiliestrans() {
		/* This we can test even if test_smilies_skip() == true */

		global $wpsmiliestrans;
		$nr_of_smilies = 10;

		/* backup */
		$old_wpsmiliestrans = $wpsmiliestrans;
		$old_option = get_option('use_smilies');
		if (!$old_option) {
			update_option('use_smilies', 1);
		}

		unset($wpsmiliestrans);
		while ($nr_of_smilies--) {
			$wpsmiliestrans[test_smilies_random_string(rand(2, 5))] = test_smilies_random_string(5, 10) . '.gif';
		}

		smilies_init();

		$this->test_all_smiles_and_filenames();

		/* restore */
		$wpsmiliestrans = $old_wpsmiliestrans;
		if (!$old_option) {
			update_option('use_smilies', $old_option);
		}
		smilies_init();
	}
}

?>
