<commit_before>#pragma once
#include <chrono>
#include <stdio.h>
#include <sstream>
#include "PlexAlloc/Allocator.hpp"

template <typename T>
using PlexAllocator = PlexAlloc::Allocator<T>;

class iTestCase
{
public:
	virtual void prepare( size_t length ) = 0;
	virtual int run( int inserts ) = 0;
};

// A test case for STL containers. Because they expose very similar API, a single template implementation is required.
template<class tContainer>
class testStl: public iTestCase
{
	tContainer local;

public:
	void prepare( size_t length ) override
	{
		for( size_t i = 0; i < length; i++ )
			local.push_back( 1 );
	}
	int run( int localInserts ) override
	{
		for( int i = 0; i < localInserts; i++ )
			local.insert( local.begin(), 1 );

		int sum = 0;
		for( int i : local )
			sum += i;
		return sum;
	}
};

template<class tTest>
void run( size_t length, int inserts )
{
	tTest test;
	using namespace std::chrono;
	using stopwatch = high_resolution_clock;

	test.prepare( length );

	const stopwatch::time_point t1 = stopwatch::now();

	const int res = test.run( inserts );

	const stopwatch::time_point t2 = stopwatch::now();
	duration<double> time_span = duration_cast<duration<double>>( t2 - t1 );

	printf( "%i\t%.9f\t%i\n", int( length ), time_span.count(), res );
}

template<class tTest>
int runAll()
{
	size_t lengths[] = { 100, 1000, 100000, 1000000, 10000000, 100000000 };
	const int inserts = 5;
	for( size_t l : lengths )
		run<tTest>( l, inserts );
	return 0;
}

inline bool tryParse( const char* str, int& res )
{
	// https://stackoverflow.com/a/14176593/126995
	errno = 0;
	char *temp;
	long val = strtol( str, &temp, 0 );

	if( temp == str || *temp != '\0' || ( ( val == LONG_MIN || val == LONG_MAX ) && errno == ERANGE ) )
		return false;
	res = (int)val;
	return true;
}

inline int parseArguments( int argc, const char* argv[] )
{
	if( 2 != argc )
	{
		printf( "Usage: %s N\n", argv[ 0 ] );
		return -1;
	}
	int res;
	if( !tryParse( argv[ 1 ], res ) || res < 0 )
	{
		printf( "The argument must be a non-negative integer\n" );
		return -1;
	}
	return res;
}

#define TEST_CASE1( nTest, tType ) case nTest: printf( "%s\n", #tType ); return runAll<tType>()
#define TEST_CASE2( nTest, tType1, tType2 ) case nTest: printf( "%s, %s\n", #tType1, #tType2 ); return runAll<tType1, tType2>()<commit_msg>Included total time measurement<commit_after>#pragma once
#include <chrono>
#include <stdio.h>
#include <sstream>
#include "PlexAlloc/Allocator.hpp"

template <typename T>
using PlexAllocator = PlexAlloc::Allocator<T>;

class iTestCase
{
public:
	virtual void prepare( size_t length ) = 0;
	virtual int run( int inserts ) = 0;
};

// A test case for STL containers. Because they expose very similar API, a single template implementation is required.
template<class tContainer>
class testStl: public iTestCase
{
	tContainer local;

public:
	void prepare( size_t length ) override
	{
		for( size_t i = 0; i < length; i++ )
			local.push_back( 1 );
	}
	int run( int localInserts ) override
	{
		for( int i = 0; i < localInserts; i++ )
			local.insert( local.begin(), 1 );

		int sum = 0;
		for( int i : local )
			sum += i;
		return sum;
	}
};

using namespace std::chrono;
using stopwatch = high_resolution_clock;

template<class tTest>
void runImpl( size_t length, int inserts )
{
	tTest test;

	test.prepare( length );

	const stopwatch::time_point t1 = stopwatch::now();

	const int res = test.run( inserts );

	const stopwatch::time_point t2 = stopwatch::now();
	duration<double> time_span = duration_cast<duration<double>>( t2 - t1 );

	printf( "%i\t%i\t%.9f", int( length ), res, time_span.count() );
}

template<class tTest>
void run( size_t length, int inserts )
{
	const stopwatch::time_point t1 = stopwatch::now();
	runImpl<tTest>( length, inserts );
	const stopwatch::time_point t2 = stopwatch::now();
	duration<double> time_span = duration_cast<duration<double>>( t2 - t1 );
	printf( "\t%.9f\n", time_span.count() );
}

template<class tTest>
int runAll()
{
	size_t lengths[] = { 100, 1000, 100000, 1000000, 10000000, 100000000 };
	const int inserts = 5;
	for( size_t l : lengths )
		run<tTest>( l, inserts );
	return 0;
}

inline bool tryParse( const char* str, int& res )
{
	// https://stackoverflow.com/a/14176593/126995
	errno = 0;
	char *temp;
	long val = strtol( str, &temp, 0 );

	if( temp == str || *temp != '\0' || ( ( val == LONG_MIN || val == LONG_MAX ) && errno == ERANGE ) )
		return false;
	res = (int)val;
	return true;
}

inline int parseArguments( int argc, const char* argv[] )
{
	if( 2 != argc )
	{
		printf( "Usage: %s N\n", argv[ 0 ] );
		return -1;
	}
	int res;
	if( !tryParse( argv[ 1 ], res ) || res < 0 )
	{
		printf( "The argument must be a non-negative integer\n" );
		return -1;
	}
	return res;
}

#define TEST_CASE1( nTest, tType ) case nTest: printf( "%s\n", #tType ); return runAll<tType>()
#define TEST_CASE2( nTest, tType1, tType2 ) case nTest: printf( "%s, %s\n", #tType1, #tType2 ); return runAll<tType1, tType2>()<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "gtest/gtest.h"

#include <iostream> // TODO: remove.
#include <sstream>

#include "Allocator.h"
#include "BitFunnel/TermMatchNode.h"
#include "QueryParser.h"
#include "TextObjectFormatter.h"

namespace BitFunnel
{

    struct ExpectedAndInputs
    {
    public:
        char const * m_expected;
        char const * m_input;
    };

    const ExpectedAndInputs c_testData[] =
    {
        // UNIGRAM.
        {"Unigram(\"wat\", 0)", "wat"},

        // STREAM:UNIGRAM.
        {"Unigram(\"wat\", 0)", "StreamsAreCurrentlyIgnored:wat"},

        // (UNIGRAM)
        {"Unigram(\"wat\", 0)", "(wat)"},

        // OR of two UNIGRAMs.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "wat|foo"
         },

        // OR of two UNIGRAMs with parens.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "(wat|foo)"
        },

        // OR of two UNIGRAMs with parens.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            " (wat|foo)\t"
        },

        // OR of two UNIGRAMs with parens.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "\t( wat |\tfoo )"
        },

        // NOT.
        {
            "Not {\n"
            "  Child: Unigram(\"wat\", 0)\n"
            "}"
            , "-wat"
        },

        // AND of 2.
        {
            "And {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "wat foo"
        },

        // AND of 2, explicit '&'.
        {
            "And {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "wat&foo"
        },

        // AND of 2, explicit '&' with whitespace.
        {
            "And {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "wat\t\t&  foo"
        },

        // PHRASE.
        {
            "Phrase {\n"
            "  StreamId: 0,\n"
            "  Grams: [\n"
            "    \"wat\",\n"
            "    \"foo\"\n"
            "  ]\n"
            "}",
            "\" wat\tfoo\""
        },

        // PHRASE.
        {
            "Phrase {\n"
            "  StreamId: 0,\n"
            "  Grams: [\n"
            "    \"wat\",\n"
            "    \"foo\"\n"
            "  ]\n"
            "}",
            "\"wat\tfoo\""
        },

        // OR of AND.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"three\", 0),\n"
            "    And {\n"
            "      Children: [\n"
            "        Unigram(\"two\", 0),\n"
            "        Unigram(\"one\", 0)\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "one two | three"
        },

        // OR of AND.
        {
            "Or {\n"
            "  Children: [\n"
            "    And {\n"
            "      Children: [\n"
            "        Unigram(\"four\", 0),\n"
            "        Unigram(\"three\", 0)\n"
            "      ]\n"
            "    },\n"
            "    And {\n"
            "      Children: [\n"
            "        Unigram(\"two\", 0),\n"
            "        Unigram(\"one\", 0)\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "one\ttwo|three    \tfour"
        },

        // AND with NOT.
        {
            "And {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one&-two"
        },

        // AND with NOT.
        {
            "And {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one -two"
        },

        // AND with NOT.
        // TODO: this is probably counter-intuitive to users.
        {
            "And {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one-two"
        },

        // AND with NOT.
        {
            "And {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one- two"
        },

        // AND with parens.
        {
            "And {\n"
            "  Children: [\n"
            "    Unigram(\"two\", 0),\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one (two)"
        },

        // OR with NOT.
        {
            "Or {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one|-two"
        },

        // OR with NOT.
        {
            "Or {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            " one    | -    two "
        },

        // AND then OR.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"three\", 0),\n"
            "    And {\n"
            "      Children: [\n"
            "        Unigram(\"two\", 0),\n"
            "        Unigram(\"one\", 0)\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "one & two | three"
        },

        // AND then OR, parens change precedence.
        {
            "And {\n"
            "  Children: [\n"
            "    Or {\n"
            "      Children: [\n"
            "        Unigram(\"three\", 0),\n"
            "        Unigram(\"two\", 0)\n"
            "      ]\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one & (two | three)"
        },

        // AND of PHRASE
        {
            "And {\n"
            "  Children: [\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"three\",\n"
            "        \"four\"\n"
            "      ]\n"
            "    },\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"one\",\n"
            "        \"two\"\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "\"one two\" \"three four\""
        },

        // AND of PHRASE
        {
            "And {\n"
            "  Children: [\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"three\",\n"
            "        \"four\"\n"
            "      ]\n"
            "    },\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"one\",\n"
            "        \"two\"\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "\"one two\"&\"three four\""
        },

        // OR of PHRASE
        {
            "Or {\n"
            "  Children: [\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"three\",\n"
            "        \"four\"\n"
            "      ]\n"
            "    },\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"one\",\n"
            "        \"two\"\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "\"one two\"|\"three four\""
        },

        // ESCAPE.
        {
            "Unigram(\"one|two\", 0)",
            "one\\|two"
        },

        // PHRASE with ESCAPE.
        {
            "Phrase {\n"
            "  StreamId: 0,\n"
            "  Grams: [\n"
            "    \"one|two\",\n"
            "    \"three\"\n"
            "  ]\n"
            "}",
            "\"one\\|two three\""
        },

        // PHRASE with quote ESCAPE.
        {
            "Phrase {\n"
            "  StreamId: 0,\n"
            "  Grams: [\n"
            "    \"one\\\"two\",\n"
            "    \"three\"\n"
            "  ]\n"
            "}",
            "\"one\\\"two three\""
        }
    };

    void VerifyQueryParser(std::string const & expected, std::string const & input, IAllocator& allocator)
    {
        std::stringstream s;
        s << input;
        QueryParser parser(s, allocator);

        std::cout << "input length: " << s.str().size() << std::endl;

        auto result = parser.Parse();
        ASSERT_NE(nullptr, result);

        std::stringstream parsedOutput;
        TextObjectFormatter formatter(parsedOutput);
        result->Format(formatter);

        std::cout << "???: " << parsedOutput.str() << std::endl;
        EXPECT_EQ(expected, parsedOutput.str());
        allocator.Reset();
    }

    TEST(QueryParser, Trivial)
    {
        Allocator allocator(512);

        for (size_t i = 0; i < sizeof(c_testData) / sizeof(ExpectedAndInputs); ++i)
        {
            VerifyQueryParser(c_testData[i].m_expected, c_testData[i].m_input, allocator);
        }
    }
}
<commit_msg>Add more QueryParser tests.<commit_after>// The MIT License (MIT)

// Copyright (c) 2016, Microsoft

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "gtest/gtest.h"

#include <iostream> // TODO: remove.
#include <sstream>

#include "Allocator.h"
#include "BitFunnel/TermMatchNode.h"
#include "QueryParser.h"
#include "TextObjectFormatter.h"

namespace BitFunnel
{

    struct ExpectedAndInputs
    {
    public:
        char const * m_expected;
        char const * m_input;
    };

    const ExpectedAndInputs c_testData[] =
    {
        // UNIGRAM.
        {"Unigram(\"wat\", 0)", "wat"},

        // STREAM:UNIGRAM.
        {"Unigram(\"wat\", 0)", "StreamsAreCurrentlyIgnored:wat"},

        // (UNIGRAM)
        {"Unigram(\"wat\", 0)", "(wat)"},

        // OR of two UNIGRAMs.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "wat|foo"
         },

        // OR of two UNIGRAMs with parens.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "(wat|foo)"
        },

        // OR of two UNIGRAMs with parens.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            " (wat|foo)\t"
        },

        // OR of two UNIGRAMs with parens.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "\t( wat |\tfoo )"
        },

        // NOT.
        {
            "Not {\n"
            "  Child: Unigram(\"wat\", 0)\n"
            "}"
            , "-wat"
        },

        // AND of 2.
        {
            "And {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "wat foo"
        },

        // AND of 2, explicit '&'.
        {
            "And {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "wat&foo"
        },

        // AND of 2, explicit '&' with whitespace.
        {
            "And {\n"
            "  Children: [\n"
            "    Unigram(\"foo\", 0),\n"
            "    Unigram(\"wat\", 0)\n"
            "  ]\n"
            "}",
            "wat\t\t&  foo"
        },

        // PHRASE.
        {
            "Phrase {\n"
            "  StreamId: 0,\n"
            "  Grams: [\n"
            "    \"wat\",\n"
            "    \"foo\"\n"
            "  ]\n"
            "}",
            "\" wat\tfoo\""
        },

        // PHRASE.
        {
            "Phrase {\n"
            "  StreamId: 0,\n"
            "  Grams: [\n"
            "    \"wat\",\n"
            "    \"foo\"\n"
            "  ]\n"
            "}",
            "\"wat\tfoo\""
        },

        // OR of AND.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"three\", 0),\n"
            "    And {\n"
            "      Children: [\n"
            "        Unigram(\"two\", 0),\n"
            "        Unigram(\"one\", 0)\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "one two | three"
        },

        // OR of AND.
        {
            "Or {\n"
            "  Children: [\n"
            "    And {\n"
            "      Children: [\n"
            "        Unigram(\"four\", 0),\n"
            "        Unigram(\"three\", 0)\n"
            "      ]\n"
            "    },\n"
            "    And {\n"
            "      Children: [\n"
            "        Unigram(\"two\", 0),\n"
            "        Unigram(\"one\", 0)\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "one\ttwo|three    \tfour"
        },

        // AND with NOT.
        {
            "And {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one&-two"
        },

        // AND with NOT.
        {
            "And {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one -two"
        },

        // AND with NOT.
        // TODO: this is probably counter-intuitive to users.
        {
            "And {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one-two"
        },

        // AND with NOT.
        {
            "And {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one- two"
        },

        // AND with parens.
        {
            "And {\n"
            "  Children: [\n"
            "    Unigram(\"two\", 0),\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one (two)"
        },

        // OR with NOT.
        {
            "Or {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one|-two"
        },

        // OR with NOT.
        {
            "Or {\n"
            "  Children: [\n"
            "    Not {\n"
            "      Child: Unigram(\"two\", 0)\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            " one    | -    two "
        },

        // AND then OR.
        {
            "Or {\n"
            "  Children: [\n"
            "    Unigram(\"three\", 0),\n"
            "    And {\n"
            "      Children: [\n"
            "        Unigram(\"two\", 0),\n"
            "        Unigram(\"one\", 0)\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "one & two | three"
        },

        // AND then OR, parens change precedence.
        {
            "And {\n"
            "  Children: [\n"
            "    Or {\n"
            "      Children: [\n"
            "        Unigram(\"three\", 0),\n"
            "        Unigram(\"two\", 0)\n"
            "      ]\n"
            "    },\n"
            "    Unigram(\"one\", 0)\n"
            "  ]\n"
            "}",
            "one & (two | three)"
        },

        // AND of PHRASE
        {
            "And {\n"
            "  Children: [\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"three\",\n"
            "        \"four\"\n"
            "      ]\n"
            "    },\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"one\",\n"
            "        \"two\"\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "\"one two\" \"three four\""
        },

        // AND of PHRASE
        {
            "And {\n"
            "  Children: [\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"three\",\n"
            "        \"four\"\n"
            "      ]\n"
            "    },\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"one\",\n"
            "        \"two\"\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "\"one two\"&\"three four\""
        },

        // OR of PHRASE
        {
            "Or {\n"
            "  Children: [\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"three\",\n"
            "        \"four\"\n"
            "      ]\n"
            "    },\n"
            "    Phrase {\n"
            "      StreamId: 0,\n"
            "      Grams: [\n"
            "        \"one\",\n"
            "        \"two\"\n"
            "      ]\n"
            "    }\n"
            "  ]\n"
            "}",
            "\"one two\"|\"three four\""
        },

        // ESCAPE.
        {
            "Unigram(\"one|two\", 0)",
            "one\\|two"
        },

        // PHRASE with ESCAPE.
        {
            "Phrase {\n"
            "  StreamId: 0,\n"
            "  Grams: [\n"
            "    \"one|two\",\n"
            "    \"three\"\n"
            "  ]\n"
            "}",
            "\"one\\|two three\""
        },

        // PHRASE with quote ESCAPE.
        {
            "Phrase {\n"
            "  StreamId: 0,\n"
            "  Grams: [\n"
            "    \"one\\\"two\",\n"
            "    \"three\"\n"
            "  ]\n"
            "}",
            "\"one\\\"two three\""
        },

        // NOT of OR.
        {
            "Not {\n"
            "  Child: Or {\n"
            "    Children: [\n"
            "      Unigram(\"two\", 0),\n"
            "      Unigram(\"one\", 0)\n"
            "    ]\n"
            "  }\n"
            "}",
            "-(one|two)"
        }
    };

    void VerifyQueryParser(std::string const & expected, std::string const & input, IAllocator& allocator)
    {
        std::stringstream s;
        s << input;
        QueryParser parser(s, allocator);

        std::cout << "input length: " << s.str().size() << std::endl;

        auto result = parser.Parse();
        ASSERT_NE(nullptr, result);

        std::stringstream parsedOutput;
        TextObjectFormatter formatter(parsedOutput);
        result->Format(formatter);

        std::cout << "???: " << parsedOutput.str() << std::endl;
        EXPECT_EQ(expected, parsedOutput.str());
        allocator.Reset();
    }

    TEST(QueryParser, Trivial)
    {
        Allocator allocator(512);

        for (size_t i = 0; i < sizeof(c_testData) / sizeof(ExpectedAndInputs); ++i)
        {
            VerifyQueryParser(c_testData[i].m_expected, c_testData[i].m_input, allocator);
        }
    }
}
<|endoftext|>


<commit_before>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

//opencv
#include <opencv2/opencv.hpp>

//local
#include "../ObjectDetection/cascade_haar_detector.h"
// #include "../ObjectDetection/daimler_people_detector.h"
#include "../ObjectDetection/detection.h"
#include "../ObjectDetection/hog_people_detector.h"
#include "../StreamDecoder/image_view.h"
#include "../ScenarioAnalysation/scenario.h"
#include "../ScenarioAnalysation/humans_in_front_of_bus_scenario.h"
#include "../ScenarioAnalysation/analyser.h"
#include "controller.h"
#include "../CarCommunication/protoagent.h"

//define keys
const int KEY_ESC = 27;
const int KEY_SPACE = 32;

void Controller::PlayAsVideo(std::string videofile) {
  FrameSelectorFactory frame_selector_factory(videofile);
  FrameSelector* pipeline = frame_selector_factory.GetFrameSelector();
  ImageView image_view;
  int protobuf_counts = pipeline->GetImageCount();
  for (int i=0; i<protobuf_counts; i++) {
      Image * current_image = pipeline->ReadImage(i);
      image_view.ShowImage(current_image);
      delete current_image;
      current_image = NULL;
      if( cvWaitKey(5) == KEY_ESC ) break;
  }
}

void Controller::AnalyseVideo(std::string videofile, uint16_t port, std::string host) {
  ImageView image_view;
  FrameSelectorFactory frame_selector_factory(videofile);
  FrameSelector* pipeline = frame_selector_factory.GetFrameSelector();
  int protobuf_counts = pipeline->GetImageCount();

  // DaimlerPeopleDetector people_detector;
  HOGPeopleDetector people_detector;
  CascadeHaarDetector vehicle_detector("cars3.xml");
  Detection detection(&people_detector, &vehicle_detector);

  // set up all objects needed for analysing
  std::vector<Scenario*> possible_scenarios;
  possible_scenarios.push_back(new HumansInFrontOfBusScenario());
  Analyser analyser(possible_scenarios);

  for (int i=0; i<protobuf_counts; i++) {

    Image * current_image = pipeline->ReadImage(i);
    FrameDetectionData* current_detections = detection.ProcessFrame(current_image);

    if(!current_detections){
        continue;
    }

    Scenario* scenario = analyser.Analyse(*current_detections);

    if(!scenario){

        std::cout << "No scenario in frame " << i << " was detected!" <<std::endl;

    }else{

        if( HumansInFrontOfBusScenario* result = dynamic_cast<HumansInFrontOfBusScenario*>(scenario) ){

            // TODO here for later: inform the communication module that a "Humans in front of bus" scenario was detected
            std::cout << "HUMANS IN FRONT OF BUS !!!!!!!" << std::endl;
        }
        // for demo: show information about scenario in current frame
        std::cout << "Current detected scenario: " << scenario->GetScenarioInformation() << " in frame: " << i << std::endl;

        #ifdef COMBINE
        //Notifying other car
        if(port!=0)
        {
            std::cout << "Informing other car" << std::endl;
            ProtoAgent::startClient(port,host);
        }
        #endif
    }

    int key = cvWaitKey(10);
    if(key == KEY_ESC)
      break;

    if (key == KEY_SPACE)
      key = cvWaitKey(0);

    delete current_image;
    current_image = NULL;
    delete current_detections;
    current_detections = NULL;
    //delete scenario;
    scenario = NULL;

   }
}

void Controller::SaveAllImagesAsJPEG(std::string videofile) {
    FrameSelectorFactory frame_selector_factory(videofile);
    FrameSelector* pipeline = frame_selector_factory.GetFrameSelector();
    int protobuf_counts = pipeline->GetImageCount();
    std::string filename = videofile.substr(videofile.find_last_of("/\\")+1);
    std::ostringstream os;
    for (int i=0; i<protobuf_counts; i++){
        os << i;
        cv::imwrite(filename+"_"+os.str()+".jpeg", pipeline->ReadImage(i)->GetRGBImage());
    }
}
<commit_msg>Removed unneeded debug outputs from Controller<commit_after>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

//opencv
#include <opencv2/opencv.hpp>

//local
#include "../ObjectDetection/cascade_haar_detector.h"
// #include "../ObjectDetection/daimler_people_detector.h"
#include "../ObjectDetection/detection.h"
#include "../ObjectDetection/hog_people_detector.h"
#include "../StreamDecoder/image_view.h"
#include "../ScenarioAnalysation/scenario.h"
#include "../ScenarioAnalysation/humans_in_front_of_bus_scenario.h"
#include "../ScenarioAnalysation/analyser.h"
#include "controller.h"
#include "../CarCommunication/protoagent.h"

//define keys
const int KEY_ESC = 27;
const int KEY_SPACE = 32;

void Controller::PlayAsVideo(std::string videofile) {
  FrameSelectorFactory frame_selector_factory(videofile);
  FrameSelector* pipeline = frame_selector_factory.GetFrameSelector();
  ImageView image_view;
  int protobuf_counts = pipeline->GetImageCount();
  for (int i=0; i<protobuf_counts; i++) {
      Image * current_image = pipeline->ReadImage(i);
      image_view.ShowImage(current_image);
      delete current_image;
      current_image = NULL;
      if( cvWaitKey(5) == KEY_ESC ) break;
  }
}

void Controller::AnalyseVideo(std::string videofile, uint16_t port, std::string host) {
  ImageView image_view;
  FrameSelectorFactory frame_selector_factory(videofile);
  FrameSelector* pipeline = frame_selector_factory.GetFrameSelector();
  int protobuf_counts = pipeline->GetImageCount();

  // DaimlerPeopleDetector people_detector;
  HOGPeopleDetector people_detector;
  CascadeHaarDetector vehicle_detector("cars3.xml");
  Detection detection(&people_detector, &vehicle_detector);

  // set up all objects needed for analysing
  std::vector<Scenario*> possible_scenarios;
  possible_scenarios.push_back(new HumansInFrontOfBusScenario());
  Analyser analyser(possible_scenarios);

  for (int i=0; i<protobuf_counts; i++) {

    Image * current_image = pipeline->ReadImage(i);
    FrameDetectionData* current_detections = detection.ProcessFrame(current_image);

    if(!current_detections){
        continue;
    }

    Scenario* scenario = analyser.Analyse(*current_detections);

    if(!scenario){

        std::cout << "No scenario in frame " << i << " was detected!" <<std::endl;

    }else{

        if( HumansInFrontOfBusScenario* result = dynamic_cast<HumansInFrontOfBusScenario*>(scenario) ){

            // TODO here for later: inform the communication module that a "Humans in front of bus" scenario was detected
        }
        // for demo: show information about scenario in current frame
        std::cout << "Current detected scenario: " << scenario->GetScenarioInformation() << " in frame: " << i << std::endl;

        #ifdef COMBINE
        //Notifying other car
        if(port!=0)
        {
            std::cout << "Informing other car" << std::endl;
            ProtoAgent::startClient(port,host);
        }
        #endif
    }

    int key = cvWaitKey(10);
    if(key == KEY_ESC)
      break;

    if (key == KEY_SPACE)
      key = cvWaitKey(0);

    delete current_image;
    current_image = NULL;
    delete current_detections;
    current_detections = NULL;
    //delete scenario;
    scenario = NULL;

   }
}

void Controller::SaveAllImagesAsJPEG(std::string videofile) {
    FrameSelectorFactory frame_selector_factory(videofile);
    FrameSelector* pipeline = frame_selector_factory.GetFrameSelector();
    int protobuf_counts = pipeline->GetImageCount();
    std::string filename = videofile.substr(videofile.find_last_of("/\\")+1);
    std::ostringstream os;
    for (int i=0; i<protobuf_counts; i++){
        os << i;
        cv::imwrite(filename+"_"+os.str()+".jpeg", pipeline->ReadImage(i)->GetRGBImage());
    }
}
<|endoftext|>


<commit_before>#include "RegularExpressionMatching.hpp"

#include <vector>

using namespace std;

bool RegularExpressionMatching::isMatch(string s, string p) {
    int sl = s.size();
    int pl = p.size();
    vector<vector<bool>> dp(sl + 1, vector<bool>(pl + 1, false));
    // if p == null, then s and p matches iff s == null
    dp[0][0] = true;

    for (int i = 1; i <= sl; i++)
        dp[i][0] = false;

    // if s == null, then s and p matches iff p conforms to (.*)*
    for (int j = 1; j <= pl; j++)
        dp[0][j] = j > 1 && p[j - 1] == '*' && dp[0][j - 2];

    for (int i = 1; i <= sl; i++) {
        for (int j = 1; j <= pl; j++) {
            if (p[j - 1] == '*')
                dp[i][j] = dp[i][j - 2] || (isMatch(s[i - 1], p[j - 2]) && dp[i - 1][j]);
            else
                dp[i][j] = dp[i - 1][j - 1] && isMatch(s[i - 1], p[j - 1]);
        }
    }

    return dp[sl][pl];
}

bool RegularExpressionMatching::isMatch(char _s, char _p) {
    return _p == '.' || _s == _p;
}
<commit_msg>Refine Problem 10. Regular Expression Matching<commit_after>#include "RegularExpressionMatching.hpp"

#include <vector>

using namespace std;

bool RegularExpressionMatching::isMatch(string s, string p) {
    size_t sl = s.size();
    size_t pl = p.size();
    vector<vector<bool>> dp(sl + 1, vector<bool>(pl + 1, false));

    dp[0][0] = true;

    for (int i = 1; i <= sl; i++)
        dp[i][0] = false;

    for (int j = 1; j <= pl; j++)
        dp[0][j] = j > 1 && p[j - 1] == '*' && dp[0][j - 2];

    for (int i = 1; i <= sl; i++) {
        for (int j = 1; j <= pl; j++) {
            if (p[j - 1] == '*')
                dp[i][j] = dp[i][j - 2] || (isMatch(s[i - 1], p[j - 2]) && dp[i - 1][j]);
            else
                dp[i][j] = dp[i - 1][j - 1] && isMatch(s[i - 1], p[j - 1]);
        }
    }

    return dp[sl][pl];
}

bool RegularExpressionMatching::isMatch(char _s, char _p) {
    return _p == '.' || _s == _p;
}
<|endoftext|>


<commit_before>#include "RenderWindow.h"
#include <assert.h>

RenderWindow::RenderWindow(QString dataset, QListWidget *listWidget_Lock, unsigned int iCounter, QWidget* parent /* = 0 */, Qt::WindowFlags flags /* = 0 */) :
	QDialog(parent, flags),
	m_strDataset(dataset),
	m_listWidget_Lock(listWidget_Lock)
{
	setupUi(this);

	m_strID = tr("[%1] %2").arg(iCounter).arg(m_strDataset);
	setWindowTitle(m_strID);
	m_listWidget_Lock->addItem(m_strID);

	LoadImages();

	ToggleRenderWindowView1x3();
	resize(405, 278);
}

RenderWindow::~RenderWindow() {

}

void RenderWindow::LoadImages() {
	m_Pixmap1x3.load("RenderWin1x3.png");
	m_Pixmap2x2.load("RenderWin2x2.png");
	m_PixmapSingle.load("RenderWin1.png");
}

void RenderWindow::ToggleRenderWindowView1x3() {
	label->setPixmap(m_Pixmap1x3);
}

void RenderWindow::ToggleRenderWindowView2x2() {
	label->setPixmap(m_Pixmap2x2);
}

void RenderWindow::ToggleRenderWindowViewSingle() {
	label->setPixmap(m_PixmapSingle);
}

void RenderWindow::closeEvent(QCloseEvent *event) {
	QDialog::closeEvent(event);

	QList<QListWidgetItem*> l = m_listWidget_Lock->findItems(m_strID,  Qt::MatchExactly);

	assert(l.size() == 1); // if l.size() != 1 something went wrong during the creation of the list

	delete l[0];
}
<commit_msg><commit_after>#include "RenderWindow.h"
#include <assert.h>

RenderWindow::RenderWindow(QString dataset, QListWidget *listWidget_Lock, unsigned int iCounter, QWidget* parent /* = 0 */, Qt::WindowFlags flags /* = 0 */) :
	QDialog(parent, flags),
	m_strDataset(dataset),
	m_listWidget_Lock(listWidget_Lock)
{
	setupUi(this);

	m_strID = tr("[%1] %2").arg(iCounter).arg(m_strDataset);
	setWindowTitle(m_strID);
	m_listWidget_Lock->addItem(m_strID);

	LoadImages();

	ToggleRenderWindowView1x3();
}

RenderWindow::~RenderWindow() {

}

void RenderWindow::LoadImages() {
	m_Pixmap1x3.load("RenderWin1x3.png");
	m_Pixmap2x2.load("RenderWin2x2.png");
	m_PixmapSingle.load("RenderWin1.png");
}

void RenderWindow::ToggleRenderWindowView1x3() {
	label->setPixmap(m_Pixmap1x3);
}

void RenderWindow::ToggleRenderWindowView2x2() {
	label->setPixmap(m_Pixmap2x2);
}

void RenderWindow::ToggleRenderWindowViewSingle() {
	label->setPixmap(m_PixmapSingle);
}

void RenderWindow::closeEvent(QCloseEvent *event) {
	QDialog::closeEvent(event);

	QList<QListWidgetItem*> l = m_listWidget_Lock->findItems(m_strID,  Qt::MatchExactly);

	assert(l.size() == 1); // if l.size() != 1 something went wrong during the creation of the list

	delete l[0];
}
<|endoftext|>


<commit_before>/*$Id$
 *
 * This source file is a part of the Fresco Project.
 * Copyright (C) 2000 Stefan Seefeld <stefan@fresco.org>
 * Copyright (C) 2001 Philip Philonenko <philonenko@orgacom.ru>
 * http://www.fresco.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include <Prague/Sys/Tracer.hh>
#include <Berlin/Logger.hh>
#include "SDLGL.hh"

// ---------------------------------------------------------------
// class SDL::GLExposeHandler (implementation)
// ---------------------------------------------------------------
void SDL::GLExposeHandler::refresh_screen()
{
  Prague::Trace trace("SDL::GLExposeHandler::refresh_screen()");

  ::Console::Drawable * drawable =
    dynamic_cast<SDL::Drawable *>(::Console::instance()->drawable());

  glDisable(GL_ALPHA_TEST);
  glDisable(GL_BLEND);
  glDisable(GL_SCISSOR_TEST);

  glReadBuffer(GL_BACK);
  glDrawBuffer(GL_FRONT);
  glRasterPos2i(0, 0);

  glCopyPixels(0, 0, drawable->width(), drawable->height(), GL_COLOR);
  glFlush();

  glEnable(GL_ALPHA_TEST);
  glEnable(GL_BLEND);
  glEnable(GL_SCISSOR_TEST);

  glDrawBuffer(GL_BACK);

  _glcontext->flush();
}

// ---------------------------------------------------------------
// class SDL::GLContext (implementation)
// ---------------------------------------------------------------

SDL::GLContext::GLContext()
{
  Prague::Trace trace("SDL::GLContext::GLContext()");

  _drawable =
    dynamic_cast<SDL::Drawable *>(::Console::instance()->drawable());

  Fresco::PixelCoord w(_drawable->width());
  Fresco::PixelCoord h(_drawable->height());

  Logger::log(Logger::loader) << "setting video mode GL " << " w="
			      << w << " h= " << h << std::endl;

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  SDL_Surface * surface = SDL_SetVideoMode(w, h, 0,
					   SDL_HWSURFACE | SDL_HWPALETTE |
					   SDL_OPENGL |
					   SDL_DOUBLEBUF |
					   SDL_HWACCEL);
  SDL_WM_SetCaption("Berlin on SDL (OpenGL)", NULL);
  SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &_isDoubleBuffered);
  if (!_isDoubleBuffered) {
    std::cout << "SDL_Error: " << SDL_GetError() << std::endl;
    throw;
  }

  // HACK: Replace the 'real' drawable with its OpenGL-replacement.
  _drawable->_surface = surface;
  _drawable->_width = w;
  _drawable->_height = h;

  int bits;
  glGetIntegerv(GL_DEPTH_BITS, &bits);
  switch (bits)
    {
    case  0: _drawable->_depth = 0; break;
    case  8: _drawable->_depth = 1; break;
    case 16: _drawable->_depth = 2; break;
    case 24: _drawable->_depth = 3; break;
    case 32: _drawable->_depth = 4; break;
    default:
      _drawable->_depth = 0;
    }

  glDrawBuffer(GL_BACK);

  // setup PointerManager:
  dynamic_cast<SDL::Console *>(::Console::instance())->
    set_PointerManager(new SDL::PointerManagerT<GLPointer>);

  // setup ExposeHandler:
  dynamic_cast<SDL::Console *>(::Console::instance())->
    set_ExposeHandler(new SDL::GLExposeHandler(this));
}

SDL::GLContext::~GLContext()
{
  Prague::Trace trace("SDL::GLContext::~SDLGLContext()");
}

void SDL::GLContext::flush() {
  Prague::Trace trace("SDL::GLContext::flush()");

  if (_isDoubleBuffered) {
    glFlush();
    SDL_GL_SwapBuffers();

    glDisable(GL_ALPHA_TEST);
    glDisable(GL_BLEND);
    glDisable(GL_SCISSOR_TEST);

    glReadBuffer(GL_FRONT);
    glDrawBuffer(GL_BACK);
    glRasterPos2i(0, 0);

    glCopyPixels(0, 0, _drawable->width(), _drawable->height(), GL_COLOR);

    glEnable(GL_ALPHA_TEST);
    glEnable(GL_BLEND);
    glEnable(GL_SCISSOR_TEST);
  } else {
    // FIXME: TODO
  }
}

// ---------------------------------------------------------------
// class SDL::GLPointer (implementation)
// ---------------------------------------------------------------

SDL::GLPointer::GLPointer(Drawable * drawable, Fresco::Raster_ptr raster)
{
  Prague::Trace trace("SDL::GLPointer::GLPointer(...)");

  // copy over the Raster:
  _raster = Fresco::Raster::_duplicate(raster);

  // get screensizes:
  _max_y_size = drawable->height();

  // copy over the Raster:
  _raster = Fresco::Raster::_duplicate(raster);

  // Disable SDL default mousecursor
  SDL_ShowCursor(0);

  // Copy the raster over into the Drawable:
  Fresco::Raster::Info info = raster->header();
  Fresco::Raster::ColorSeq_var pixels;
  Fresco::Raster::Index lower, upper;
  lower.x = lower.y = 0;
  upper.x = info.width, upper.y = info.height;
  raster->store_pixels(lower, upper, pixels);
  _origin[0] = _origin[1] = 0;
  _size[0] = info.width;
  _size[1] = info.height;
  _scale[0] = 1.0/drawable->resolution(Fresco::xaxis);
  _scale[1] = 1.0/drawable->resolution(Fresco::yaxis);

  _cursor = new Uint8[_size[0] * _size[1] * 4]; // RGBA
  _saved_area = new Uint8[_size[0] * _size[1] * 3]; //RGB

  unsigned pos = 0;
  Fresco::Color c;

  for (unsigned short y = 0; y != _size[1]; ++y)
    for (unsigned short x = 0; x != _size[0]; ++x)
      {
	c = (*(pixels->get_buffer() + y * info.width + x));

	pos = (((_size[1] - 1 - y) * _size[0] + x) << 2);

	_cursor[pos + 0] = Uint8(c.red   * 0xFF);
	_cursor[pos + 1] = Uint8(c.green * 0xFF);
	_cursor[pos + 2] = Uint8(c.blue  * 0xFF);
	_cursor[pos + 3] = Uint8(c.alpha * 0xFF);
      }

  // set position
  _position[0] = _position[1] = 8;
}

SDL::GLPointer::~GLPointer()
{
  restore();
  delete[] _cursor;
  delete[] _saved_area;
}

void SDL::GLPointer::save()
{
  Prague::Trace trace("SDL::GLPointer::save()");

  Fresco::PixelCoord x = _position[0] - _origin[0];
  Fresco::PixelCoord y = _max_y_size - _position[1] - _size[1] + _origin[1];
  glDisable(GL_BLEND);
  glDisable(GL_ALPHA);
  glDisable(GL_SCISSOR_TEST);

  glReadBuffer(GL_FRONT);
  glReadPixels(x, y,
	       _size[0], _size[1],
	       GL_RGB, GL_UNSIGNED_BYTE,
	       _saved_area);
  glEnable(GL_BLEND);
  glEnable(GL_ALPHA);
  glEnable(GL_SCISSOR_TEST);
}

void SDL::GLPointer::restore()
{
  Prague::Trace trace("SDL::GLPointer::restore()");

  Fresco::PixelCoord x = _position[0] - _origin[0];
  Fresco::PixelCoord y = _position[1] + _size[1] - _origin[1];
  glDisable(GL_BLEND);
  glDisable(GL_ALPHA);
  glDisable(GL_SCISSOR_TEST);

  glRasterPos2i((int)(x * _scale[0]), (int)(y * _scale[1]));
  glDrawBuffer(GL_FRONT);
  glDrawPixels(_size[0], _size[1], GL_RGB, GL_UNSIGNED_BYTE, _saved_area);

  glEnable(GL_BLEND);
  glEnable(GL_ALPHA);
  glEnable(GL_SCISSOR_TEST);
  glDrawBuffer(GL_BACK);
}

void SDL::GLPointer::draw()
{
  Prague::Trace trace("SDL::GLPointer::draw()");

  Fresco::PixelCoord x = _position[0] - _origin[0];
  Fresco::PixelCoord y = _position[1] + _size[1] - _origin[1];
  glDisable(GL_SCISSOR_TEST);

  glDrawBuffer(GL_FRONT);
  glRasterPos2i((int)(x * _scale[0]), (int)(y * _scale[1]));
  glDrawPixels(_size[0], _size[1], GL_RGBA, GL_UNSIGNED_BYTE, _cursor);

  glEnable(GL_SCISSOR_TEST);
  glFlush();
  glDrawBuffer(GL_BACK);
}

// ---------------------------------------------------------------
// externs
// ---------------------------------------------------------------

extern "C" Console::Extension *load() { return new SDL::GLContext();}
<commit_msg>Stop the mouse pointer from disappearing near the bottom of the window in SDL GL mode. Fixes bug150.<commit_after>/*$Id$
 *
 * This source file is a part of the Fresco Project.
 * Copyright (C) 2000 Stefan Seefeld <stefan@fresco.org>
 * Copyright (C) 2001 Philip Philonenko <philonenko@orgacom.ru>
 * http://www.fresco.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include <Prague/Sys/Tracer.hh>
#include <Berlin/Logger.hh>
#include "SDLGL.hh"

// ---------------------------------------------------------------
// class SDL::GLExposeHandler (implementation)
// ---------------------------------------------------------------
void SDL::GLExposeHandler::refresh_screen()
{
  Prague::Trace trace("SDL::GLExposeHandler::refresh_screen()");

  ::Console::Drawable * drawable =
    dynamic_cast<SDL::Drawable *>(::Console::instance()->drawable());

  glDisable(GL_ALPHA_TEST);
  glDisable(GL_BLEND);
  glDisable(GL_SCISSOR_TEST);

  glReadBuffer(GL_BACK);
  glDrawBuffer(GL_FRONT);
  glRasterPos2i(0, 0);

  glCopyPixels(0, 0, drawable->width(), drawable->height(), GL_COLOR);
  glFlush();

  glEnable(GL_ALPHA_TEST);
  glEnable(GL_BLEND);
  glEnable(GL_SCISSOR_TEST);

  glDrawBuffer(GL_BACK);

  _glcontext->flush();
}

// ---------------------------------------------------------------
// class SDL::GLContext (implementation)
// ---------------------------------------------------------------

SDL::GLContext::GLContext()
{
  Prague::Trace trace("SDL::GLContext::GLContext()");

  _drawable =
    dynamic_cast<SDL::Drawable *>(::Console::instance()->drawable());

  Fresco::PixelCoord w(_drawable->width());
  Fresco::PixelCoord h(_drawable->height());

  Logger::log(Logger::loader) << "setting video mode GL " << " w="
			      << w << " h= " << h << std::endl;

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  SDL_Surface * surface = SDL_SetVideoMode(w, h, 0,
					   SDL_HWSURFACE | SDL_HWPALETTE |
					   SDL_OPENGL |
					   SDL_DOUBLEBUF |
					   SDL_HWACCEL);
  SDL_WM_SetCaption("Berlin on SDL (OpenGL)", NULL);
  SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &_isDoubleBuffered);
  if (!_isDoubleBuffered) {
    std::cout << "SDL_Error: " << SDL_GetError() << std::endl;
    throw;
  }

  // HACK: Replace the 'real' drawable with its OpenGL-replacement.
  _drawable->_surface = surface;
  _drawable->_width = w;
  _drawable->_height = h;

  int bits;
  glGetIntegerv(GL_DEPTH_BITS, &bits);
  switch (bits)
    {
    case  0: _drawable->_depth = 0; break;
    case  8: _drawable->_depth = 1; break;
    case 16: _drawable->_depth = 2; break;
    case 24: _drawable->_depth = 3; break;
    case 32: _drawable->_depth = 4; break;
    default:
      _drawable->_depth = 0;
    }

  glDrawBuffer(GL_BACK);

  // setup PointerManager:
  dynamic_cast<SDL::Console *>(::Console::instance())->
    set_PointerManager(new SDL::PointerManagerT<GLPointer>);

  // setup ExposeHandler:
  dynamic_cast<SDL::Console *>(::Console::instance())->
    set_ExposeHandler(new SDL::GLExposeHandler(this));
}

SDL::GLContext::~GLContext()
{
  Prague::Trace trace("SDL::GLContext::~SDLGLContext()");
}

void SDL::GLContext::flush() {
  Prague::Trace trace("SDL::GLContext::flush()");

  if (_isDoubleBuffered) {
    glFlush();
    SDL_GL_SwapBuffers();

    glDisable(GL_ALPHA_TEST);
    glDisable(GL_BLEND);
    glDisable(GL_SCISSOR_TEST);

    glReadBuffer(GL_FRONT);
    glDrawBuffer(GL_BACK);
    glRasterPos2i(0, 0);

    glCopyPixels(0, 0, _drawable->width(), _drawable->height(), GL_COLOR);

    glEnable(GL_ALPHA_TEST);
    glEnable(GL_BLEND);
    glEnable(GL_SCISSOR_TEST);
  } else {
    // FIXME: TODO
  }
}

// ---------------------------------------------------------------
// class SDL::GLPointer (implementation)
// ---------------------------------------------------------------

SDL::GLPointer::GLPointer(Drawable * drawable, Fresco::Raster_ptr raster)
{
  Prague::Trace trace("SDL::GLPointer::GLPointer(...)");

  // copy over the Raster:
  _raster = Fresco::Raster::_duplicate(raster);

  // get screensizes:
  _max_y_size = drawable->height();

  // copy over the Raster:
  _raster = Fresco::Raster::_duplicate(raster);

  // Disable SDL default mousecursor
  SDL_ShowCursor(0);

  // Copy the raster over into the Drawable:
  Fresco::Raster::Info info = raster->header();
  Fresco::Raster::ColorSeq_var pixels;
  Fresco::Raster::Index lower, upper;
  lower.x = lower.y = 0;
  upper.x = info.width, upper.y = info.height;
  raster->store_pixels(lower, upper, pixels);
  _origin[0] = _origin[1] = 0;
  _size[0] = info.width;
  _size[1] = info.height;
  _scale[0] = 1.0/drawable->resolution(Fresco::xaxis);
  _scale[1] = 1.0/drawable->resolution(Fresco::yaxis);

  _cursor = new Uint8[_size[0] * _size[1] * 4]; // RGBA
  _saved_area = new Uint8[_size[0] * _size[1] * 3]; //RGB

  unsigned pos = 0;
  Fresco::Color c;

  for (unsigned short y = 0; y != _size[1]; ++y)
    for (unsigned short x = 0; x != _size[0]; ++x)
      {
	c = (*(pixels->get_buffer() + y * info.width + x));

	pos = (((_size[1] - 1 - y) * _size[0] + x) << 2);

	_cursor[pos + 0] = Uint8(c.red   * 0xFF);
	_cursor[pos + 1] = Uint8(c.green * 0xFF);
	_cursor[pos + 2] = Uint8(c.blue  * 0xFF);
	_cursor[pos + 3] = Uint8(c.alpha * 0xFF);
      }

  // set position
  _position[0] = _position[1] = 8;
}

SDL::GLPointer::~GLPointer()
{
  restore();
  delete[] _cursor;
  delete[] _saved_area;
}

void SDL::GLPointer::save()
{
  Prague::Trace trace("SDL::GLPointer::save()");

  Fresco::PixelCoord x = _position[0] - _origin[0];
  Fresco::PixelCoord y = _max_y_size - _position[1] - _size[1] + _origin[1];
  int offset = 0;
  if (y >= _max_y_size) {
    offset = y - _max_y_size + 1;
    y = _max_y_size-1;
  }
  glDisable(GL_BLEND);
  glDisable(GL_ALPHA);
  glDisable(GL_SCISSOR_TEST);

  glReadBuffer(GL_FRONT);
  glReadPixels(x, y,
	       _size[0], _size[1]-offset,
	       GL_RGB, GL_UNSIGNED_BYTE,
	       _saved_area);
  glEnable(GL_BLEND);
  glEnable(GL_ALPHA);
  glEnable(GL_SCISSOR_TEST);
}

void SDL::GLPointer::restore()
{
  Prague::Trace trace("SDL::GLPointer::restore()");

  Fresco::PixelCoord x = _position[0] - _origin[0];
  Fresco::PixelCoord y = _position[1] + _size[1] - _origin[1];
  int offset = 0;
  if (y >= _max_y_size) {
    offset = y - _max_y_size + 1;
    y = _max_y_size-1;
  }
  glDisable(GL_BLEND);
  glDisable(GL_ALPHA);
  glDisable(GL_SCISSOR_TEST);

  glRasterPos2i((int)(x * _scale[0]), (int)(y * _scale[1]));
  glDrawBuffer(GL_FRONT);
  glDrawPixels(_size[0], _size[1]-offset, GL_RGB, GL_UNSIGNED_BYTE, _saved_area);

  glEnable(GL_BLEND);
  glEnable(GL_ALPHA);
  glEnable(GL_SCISSOR_TEST);
  glDrawBuffer(GL_BACK);
}

void SDL::GLPointer::draw()
{
  Prague::Trace trace("SDL::GLPointer::draw()");

  Fresco::PixelCoord x = _position[0] - _origin[0];
  Fresco::PixelCoord y = _position[1] + _size[1] - _origin[1];
  int offset = 0;
  if (y >= _max_y_size) {
    offset = y - _max_y_size + 1;
    y = _max_y_size-1;
  }
  glDisable(GL_SCISSOR_TEST);

  glDrawBuffer(GL_FRONT);
  glRasterPos2i((int)(x * _scale[0]), (int)(y * _scale[1]));
  glDrawPixels(_size[0], _size[1]-offset, GL_RGBA, GL_UNSIGNED_BYTE, _cursor+(offset*_size[0]*4));

  glEnable(GL_SCISSOR_TEST);
  glFlush();
  glDrawBuffer(GL_BACK);
}

// ---------------------------------------------------------------
// externs
// ---------------------------------------------------------------

extern "C" Console::Extension *load() { return new SDL::GLContext();}
<|endoftext|>


<commit_before>// Copyright (c) 2014, Ruslan Baratov
// All rights reserved.

#include "Weather.hpp"

#include <boost/network/protocol/http/client.hpp>

#include "Exception.hpp"
#include "Json.hpp"

Weather::Weather(): client_(new Client) {
}

Weather::~Weather() {
}

Result Weather::get_result(const char* city) BOOST_NOEXCEPT {
  try {
    return process_city(city);
  }
  catch (Exception& exception) {
    return Result(Result::Error(exception.what()));
  }
  catch (std::exception& exception) {
    return Result(Result::Error(exception.what()));
  }
  catch (...) {
    return Result(Result::Error("Unknown exception"));
  }
}

Result Weather::process_city(const char* city) {
  std::string body = get_body(city);

  Json doc(body.c_str());

  std::string temperature = doc.get_number("main", "temp");
  assert(!temperature.empty());
  if (temperature[0] != '-') {
    temperature = '+' + temperature;
  }

  // http://www.fileformat.info/info/unicode/char/2103/index.htm
  temperature += " \xE2\x84\x83"; // Degree Celsius

  Result::Mandatory mandatory(
      doc.get_number("coord", "lon"),
      doc.get_number("coord", "lat"),
      temperature,
      doc.get_number("wind", "speed") + " mps"
  );

  try {
    Result::Detailed detailed(
        doc.get_string("weather", "icon"),
        doc.get_string("weather", "description")
    );
    return Result(mandatory, detailed);
  }
  catch(Exception&) {
    // ignore exception, detailed description is optional
  }

  return Result(mandatory);
}

std::string Weather::get_body(const char* city) {
  std::string request_url("http://api.openweathermap.org/data/2.5/weather?q=");
  request_url += city;
  request_url += "&units=metric";

  namespace network = boost::network;
  namespace http = network::http;

  http::client::request request(request_url);
  request << network::header("Connection", "close");
  http::client::response response = client_->get(request);
  return http::body(response);
}
<commit_msg>Encode city<commit_after>// Copyright (c) 2014, Ruslan Baratov
// All rights reserved.

#include "Weather.hpp"

#include <boost/network/protocol/http/client.hpp>

#include "Exception.hpp"
#include "Json.hpp"

Weather::Weather(): client_(new Client) {
}

Weather::~Weather() {
}

Result Weather::get_result(const char* city) BOOST_NOEXCEPT {
  try {
    return process_city(city);
  }
  catch (Exception& exception) {
    return Result(Result::Error(exception.what()));
  }
  catch (std::exception& exception) {
    return Result(Result::Error(exception.what()));
  }
  catch (...) {
    return Result(Result::Error("Unknown exception"));
  }
}

Result Weather::process_city(const char* city) {
  std::string body = get_body(city);

  Json doc(body.c_str());

  std::string temperature = doc.get_number("main", "temp");
  assert(!temperature.empty());
  if (temperature[0] != '-') {
    temperature = '+' + temperature;
  }

  // http://www.fileformat.info/info/unicode/char/2103/index.htm
  temperature += " \xE2\x84\x83"; // Degree Celsius

  Result::Mandatory mandatory(
      doc.get_number("coord", "lon"),
      doc.get_number("coord", "lat"),
      temperature,
      doc.get_number("wind", "speed") + " mps"
  );

  try {
    Result::Detailed detailed(
        doc.get_string("weather", "icon"),
        doc.get_string("weather", "description")
    );
    return Result(mandatory, detailed);
  }
  catch(Exception&) {
    // ignore exception, detailed description is optional
  }

  return Result(mandatory);
}

std::string Weather::get_body(const char* city) {
  std::string request_url("http://api.openweathermap.org/data/2.5/weather?q=");
  request_url += boost::network::uri::encoded(city);
  request_url += "&units=metric";

  namespace network = boost::network;
  namespace http = network::http;

  http::client::request request(request_url);
  request << network::header("Connection", "close");
  http::client::response response = client_->get(request);
  return http::body(response);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Tests for CppBoundClass, in conjunction with CppBindingExample.  Binds
// a CppBindingExample class into JavaScript in a custom test shell and tests
// the binding from the outside by loading JS into the shell.

#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "webkit/glue/cpp_binding_example.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/tools/test_shell/test_shell_test.h"

using WebKit::WebFrame;
using webkit_glue::CppArgumentList;
using webkit_glue::CppBindingExample;
using webkit_glue::CppVariant;

namespace {

class CppBindingExampleSubObject : public CppBindingExample {
 public:
  CppBindingExampleSubObject() {
    sub_value_.Set("sub!");
    BindProperty("sub_value", &sub_value_);
  }
 private:
  CppVariant sub_value_;
};

class CppBindingExampleWithOptionalFallback : public CppBindingExample {
 public:
  CppBindingExampleWithOptionalFallback() {
    BindProperty("sub_object", sub_object_.GetAsCppVariant());
  }

  void set_fallback_method_enabled(bool state) {
    BindFallbackCallback(state ?
        base::Bind(&CppBindingExampleWithOptionalFallback::fallbackMethod,
                   base::Unretained(this))
        : CppBoundClass::Callback());
  }

  // The fallback method does nothing, but because of it the JavaScript keeps
  // running when a nonexistent method is called on an object.
  void fallbackMethod(const CppArgumentList& args, CppVariant* result) {
  }

 private:
  CppBindingExampleSubObject sub_object_;
};

class ExampleTestShell : public TestShell {
 public:

  ExampleTestShell(bool use_fallback_method) {
    example_bound_class_.set_fallback_method_enabled(use_fallback_method);
  }

  // When called by WebViewDelegate::WindowObjectCleared method, this binds a
  // CppExampleObject to window.example.
  virtual void BindJSObjectsToWindow(WebFrame* frame) {
    example_bound_class_.BindToJavascript(frame, "example");
    // We use the layoutTestController binding for notifyDone.
    TestShell::BindJSObjectsToWindow(frame);
  }

  // This is a public interface to TestShell's protected method, so it
  // can be called by our CreateEmptyWindow.
  bool PublicInitialize(const std::string& starting_url) {
    return Initialize(GURL(starting_url));
  }

  CppBindingExampleWithOptionalFallback example_bound_class_;
};

class CppBoundClassTest : public TestShellTest {
 protected:
   // Adapted from TestShell::CreateNewWindow, this creates an
   // ExampleTestShellWindow rather than a regular TestShell.
   virtual void CreateEmptyWindow() {
     ExampleTestShell* host = new ExampleTestShell(useFallback());
     ASSERT_TRUE(host != NULL);
     bool rv = host->PublicInitialize("about:blank");
     if (rv) {
       test_shell_ = host;
       TestShell::windowList()->push_back(host->mainWnd());
       webframe_ = test_shell_->webView()->mainFrame();
       ASSERT_TRUE(webframe_ != NULL);
     } else {
       delete host;
     }
   }

   // Wraps the given JavaScript snippet in ");
     // The base URL doesn't matter.
     webframe_->loadHTMLString(html, GURL("about:blank"));

     test_shell_->WaitTestFinished();
    }

   // Executes the specified JavaScript and checks to be sure that the resulting
   // document text is exactly "SUCCESS".
   void CheckJavaScriptSuccess(const std::string& javascript) {
     ExecuteJavaScript(javascript);
     EXPECT_EQ("SUCCESS",
               UTF16ToASCII(webkit_glue::DumpDocumentText(webframe_)));
   }

   // Executes the specified JavaScript and checks that the resulting document
   // text is empty.
   void CheckJavaScriptFailure(const std::string& javascript) {
     ExecuteJavaScript(javascript);
     EXPECT_EQ("", UTF16ToASCII(webkit_glue::DumpDocumentText(webframe_)));
   }

   // Constructs a JavaScript snippet that evaluates and compares the left and
   // right expressions, printing "SUCCESS" to the page if they are equal and
   // printing their actual values if they are not.  Any strings in the
   // expressions should be enclosed in single quotes, and no double quotes
   // should appear in either expression (even if escaped). (If a test case
   // is added that needs fancier quoting, Json::valueToQuotedString could be
   // used here.  For now, it's not worth adding the dependency.)
   std::string BuildJSCondition(std::string left, std::string right) {
     return "var leftval = " + left + ";" +
            "var rightval = " + right + ";" +
            "if (leftval == rightval) {" +
            "  document.writeln('SUCCESS');" +
            "} else {" +
            "  document.writeln(\"" +
                 left + " [\" + leftval + \"] != " +
                 right + " [\" + rightval + \"]\");" +
            "}";
   }

protected:
  virtual bool useFallback() {
    return false;
  }

private:
  WebFrame* webframe_;
};

class CppBoundClassWithFallbackMethodTest : public CppBoundClassTest {
protected:
  virtual bool useFallback() {
    return true;
  }
};

// Ensures that the example object has been bound to JS.
TEST_F(CppBoundClassTest, ObjectExists) {
  std::string js = BuildJSCondition("typeof window.example", "'object'");
  CheckJavaScriptSuccess(js);

  // An additional check to test our test.
  js = BuildJSCondition("typeof window.invalid_object", "'undefined'");
  CheckJavaScriptSuccess(js);
}

TEST_F(CppBoundClassTest, PropertiesAreInitialized) {
  std::string js = BuildJSCondition("example.my_value", "10");
  CheckJavaScriptSuccess(js);

  js = BuildJSCondition("example.my_other_value", "'Reinitialized!'");
  CheckJavaScriptSuccess(js);
}

TEST_F(CppBoundClassTest, SubOject) {
  std::string js = BuildJSCondition("typeof window.example.sub_object",
                                    "'object'");
  CheckJavaScriptSuccess(js);

  js = BuildJSCondition("example.sub_object.sub_value", "'sub!'");
  CheckJavaScriptSuccess(js);
}

TEST_F(CppBoundClassTest, SetAndGetProperties) {
  // The property on the left will be set to the value on the right, then
  // checked to make sure it holds that same value.
  static const std::string tests[] = {
    "example.my_value", "7",
    "example.my_value", "'test'",
    "example.my_other_value", "3.14",
    "example.my_other_value", "false",
    "" // Array end marker: insert additional test pairs before this.
  };

  for (int i = 0; tests[i] != ""; i += 2) {
    std::string left = tests[i];
    std::string right = tests[i + 1];
    // left = right;
    std::string js = left;
    js.append(" = ");
    js.append(right);
    js.append(";");
    js.append(BuildJSCondition(left, right));
    CheckJavaScriptSuccess(js);
  }
}

TEST_F(CppBoundClassTest, SetAndGetPropertiesWithCallbacks) {
  // TODO(dglazkov): fix NPObject issues around failing property setters and
  // getters and add tests for situations when GetProperty or SetProperty fail.
  std::string js = "var result = 'SUCCESS';\n"
    "example.my_value_with_callback = 10;\n"
    "if (example.my_value_with_callback != 10)\n"
    "  result = 'FAIL: unable to set property.';\n"
    "example.my_value_with_callback = 11;\n"
    "if (example.my_value_with_callback != 11)\n"
    "  result = 'FAIL: unable to set property again';\n"
    "if (example.same != 42)\n"
    "  result = 'FAIL: same property should always be 42';\n"
    "example.same = 24;\n"
    "if (example.same != 42)\n"
    "  result = 'FAIL: same property should always be 42';\n"
    "document.writeln(result);\n";
  CheckJavaScriptSuccess(js);
}

TEST_F(CppBoundClassTest, InvokeMethods) {
  // The expression on the left is expected to return the value on the right.
  static const std::string tests[] = {
    "example.echoValue(true)", "true",
    "example.echoValue(13)", "13",
    "example.echoValue(2.718)", "2.718",
    "example.echoValue('yes')", "'yes'",
    "example.echoValue()", "null",     // Too few arguments

    "example.echoType(false)", "true",
    "example.echoType(19)", "3.14159",
    "example.echoType(9.876)", "3.14159",
    "example.echoType('test string')", "'Success!'",
    "example.echoType()", "null",      // Too few arguments

    // Comparing floats that aren't integer-valued is usually problematic due
    // to rounding, but exact powers of 2 should also be safe.
    "example.plus(2.5, 18.0)", "20.5",
    "example.plus(2, 3.25)", "5.25",
    "example.plus(2, 3)", "5",
    "example.plus()", "null",             // Too few arguments
    "example.plus(1)", "null",            // Too few arguments
    "example.plus(1, 'test')", "null",    // Wrong argument type
    "example.plus('test', 2)", "null",    // Wrong argument type
    "example.plus('one', 'two')", "null", // Wrong argument type
    "" // Array end marker: insert additional test pairs before this.
  };

  for (int i = 0; tests[i] != ""; i+= 2) {
    std::string left = tests[i];
    std::string right = tests[i + 1];
    std::string js = BuildJSCondition(left, right);
    CheckJavaScriptSuccess(js);
  }

  std::string js = "example.my_value = 3.25; example.my_other_value = 1.25;";
  js.append(BuildJSCondition(
      "example.plus(example.my_value, example.my_other_value)", "4.5"));
  CheckJavaScriptSuccess(js);
}

// Tests that invoking a nonexistent method with no fallback method stops the
// script's execution
TEST_F(CppBoundClassTest,
       InvokeNonexistentMethodNoFallback) {
  std::string js = "example.nonExistentMethod();document.writeln('SUCCESS');";
  CheckJavaScriptFailure(js);
}

// Ensures existent methods can be invoked successfully when the fallback method
// is used
TEST_F(CppBoundClassWithFallbackMethodTest,
       InvokeExistentMethodsWithFallback) {
  std::string js = BuildJSCondition("example.echoValue(34)", "34");
  CheckJavaScriptSuccess(js);
}

}  // namespace
<commit_msg>Remove layoutTestController from CppBoundClassTest in test_shell_tests.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Tests for CppBoundClass, in conjunction with CppBindingExample.  Binds
// a CppBindingExample class into JavaScript in a custom test shell and tests
// the binding from the outside by loading JS into the shell.

#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSettings.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebViewClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebKitPlatformSupport.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "webkit/glue/cpp_binding_example.h"
#include "webkit/glue/webkit_glue.h"

using WebKit::WebFrame;
using WebKit::WebView;
using webkit_glue::CppArgumentList;
using webkit_glue::CppBindingExample;
using webkit_glue::CppVariant;

namespace {

class CppBindingExampleSubObject : public CppBindingExample {
 public:
  CppBindingExampleSubObject() {
    sub_value_.Set("sub!");
    BindProperty("sub_value", &sub_value_);
  }
 private:
  CppVariant sub_value_;
};

class CppBindingExampleWithOptionalFallback : public CppBindingExample {
 public:
  CppBindingExampleWithOptionalFallback() {
    BindProperty("sub_object", sub_object_.GetAsCppVariant());
  }

  void set_fallback_method_enabled(bool state) {
    BindFallbackCallback(state ?
        base::Bind(&CppBindingExampleWithOptionalFallback::fallbackMethod,
                   base::Unretained(this))
        : CppBoundClass::Callback());
  }

  // The fallback method does nothing, but because of it the JavaScript keeps
  // running when a nonexistent method is called on an object.
  void fallbackMethod(const CppArgumentList& args, CppVariant* result) {
  }

 private:
  CppBindingExampleSubObject sub_object_;
};

class TestWebFrameClient : public WebKit::WebFrameClient {
 public:
  virtual void didClearWindowObject(WebKit::WebFrame* frame) OVERRIDE {
    example_bound_class_.BindToJavascript(frame, "example");
  }
  void set_fallback_method_enabled(bool use_fallback) {
    example_bound_class_.set_fallback_method_enabled(use_fallback);
  }
 private:
  CppBindingExampleWithOptionalFallback example_bound_class_;
};

class TestWebViewClient : public WebKit::WebViewClient {
};

class CppBoundClassTest : public testing::Test, public WebKit::WebFrameClient {
 public:
  CppBoundClassTest() : webview_(NULL) { }

  virtual void SetUp() OVERRIDE {
    webview_ = WebView::create(&webview_client_);
    webview_->settings()->setJavaScriptEnabled(true);
    webview_->initializeMainFrame(&webframe_client_);
    webframe_client_.set_fallback_method_enabled(useFallback());

    WebKit::WebURLRequest urlRequest;
    urlRequest.initialize();
    urlRequest.setURL(GURL("about:blank"));
    webframe()->loadRequest(urlRequest);
  }

  virtual void TearDown() OVERRIDE {
    if (webview_)
      webview_->close();
  }

  WebFrame* webframe() {
    return webview_->mainFrame();
  }

  // Wraps the given JavaScript snippet in ");
    webframe()->loadHTMLString(html, GURL("about:blank"));
    MessageLoop::current()->RunAllPending();
  }

  // Executes the specified JavaScript and checks to be sure that the resulting
  // document text is exactly "SUCCESS".
  void CheckJavaScriptSuccess(const std::string& javascript) {
    ExecuteJavaScript(javascript);
    EXPECT_EQ("SUCCESS",
              UTF16ToASCII(webkit_glue::DumpDocumentText(webframe())));
  }

  // Executes the specified JavaScript and checks that the resulting document
  // text is empty.
  void CheckJavaScriptFailure(const std::string& javascript) {
    ExecuteJavaScript(javascript);
    EXPECT_EQ("", UTF16ToASCII(webkit_glue::DumpDocumentText(webframe())));
  }

  // Constructs a JavaScript snippet that evaluates and compares the left and
  // right expressions, printing "SUCCESS" to the page if they are equal and
  // printing their actual values if they are not.  Any strings in the
  // expressions should be enclosed in single quotes, and no double quotes
  // should appear in either expression (even if escaped). (If a test case
  // is added that needs fancier quoting, Json::valueToQuotedString could be
  // used here.  For now, it's not worth adding the dependency.)
  std::string BuildJSCondition(std::string left, std::string right) {
    return "var leftval = " + left + ";" +
           "var rightval = " + right + ";" +
           "if (leftval == rightval) {" +
           "  document.writeln('SUCCESS');" +
           "} else {" +
           "  document.writeln(\"" +
                left + " [\" + leftval + \"] != " +
                right + " [\" + rightval + \"]\");" +
           "}";
  }

 protected:
  virtual bool useFallback() {
    return false;
  }

 private:
  WebView* webview_;
  TestWebFrameClient webframe_client_;
  TestWebViewClient webview_client_;
};

class CppBoundClassWithFallbackMethodTest : public CppBoundClassTest {
 protected:
  virtual bool useFallback() {
    return true;
  }
};

// Ensures that the example object has been bound to JS.
TEST_F(CppBoundClassTest, ObjectExists) {
  std::string js = BuildJSCondition("typeof window.example", "'object'");
  CheckJavaScriptSuccess(js);

  // An additional check to test our test.
  js = BuildJSCondition("typeof window.invalid_object", "'undefined'");
  CheckJavaScriptSuccess(js);
}

TEST_F(CppBoundClassTest, PropertiesAreInitialized) {
  std::string js = BuildJSCondition("example.my_value", "10");
  CheckJavaScriptSuccess(js);

  js = BuildJSCondition("example.my_other_value", "'Reinitialized!'");
  CheckJavaScriptSuccess(js);
}

TEST_F(CppBoundClassTest, SubOject) {
  std::string js = BuildJSCondition("typeof window.example.sub_object",
                                    "'object'");
  CheckJavaScriptSuccess(js);

  js = BuildJSCondition("example.sub_object.sub_value", "'sub!'");
  CheckJavaScriptSuccess(js);
}

TEST_F(CppBoundClassTest, SetAndGetProperties) {
  // The property on the left will be set to the value on the right, then
  // checked to make sure it holds that same value.
  static const std::string tests[] = {
    "example.my_value", "7",
    "example.my_value", "'test'",
    "example.my_other_value", "3.14",
    "example.my_other_value", "false",
    "" // Array end marker: insert additional test pairs before this.
  };

  for (int i = 0; tests[i] != ""; i += 2) {
    std::string left = tests[i];
    std::string right = tests[i + 1];
    // left = right;
    std::string js = left;
    js.append(" = ");
    js.append(right);
    js.append(";");
    js.append(BuildJSCondition(left, right));
    CheckJavaScriptSuccess(js);
  }
}

TEST_F(CppBoundClassTest, SetAndGetPropertiesWithCallbacks) {
  // TODO(dglazkov): fix NPObject issues around failing property setters and
  // getters and add tests for situations when GetProperty or SetProperty fail.
  std::string js = "var result = 'SUCCESS';\n"
    "example.my_value_with_callback = 10;\n"
    "if (example.my_value_with_callback != 10)\n"
    "  result = 'FAIL: unable to set property.';\n"
    "example.my_value_with_callback = 11;\n"
    "if (example.my_value_with_callback != 11)\n"
    "  result = 'FAIL: unable to set property again';\n"
    "if (example.same != 42)\n"
    "  result = 'FAIL: same property should always be 42';\n"
    "example.same = 24;\n"
    "if (example.same != 42)\n"
    "  result = 'FAIL: same property should always be 42';\n"
    "document.writeln(result);\n";
  CheckJavaScriptSuccess(js);
}

TEST_F(CppBoundClassTest, InvokeMethods) {
  // The expression on the left is expected to return the value on the right.
  static const std::string tests[] = {
    "example.echoValue(true)", "true",
    "example.echoValue(13)", "13",
    "example.echoValue(2.718)", "2.718",
    "example.echoValue('yes')", "'yes'",
    "example.echoValue()", "null",     // Too few arguments

    "example.echoType(false)", "true",
    "example.echoType(19)", "3.14159",
    "example.echoType(9.876)", "3.14159",
    "example.echoType('test string')", "'Success!'",
    "example.echoType()", "null",      // Too few arguments

    // Comparing floats that aren't integer-valued is usually problematic due
    // to rounding, but exact powers of 2 should also be safe.
    "example.plus(2.5, 18.0)", "20.5",
    "example.plus(2, 3.25)", "5.25",
    "example.plus(2, 3)", "5",
    "example.plus()", "null",             // Too few arguments
    "example.plus(1)", "null",            // Too few arguments
    "example.plus(1, 'test')", "null",    // Wrong argument type
    "example.plus('test', 2)", "null",    // Wrong argument type
    "example.plus('one', 'two')", "null", // Wrong argument type
    "" // Array end marker: insert additional test pairs before this.
  };

  for (int i = 0; tests[i] != ""; i+= 2) {
    std::string left = tests[i];
    std::string right = tests[i + 1];
    std::string js = BuildJSCondition(left, right);
    CheckJavaScriptSuccess(js);
  }

  std::string js = "example.my_value = 3.25; example.my_other_value = 1.25;";
  js.append(BuildJSCondition(
      "example.plus(example.my_value, example.my_other_value)", "4.5"));
  CheckJavaScriptSuccess(js);
}

// Tests that invoking a nonexistent method with no fallback method stops the
// script's execution
TEST_F(CppBoundClassTest,
       InvokeNonexistentMethodNoFallback) {
  std::string js = "example.nonExistentMethod();document.writeln('SUCCESS');";
  CheckJavaScriptFailure(js);
}

// Ensures existent methods can be invoked successfully when the fallback method
// is used
TEST_F(CppBoundClassWithFallbackMethodTest,
       InvokeExistentMethodsWithFallback) {
  std::string js = BuildJSCondition("example.echoValue(34)", "34");
  CheckJavaScriptSuccess(js);
}

}  // namespace
<|endoftext|>