<?php
/**
 * @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
 */

namespace qfq;

use qfq;
//use qfq\helper;
use qfq\helper\KeyValueStringParser;

require_once(__DIR__ . '/../../qfq/helper/KeyValueStringParser.php');

class KeyValueStringParserTest extends \PHPUnit_Framework_TestCase {

    /**
     * @var KeyValueStringParser
     */
    private $keyValueStringParser;

    public function setUp() {
        $this->keyValueStringParser = new KeyValueStringParser();
    }

    public function testSingleKeyValuePair() {
        $actual = $this->keyValueStringParser->parse("key:value");

        $this->assertCount(1, $actual);
        $this->assertArrayHasKey('key', $actual);
        $this->assertEquals('value', $actual['key']);
    }

    public function testKeyWithoutValue() {
        $actual = $this->keyValueStringParser->parse("keywithoutvalue");
        $this->assertCount(1, $actual);
        $this->assertArrayHasKey('keywithoutvalue', $actual);
        $this->assertSame("", $actual['keywithoutvalue']);
    }

    public function testGOODNAMEHERE() {
        $actual = $this->keyValueStringParser->parse(",,");

        $this->assertCount(0, $actual);
    }

    /**
     * @expectedException \qfq\exceptions\UserException
     */
    public function testNoKey() {
        $this->keyValueStringParser->parse(":value,key:value");
    }

    public function testNoValue() {
        $actual = $this->keyValueStringParser->parse("key1:,key2:value2");
        $this->assertCount(2, $actual);
        $this->assertArrayHasKey('key1', $actual);
        $this->assertArrayHasKey('key2', $actual);
        $this->assertEquals('', $actual['key1']);
        $this->assertEquals('value2', $actual['key2']);
    }

    public function testEmptyKeyValuePairString() {
        $actual = $this->keyValueStringParser->parse("");

        $this->assertCount(0, $actual);
    }

    public function testMultipleKeyValuePairs() {
        $actual = $this->keyValueStringParser->parse("key1:value1,key2:value2");

        $this->assertCount(2, $actual);
        $this->assertArrayHasKey('key1', $actual);
        $this->assertArrayHasKey('key2', $actual);
        $this->assertEquals('value1', $actual['key1']);
        $this->assertEquals('value2', $actual['key2']);
    }

    public function testKeyValueSeparatorInValue() {
        $actual = $this->keyValueStringParser->parse("key1:val:ue1,key2:value2");

        $this->assertCount(2, $actual);
        $this->assertArrayHasKey('key1', $actual);
        $this->assertArrayHasKey('key2', $actual);
        $this->assertEquals('val:ue1', $actual['key1']);
        $this->assertEquals('value2', $actual['key2']);
    }

    public function testWhiteSpaceHandling() {
        $actual = $this->keyValueStringParser->parse(" key1 : val:ue1 , key2 : value2 ");

        $this->assertCount(2, $actual);
        $this->assertArrayHasKey('key1', $actual);
        $this->assertArrayHasKey('key2', $actual);
        $this->assertEquals('val:ue1', $actual['key1']);
        $this->assertEquals('value2', $actual['key2']);
    }

    public function testSourroundingQuotes() {
        $actual = $this->keyValueStringParser->parse("key1:\" val:ue1 \", key2:' value2 ', key3:\"value3', key4:''");

        $expected = [
            'key1' => ' val:ue1 ',
            'key2' => ' value2 ',
            'key3' => "\"value3'",
            'key4' => ''
        ];
        $this->assertEquals($expected, $actual);
    }

    public function testComments() {
        $actual = $this->keyValueStringParser->parse(" key1 : val:ue1 , # key2 : value2 , ; : broken key value in comment, key3 : valid ");

        $expected = [
            'key1' => 'val:ue1',
            'key3' => "valid",
        ];
        $this->assertEquals($expected, $actual);
    }

    public function testUnparse() {
        $array = $this->keyValueStringParser->parse("key1:\" val:ue1 \", key2:' value2 ', key3:\"value3'");
        $actual = $this->keyValueStringParser->unparse($array);
        $expected = "key1:\" val:ue1 \",key2:\" value2 \",key3:\"value3'";

        $this->assertSame($expected, $actual);

    }

    public function testKeyValuePairCR() {
        $keyValueStringParserCR = new KeyValueStringParser("=", "\n");

        $actual = $keyValueStringParserCR->parse("key1=value1\nkey2=value2");

        $this->assertCount(2, $actual);
        $this->assertArrayHasKey('key1', $actual);
        $this->assertArrayHasKey('key2', $actual);
        $this->assertEquals('value1', $actual['key1']);
        $this->assertEquals('value2', $actual['key2']);
    }

}