<?php

/*
Plugin Name: Unit Test: Query Flags
Description: Drop into mu-plugins folder and go to front page
Author: scribu
Version: 1.0
*/

class Unit_Query_Flags {

	const POSTS_PAGE_ID = 111;

	// Expected flags are set without the is_ prefix and separated by a space
	static $tests = array(

		// Singles

		array(
			'query' => array( 'p' => 123 ),
			'flags' => 'single singular',
		),

		array(
			'query' => array( 'p' => 123, 'cpage' => 2 ),
			'flags' => 'single singular',
		),

		array(
			'query' => array( 'name' => 'foo' ),
			'flags' => 'single singular',
		),

		array(
			'query' => array( 'pagename' => 'foo/bar' ),
			'flags' => 'page singular',
		),

		array(
			'query' => array( 'page_id' => 123 ),
			'flags' => 'page singular',
		),

		array(
			'query' => array( 'pagename' => 'foo/bar', 'page' => 2 ),
			'flags' => 'page singular',
		),

		array(
			'query' => array( 'post_type' => 'book', 'name' => 'foo' ),
			'flags' => 'single singular',
		),

		array(
			'query' => array( 'attachment' => 'foo' ),
			'flags' => 'attachment single singular',
		),

		array(
			'query' => array( 'attachment_id' => 123 ),
			'flags' => 'attachment single singular',
		),

		// Basic archives

		array(
			'query' => array(),
			'flags' => 'home',
		),

		array(
			'query' => array( 'page_id' => self::POSTS_PAGE_ID ),
			'flags' => 'home posts_page',
		),

		array(
			'query' => array( 'paged' => 2 ),
			'flags' => 'home paged',
		),

		array(
			'query' => array( 's' => 'foo' ),
			'flags' => 'search',
		),

		array(
			'query' => array( 's' => 'foo' ),
			'flags' => 'search'
		),

		array(
			'query' => array( 'author_name' => 'admin' ),
			'flags' => 'archive author'
		),

		array(
			'query' => array( 'post__in' => array( 1, 2 ) ),
			'flags' => 'home'
		),

		// Date archives

		array(
			'query' => array( 'second' => 1 ),
			'flags' => 'archive date time'
		),

		array(
			'query' => array( 'day' => 22 ),
			'flags' => 'archive date day'
		),

		array(
			'query' => array( 'monthnum' => 1 ),
			'flags' => 'archive date month'
		),

		array(
			'query' => array( 'year' => 2011 ),
			'flags' => 'archive date year'
		),

		// Tag archives

		array(
			'query' => array( 'tag' => 'featured' ),
			'flags' => 'archive tag'
		),

		array(
			'query' => array( 'tag' => 'foo+bar' ),
			'flags' => 'archive tag'
		),

		array(
			'query' => array( 'tag' => 'foo,bar' ),
			'flags' => 'archive tag'
		),

		array(
			'query' => array( 'tag_id' => 123 ),
			'flags' => 'archive tag'
		),

		// Category archives

		array(
			'query' => array( 'category_name' => 'foo/bar' ),
			'flags' => 'archive category'
		),

		array(
			'query' => array( 'cat' => '1+2+3' ),
			'flags' => 'archive category'
		),

		array(
			'query' => array( 'cat' => '-1,2,3' ),
			'flags' => 'archive category'
		),

		array(
			'query' => array( 'cat' => -1 ),
			'flags' => 'home'
		),

		// Taxonomy archives

		array(
			'query' => array( 'color' => 'green' ),
			'flags' => 'archive tax'
		),

		array(
			'query' => array( 'color' => 'green+white' ),
			'flags' => 'archive tax'
		),

		array(
			'query' => array( 'color' => 'green,white' ),
			'flags' => 'archive tax'
		),

		array(
			'query' => array( 'tax_query' => array(
				array( 'taxonomy' => 'color', 'terms' => array( 'green' ), 'operator' => 'IN' )
			) ),
			'flags' => 'archive tax'
		),

		array(
			'query' => array( 'tax_query' => array(
				array( 'taxonomy' => 'color', 'terms' => array( 'green' ), 'operator' => 'NOT IN' )
			) ),
			'flags' => 'home'
		),

		array(
			'query' => array( 'tax_query' => array(
				array( 'taxonomy' => 'category', 'terms' => array( 'green' ), 'operator' => 'NOT IN' )
			) ),
			'flags' => 'home'
		),

		array(
			'query' => array( 'tax_query' => array(
				array( 'taxonomy' => 'post_tag', 'terms' => array( 'green' ), 'operator' => 'NOT IN' )
			) ),
			'flags' => 'home'
		),

		// Taxonomy combinations

		array(
			'query' => array( 'tag' => 'foo', 'cat' => 1 ),
			'flags' => 'archive category tag'
		),

		array(
			'query' => array( 'tag' => 'foo', 'color' => 'green' ),
			'flags' => 'archive tag tax'
		),

		array(
			'query' => array( 'cat' => 1, 'color' => 'green' ),
			'flags' => 'archive category tax'
		),

		array(
			'query' => array( 'color' => 'green', 'weight' => 'heavy' ),
			'flags' => 'archive tax'
		),

		// CPT Archives

		array(
			'query' => array( 'post_type' => 'book' ),
			'flags' => 'archive post_type_archive'
		),

		array(
			'query' => array( 'post_type' => 'book', 's' => 'foo' ),
			'flags' => 'archive post_type_archive search'
		),

		array(
			'query' => array( 'post_type' => 'book', 'color' => 'green' ),
			'flags' => 'archive post_type_archive tax'
		),

		// Feeds

		array(
			'query' => array( 'feed' => 'rss' ),
			'flags' => 'feed'
		),

		array(
			'query' => array( 's' => 'foo', 'feed' => 'rss' ),
			'flags' => 'feed search'
		),

		array(
			'query' => array( 'author_name' => 'foo', 'feed' => 'rss' ),
			'flags' => 'archive author feed'
		),

		array(
			'query' => array( 'p' => 1, 'feed' => 'rss' ),
			'flags' => 'comment_feed feed single singular'
		),

		// Misc

		array(
			'query' => array( 'p' => 123, 'preview' => true ),
			'flags' => 'preview single singular'
		),

		array(
			'query' => array( 'p' => 123, 'tb' => true ),
			'flags' => 'trackback single singular'
		),

		array(
			'query' => array( 'robots' => true ),
			'flags' => 'robots'
		),

		array(
			'query' => array( 'p' => 123, 'comments_popup' => true ),
			'flags' => 'comments_popup single singular'
		),
	);

	static $query_flags = array(
		'single',
		'preview',
		'page',
		'archive',
		'date',
		'year',
		'month',
		'day',
		'time',
		'author',
		'category',
		'tag',
		'tax',
		'search',
		'feed',
		'comment_feed',
		'trackback',
		'home',
		'404',
		'comments_popup',
		'paged',
		'admin',
		'attachment',
		'singular',
		'robots',
		'posts_page',
		'post_type_archive',
	);

	// Register any necessary post types and taxonomies
	function init() {
		register_post_type( 'book', array(
			'public' => true,
			'has_archive' => true,
			'label' => 'Books',
		) );

		register_taxonomy( 'color', 'book' );

		register_taxonomy( 'weight', 'book' );

		// For is_posts_page		
		add_filter( 'pre_option_show_on_front', function() { return 'page'; } );
		add_filter( 'pre_option_page_for_posts', function() { return Unit_Query_Flags::POSTS_PAGE_ID; } );
	}

	// Run the tests
	function run() {
		// We're not interested in actually running the query
		add_filter( 'posts_request', '__return_false' );

		echo "<pre>";

		$failed = $passed = 0;
		foreach ( self::$tests as $i => $test ) {
			$args = $test['query'];
			$args['ignore_sticky_posts'] = true;	// prevents warning caused by null $posts

			$q = new WP_Query( $args );

			$result = array();
			foreach ( self::$query_flags as $flag ) {
				$key = "is_$flag";

				if ( isset( $q->$key ) && $q->$key )
					$result[] = $flag;
			}

			$expected = explode( ' ', $test['flags'] );

			sort( $expected );
			sort( $result );

			if ( $expected == $result ) {
				$passed++;
			} else {
				$failed++;

				echo "Failed test $i:\n";
				echo "    Expected: " . implode( ' ', $expected ) . "\n";
				echo "    Result: " . implode( ' ', $result ) . "\n";
				echo "    Query: \n";
				print_r( $test['query'] );
				echo "<hr>";
			}
		}

		echo "Summary:\n";
		echo "    Passed: $passed\n";
		echo "    Failed: $failed\n";

		remove_filter( 'posts_request', '__return_false' );
		die;
	}
}

add_action( 'init', array( 'Unit_Query_Flags', 'init' ) );
add_action( 'template_redirect', array( 'Unit_Query_Flags', 'run' ) );

