/**
     * Test HTML messages
     */
    public function testSendHTML()
    {
        $mailer = new MailerTest_MockMailer();
        // Test with default encoding
        $testMessageHTML = "<p>The majority of the <i>answers</i> so far are saying that private methods are " . "implementation details which don&#39;t (<a href=\"http://www.google.com\">or at least shouldn&#39;t</a>) " . "matter so long as the public interface is well-tested &amp; working</p> " . "<p>That&#39;s absolutely correct if your only purpose for testing is to guarantee that the " . "public interface works.</p>";
        $testMessagePlain = Convert::xml2raw($testMessageHTML);
        $this->assertTrue(stripos($testMessagePlain, '&#') === false);
        list($to, $subjectEncoded, $fullBody, $headersEncoded, $bounceAddress) = $mailer->sendHTML('<*****@*****.**>', 'tom@jones <*****@*****.**>', "What is the <purpose> of testing?", $testMessageHTML, null, array('CC' => '*****@*****.**', 'bcc' => '*****@*****.**'));
        $this->assertEquals('*****@*****.**', $to);
        $this->assertEquals('=?UTF-8?B?V2hhdCBpcyB0aGUgPHB1cnBvc2U+IG9mIHRlc3Rpbmc/?=', $subjectEncoded);
        $this->assertEquals('=?UTF-8?B?' . base64_encode('What is the <purpose> of testing?') . '?=', $subjectEncoded);
        $this->assertEquals(Convert::nl2os(<<<PHP

This is a multi-part message in MIME format.

------=_NextPart_000000000000
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

The majority of the answers so far are saying that private methods are impl=
ementation details which don't (or at least shouldn't[http://www.google.com=
]) matter so long as the public interface is well-tested & working=0A=0A=0A=
=0AThat's absolutely correct if your only purpose for testing is to guarant=
ee that the public interface works.

------=_NextPart_000000000000
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">=0A<HTML><HEA=
D>=0A<META http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-=
8">=0A<STYLE type=3D"text/css"></STYLE>=0A=0A</HEAD>=0A<BODY bgColor=3D"#ff=
ffff">=0A<p>The majority of the <i>answers</i> so far are saying that priva=
te methods are implementation details which don&#39;t (<a href=3D"http://ww=
w.google.com">or at least shouldn&#39;t</a>) matter so long as the public i=
nterface is well-tested &amp; working</p> <p>That&#39;s absolutely correct =
if your only purpose for testing is to guarantee that the public interface =
works.</p>=0A</BODY>=0A</HTML>
------=_NextPart_000000000000--
PHP
), Convert::nl2os($this->normaliseDivisions($fullBody)));
        // Check that the messages exist in the output
        $this->assertTrue(stripos($fullBody, quoted_printable_encode($testMessagePlain)) !== false);
        $this->assertEquals(<<<PHP
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="----=_NextPart_000000000000"
Content-Transfer-Encoding: 7bit
From: tomjones <*****@*****.**>
X-Mailer: SilverStripe Mailer - version 2006.06.21
X-Priority: 3
Bcc: andrew@thing.com
Cc: admin@silverstripe.com

PHP
, Convert::nl2os($this->normaliseDivisions($headersEncoded)));
        $this->assertEquals('*****@*****.**', $bounceAddress);
        // Test override bounce email and alternate encoding
        $mailer->setBounceEmail('*****@*****.**');
        $mailer->setMessageEncoding('base64');
        list($to, $subjectEncoded, $fullBody, $headersEncoded, $bounceAddress) = $mailer->sendHTML('<*****@*****.**>', 'tom@jones <*****@*****.**>', "What is the <purpose> of testing?", $testMessageHTML, null, array('CC' => '*****@*****.**', 'bcc' => '*****@*****.**'));
        $this->assertEquals('*****@*****.**', $bounceAddress);
        $this->assertEquals(<<<PHP

This is a multi-part message in MIME format.

------=_NextPart_000000000000
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64

VGhlIG1ham9yaXR5IG9mIHRoZSBhbnN3ZXJzIHNvIGZhciBhcmUgc2F5aW5n
IHRoYXQgcHJpdmF0ZSBtZXRob2RzIGFyZSBpbXBsZW1lbnRhdGlvbiBkZXRh
aWxzIHdoaWNoIGRvbid0IChvciBhdCBsZWFzdCBzaG91bGRuJ3RbaHR0cDov
L3d3dy5nb29nbGUuY29tXSkgbWF0dGVyIHNvIGxvbmcgYXMgdGhlIHB1Ymxp
YyBpbnRlcmZhY2UgaXMgd2VsbC10ZXN0ZWQgJiB3b3JraW5nCgoKClRoYXQn
cyBhYnNvbHV0ZWx5IGNvcnJlY3QgaWYgeW91ciBvbmx5IHB1cnBvc2UgZm9y
IHRlc3RpbmcgaXMgdG8gZ3VhcmFudGVlIHRoYXQgdGhlIHB1YmxpYyBpbnRl
cmZhY2Ugd29ya3Mu


------=_NextPart_000000000000
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBU
cmFuc2l0aW9uYWwvL0VOIj4KPEhUTUw+PEhFQUQ+CjxNRVRBIGh0dHAtZXF1
aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0
PXV0Zi04Ij4KPFNUWUxFIHR5cGU9InRleHQvY3NzIj48L1NUWUxFPgoKPC9I
RUFEPgo8Qk9EWSBiZ0NvbG9yPSIjZmZmZmZmIj4KPHA+VGhlIG1ham9yaXR5
IG9mIHRoZSA8aT5hbnN3ZXJzPC9pPiBzbyBmYXIgYXJlIHNheWluZyB0aGF0
IHByaXZhdGUgbWV0aG9kcyBhcmUgaW1wbGVtZW50YXRpb24gZGV0YWlscyB3
aGljaCBkb24mIzM5O3QgKDxhIGhyZWY9Imh0dHA6Ly93d3cuZ29vZ2xlLmNv
bSI+b3IgYXQgbGVhc3Qgc2hvdWxkbiYjMzk7dDwvYT4pIG1hdHRlciBzbyBs
b25nIGFzIHRoZSBwdWJsaWMgaW50ZXJmYWNlIGlzIHdlbGwtdGVzdGVkICZh
bXA7IHdvcmtpbmc8L3A+IDxwPlRoYXQmIzM5O3MgYWJzb2x1dGVseSBjb3Jy
ZWN0IGlmIHlvdXIgb25seSBwdXJwb3NlIGZvciB0ZXN0aW5nIGlzIHRvIGd1
YXJhbnRlZSB0aGF0IHRoZSBwdWJsaWMgaW50ZXJmYWNlIHdvcmtzLjwvcD4K
PC9CT0RZPgo8L0hUTUw+

------=_NextPart_000000000000--
PHP
, Convert::nl2os($this->normaliseDivisions($fullBody)));
        // Check that the text message version is somewhere in there
        $this->assertTrue(stripos($fullBody, chunk_split(base64_encode($testMessagePlain), 60)) !== false);
    }
 /**
  * Test getManipulatedData on subclassed dataobjects
  */
 public function testInheritedGetManiplatedData()
 {
     $list = GridFieldSortableHeaderTest_TeamGroup::get();
     $config = new GridFieldConfig_RecordEditor();
     $gridField = new GridField('testfield', 'testfield', $list, $config);
     $state = $gridField->State->GridFieldSortableHeader;
     $compontent = $gridField->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldSortableHeader');
     // Test that inherited dataobjects will work correctly
     $state->SortColumn = 'Cheerleader.Hat.Colour';
     $state->SortDirection = 'asc';
     $relationListA = $compontent->getManipulatedData($gridField, $list);
     $relationListAsql = Convert::nl2os($relationListA->sql(), ' ');
     // Assert that all tables are joined properly
     $this->assertContains('FROM "GridFieldSortableHeaderTest_Team"', $relationListAsql);
     $this->assertContains('LEFT JOIN "GridFieldSortableHeaderTest_TeamGroup" ' . 'ON "GridFieldSortableHeaderTest_TeamGroup"."ID" = "GridFieldSortableHeaderTest_Team"."ID"', $relationListAsql);
     $this->assertContains('LEFT JOIN "GridFieldSortableHeaderTest_Cheerleader" ' . 'ON "GridFieldSortableHeaderTest_Cheerleader"."ID" = "GridFieldSortableHeaderTest_Team"."CheerleaderID"', $relationListAsql);
     $this->assertContains('LEFT JOIN "GridFieldSortableHeaderTest_CheerleaderHat" ' . 'ON "GridFieldSortableHeaderTest_CheerleaderHat"."ID" = "GridFieldSortableHeaderTest_Cheerleader"."HatID"', $relationListAsql);
     // Test sorting is correct
     $this->assertEquals(array('Cologne', 'Auckland', 'Wellington', 'Melbourne'), $relationListA->column('City'));
     $state->SortDirection = 'desc';
     $relationListAdesc = $compontent->getManipulatedData($gridField, $list);
     $this->assertEquals(array('Melbourne', 'Wellington', 'Auckland', 'Cologne'), $relationListAdesc->column('City'));
     // Test subclasses of tables
     $state->SortColumn = 'CheerleadersMom.Hat.Colour';
     $state->SortDirection = 'asc';
     $relationListB = $compontent->getManipulatedData($gridField, $list);
     $relationListBsql = $relationListB->sql();
     // Assert that subclasses are included in the query
     $this->assertContains('FROM "GridFieldSortableHeaderTest_Team"', $relationListBsql);
     $this->assertContains('LEFT JOIN "GridFieldSortableHeaderTest_TeamGroup" ' . 'ON "GridFieldSortableHeaderTest_TeamGroup"."ID" = "GridFieldSortableHeaderTest_Team"."ID"', $relationListBsql);
     // Joined tables are joined basetable first
     $this->assertContains('LEFT JOIN "GridFieldSortableHeaderTest_Cheerleader" ' . 'ON "GridFieldSortableHeaderTest_Cheerleader"."ID" = "GridFieldSortableHeaderTest_Team"."CheerleadersMomID"', $relationListBsql);
     // Then the basetable of the joined record is joined to the specific subtable
     $this->assertContains('LEFT JOIN "GridFieldSortableHeaderTest_Mom" ' . 'ON "GridFieldSortableHeaderTest_Cheerleader"."ID" = "GridFieldSortableHeaderTest_Mom"."ID"', $relationListBsql);
     $this->assertContains('LEFT JOIN "GridFieldSortableHeaderTest_CheerleaderHat" ' . 'ON "GridFieldSortableHeaderTest_CheerleaderHat"."ID" = "GridFieldSortableHeaderTest_Cheerleader"."HatID"', $relationListBsql);
     // Test sorting is correct
     $this->assertEquals(array('Cologne', 'Auckland', 'Wellington', 'Melbourne'), $relationListB->column('City'));
     $state->SortDirection = 'desc';
     $relationListBdesc = $compontent->getManipulatedData($gridField, $list);
     $this->assertEquals(array('Melbourne', 'Wellington', 'Auckland', 'Cologne'), $relationListBdesc->column('City'));
 }
    /**
     * @todo Should be in a separate test suite, but don't want to duplicate setup logic
     */
    public function testYamlWriter()
    {
        $writer = new i18nTextCollector_Writer_RailsYaml();
        $entities = array('Level1.Level2.EntityName' => array('Text', 'Context'), 'Level1.OtherEntityName' => array('Other Text', 'Other Context'), 'Level1.BoolTest' => array('True'), 'Level1.FlagTest' => array('No'), 'Level1.TextTest' => array('Maybe'));
        $yaml = <<<YAML
de:
  Level1:
    Level2:
      EntityName: Text
    OtherEntityName: 'Other Text'
    BoolTest: 'True'
    FlagTest: 'No'
    TextTest: Maybe

YAML;
        $this->assertEquals($yaml, Convert::nl2os($writer->getYaml($entities, 'de')));
    }
 /**
  * Tests {@link Convert::nl2os()}
  */
 public function testNL2OS()
 {
     foreach (array("\r\n", "\r", "\n") as $nl) {
         // Base case: no action
         $this->assertEqualsQuoted("Base case", Convert::nl2os("Base case", $nl));
         // Mixed formats
         $this->assertEqualsQuoted("Test{$nl}Text{$nl}Is{$nl}{$nl}Here{$nl}.", Convert::nl2os("Test\rText\r\nIs\n\rHere\r\n.", $nl));
         // Test that multiple runs are non-destructive
         $expected = "Test{$nl}Text{$nl}Is{$nl}{$nl}Here{$nl}.";
         $this->assertEqualsQuoted($expected, Convert::nl2os($expected, $nl));
         // Check repeated sequence behaves correctly
         $expected = "{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}{$nl}";
         $input = "\r\r\n\r\r\n\n\n\n\r";
         $this->assertEqualsQuoted($expected, Convert::nl2os($input, $nl));
     }
 }