2009-02-12 10:24:33 +01:00
|
|
|
<?php
|
2015-08-30 07:02:55 +02:00
|
|
|
|
2016-10-14 03:30:05 +02:00
|
|
|
namespace SilverStripe\ORM\Tests;
|
2016-06-15 06:03:16 +02:00
|
|
|
|
|
|
|
use SilverStripe\ORM\FieldType\DBField;
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\Dev\SapphireTest;
|
2017-07-18 15:19:16 +02:00
|
|
|
use SilverStripe\ORM\FieldType\DBText;
|
2016-08-19 00:51:35 +02:00
|
|
|
|
2009-02-12 10:24:33 +01:00
|
|
|
/**
|
2016-06-17 08:49:23 +02:00
|
|
|
* Tests parsing and summary methods on DBText
|
2009-02-12 10:24:33 +01:00
|
|
|
*/
|
2016-12-16 05:34:21 +01:00
|
|
|
class DBTextTest extends SapphireTest
|
|
|
|
{
|
2009-02-12 10:38:43 +01:00
|
|
|
|
2017-07-18 15:19:16 +02:00
|
|
|
private $previousLocaleSetting = null;
|
|
|
|
|
|
|
|
public function setUp()
|
|
|
|
{
|
|
|
|
parent::setUp();
|
|
|
|
// clear the previous locale setting
|
|
|
|
$this->previousLocaleSetting = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function tearDown()
|
|
|
|
{
|
|
|
|
parent::tearDown();
|
|
|
|
// If a test sets the locale, reset it on teardown
|
|
|
|
if ($this->previousLocaleSetting) {
|
|
|
|
setlocale(LC_CTYPE, $this->previousLocaleSetting);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* Test {@link Text->LimitCharacters()}
|
|
|
|
*/
|
|
|
|
public function providerLimitCharacters()
|
|
|
|
{
|
|
|
|
// Plain text values always encoded safely
|
|
|
|
// HTML stored in non-html fields is treated literally.
|
|
|
|
return [
|
2020-08-06 09:37:03 +02:00
|
|
|
['The little brown fox jumped over the lazy cow.', 'The little brown fox…'],
|
2016-12-16 05:34:21 +01:00
|
|
|
['<p>Short & Sweet</p>', '<p>Short & Sweet</p>'],
|
2020-08-06 09:37:03 +02:00
|
|
|
['This text contains & in it', 'This text contains &…'],
|
|
|
|
['Is an umault in schön?', 'Is an umault in schö…'],
|
2016-12-16 05:34:21 +01:00
|
|
|
];
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* Test {@link Text->LimitCharacters()}
|
|
|
|
*
|
|
|
|
* @dataProvider providerLimitCharacters
|
|
|
|
* @param string $originalValue
|
|
|
|
* @param string $expectedValue
|
|
|
|
*/
|
|
|
|
public function testLimitCharacters($originalValue, $expectedValue)
|
|
|
|
{
|
|
|
|
$textObj = DBField::create_field('Text', $originalValue);
|
|
|
|
$result = $textObj->obj('LimitCharacters')->forTemplate();
|
|
|
|
$this->assertEquals($expectedValue, $result);
|
|
|
|
}
|
2014-10-17 11:41:28 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function providerLimitCharactersToClosestWord()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
// Standard words limited, ellipsis added if truncated
|
2020-08-06 09:37:03 +02:00
|
|
|
['Lorem ipsum dolor sit amet', 24, 'Lorem ipsum dolor sit…'],
|
2016-06-17 08:49:23 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
// Complete words less than the character limit don't get truncated, ellipsis not added
|
|
|
|
['Lorem ipsum', 24, 'Lorem ipsum'],
|
|
|
|
['Lorem', 24, 'Lorem'],
|
|
|
|
['', 24, ''], // No words produces nothing!
|
2016-06-17 08:49:23 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
// Special characters are encoded safely
|
|
|
|
['Nice & Easy', 24, 'Nice & Easy'],
|
2016-06-17 08:49:23 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
// HTML stored in non-html fields is treated literally.
|
|
|
|
// If storing HTML you should use DBHTMLText instead
|
2020-08-06 09:37:03 +02:00
|
|
|
['<p>Lorem ipsum dolor sit amet</p>', 24, '<p>Lorem ipsum dolor…'],
|
|
|
|
['<p><span>Lorem ipsum dolor sit amet</span></p>', 24, '<p><span>Lorem ipsum…'],
|
2016-12-16 05:34:21 +01:00
|
|
|
['<p>Lorem ipsum</p>', 24, '<p>Lorem ipsum</p>'],
|
2020-08-06 09:37:03 +02:00
|
|
|
['Lorem & ipsum dolor sit amet', 24, 'Lorem &amp; ipsum dolor…'],
|
2017-11-06 00:08:29 +01:00
|
|
|
|
2020-08-06 09:37:03 +02:00
|
|
|
['Is an umault in schön or not?', 22, 'Is an umault in schön…'],
|
2017-11-06 00:08:29 +01:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
];
|
|
|
|
}
|
2009-02-12 10:24:33 +01:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* Test {@link Text->LimitCharactersToClosestWord()}
|
|
|
|
*
|
|
|
|
* @dataProvider providerLimitCharactersToClosestWord
|
|
|
|
*
|
|
|
|
* @param string $originalValue Raw string input
|
|
|
|
* @param int $limit
|
|
|
|
* @param string $expectedValue Expected template value
|
|
|
|
*/
|
|
|
|
public function testLimitCharactersToClosestWord($originalValue, $limit, $expectedValue)
|
|
|
|
{
|
|
|
|
$textObj = DBField::create_field('Text', $originalValue);
|
|
|
|
$result = $textObj->obj('LimitCharactersToClosestWord', [$limit])->forTemplate();
|
|
|
|
$this->assertEquals($expectedValue, $result);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* Test {@link Text->LimitWordCount()}
|
|
|
|
*/
|
|
|
|
public function providerLimitWordCount()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
// Standard words limited, ellipsis added if truncated
|
2020-08-06 09:37:03 +02:00
|
|
|
['The little brown fox jumped over the lazy cow.', 3, 'The little brown…'],
|
|
|
|
[' This text has white space around the ends ', 3, 'This text has…'],
|
2016-06-17 08:49:23 +02:00
|
|
|
|
2021-05-23 13:22:22 +02:00
|
|
|
// Words less than the limit word count don't get truncated, ellipsis not added
|
2016-12-16 05:34:21 +01:00
|
|
|
['Two words', 3, 'Two words'], // Two words shouldn't have an ellipsis
|
|
|
|
['These three words', 3, 'These three words'], // Three words shouldn't have an ellipsis
|
|
|
|
['One', 3, 'One'], // Neither should one word
|
|
|
|
['', 3, ''], // No words produces nothing!
|
2016-06-17 08:49:23 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
// Text with special characters
|
|
|
|
['Nice & Easy', 3, 'Nice & Easy'],
|
2020-08-06 09:37:03 +02:00
|
|
|
['One & Two & Three', 3, 'One & Two…'],
|
2016-06-17 08:49:23 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
// HTML stored in non-html fields is treated literally.
|
|
|
|
// If storing HTML you should use DBHTMLText instead
|
2020-08-06 09:37:03 +02:00
|
|
|
['<p>Text inside a paragraph tag should also work</p>', 3, '<p>Text inside a…'],
|
2016-12-16 05:34:21 +01:00
|
|
|
['<p>Two words</p>', 3, '<p>Two words</p>'],
|
2017-11-06 00:08:29 +01:00
|
|
|
|
|
|
|
// Check UTF8
|
2020-08-06 09:37:03 +02:00
|
|
|
['Is an umault in schön or not?', 5, 'Is an umault in schön…'],
|
2016-12-16 05:34:21 +01:00
|
|
|
];
|
|
|
|
}
|
2014-05-26 02:57:12 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* Test {@link DBText->LimitWordCount()}
|
|
|
|
*
|
|
|
|
* @dataProvider providerLimitWordCount
|
|
|
|
*
|
|
|
|
* @param string $originalValue Raw string input
|
|
|
|
* @param int $limit Number of words
|
|
|
|
* @param string $expectedValue Expected template value
|
|
|
|
*/
|
|
|
|
public function testLimitWordCount($originalValue, $limit, $expectedValue)
|
|
|
|
{
|
|
|
|
$textObj = DBField::create_field('Text', $originalValue);
|
|
|
|
$result = $textObj->obj('LimitWordCount', [$limit])->forTemplate();
|
|
|
|
$this->assertEquals($expectedValue, $result);
|
|
|
|
}
|
2014-10-01 05:02:28 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
*/
|
|
|
|
public function providerLimitSentences()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
['', 2, ''],
|
|
|
|
['First sentence.', 2, 'First sentence.'],
|
|
|
|
['First sentence. Second sentence.', 2, 'First sentence. Second sentence.'],
|
2016-06-17 08:49:23 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
// HTML stored in non-html fields is treated literally.
|
|
|
|
// If storing HTML you should use DBHTMLText instead
|
|
|
|
['<p>First sentence.</p>', 2, '<p>First sentence.</p>'],
|
|
|
|
['<p>First sentence. Second sentence. Third sentence</p>', 2, '<p>First sentence. Second sentence.'],
|
2017-11-06 00:08:29 +01:00
|
|
|
|
|
|
|
// Check UTF8
|
|
|
|
['Is schön. Isn\'t schön.', 1, 'Is schön.'],
|
2016-12-16 05:34:21 +01:00
|
|
|
];
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* Test {@link DBText->LimitSentences()}
|
|
|
|
*
|
|
|
|
* @dataProvider providerLimitSentences
|
|
|
|
* @param string $originalValue
|
|
|
|
* @param int $limit Number of sentences
|
|
|
|
* @param string $expectedValue Expected template value
|
2016-06-17 08:49:23 +02:00
|
|
|
*/
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testLimitSentences($originalValue, $limit, $expectedValue)
|
|
|
|
{
|
|
|
|
$textObj = DBField::create_field('Text', $originalValue);
|
|
|
|
$result = $textObj->obj('LimitSentences', [$limit])->forTemplate();
|
|
|
|
$this->assertEquals($expectedValue, $result);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
public function providerFirstSentence()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
['', ''],
|
|
|
|
['First sentence.', 'First sentence.'],
|
|
|
|
['First sentence. Second sentence', 'First sentence.'],
|
|
|
|
['First sentence? Second sentence', 'First sentence?'],
|
|
|
|
['First sentence! Second sentence', 'First sentence!'],
|
2016-06-17 08:49:23 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
// HTML stored in non-html fields is treated literally.
|
|
|
|
// If storing HTML you should use DBHTMLText instead
|
|
|
|
['<br />First sentence.', '<br />First sentence.'],
|
|
|
|
['<p>First sentence. Second sentence. Third sentence</p>', '<p>First sentence.'],
|
2017-11-06 00:08:29 +01:00
|
|
|
|
|
|
|
// Check UTF8
|
|
|
|
['Is schön. Isn\'t schön.', 'Is schön.'],
|
2016-12-16 05:34:21 +01:00
|
|
|
];
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* @dataProvider providerFirstSentence
|
|
|
|
* @param string $originalValue
|
|
|
|
* @param string $expectedValue
|
2016-06-17 08:49:23 +02:00
|
|
|
*/
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testFirstSentence($originalValue, $expectedValue)
|
|
|
|
{
|
|
|
|
$textObj = DBField::create_field('Text', $originalValue);
|
|
|
|
$result = $textObj->obj('FirstSentence')->forTemplate();
|
|
|
|
$this->assertEquals($expectedValue, $result);
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
2021-05-23 13:22:22 +02:00
|
|
|
* each test is in the format input, character limit, highlight, expected output
|
2016-12-16 05:34:21 +01:00
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function providerContextSummary()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
[
|
|
|
|
'This is some text. It is a test',
|
|
|
|
20,
|
|
|
|
'test',
|
2020-08-06 09:37:03 +02:00
|
|
|
'… text. It is a <mark>test</mark>'
|
2016-12-16 05:34:21 +01:00
|
|
|
],
|
|
|
|
[
|
|
|
|
// Retains case of original string
|
|
|
|
'This is some test text. Test test what if you have multiple keywords.',
|
|
|
|
50,
|
|
|
|
'some test',
|
2017-09-05 01:42:08 +02:00
|
|
|
'This is <mark>some</mark> <mark>test</mark> text.'
|
2020-08-06 09:37:03 +02:00
|
|
|
. ' <mark>Test</mark> <mark>test</mark> what if you have…'
|
2016-12-16 05:34:21 +01:00
|
|
|
],
|
|
|
|
[
|
|
|
|
'Here is some text & HTML included',
|
|
|
|
20,
|
|
|
|
'html',
|
2020-08-06 09:37:03 +02:00
|
|
|
'… text & <mark>HTML</mark> inc…'
|
2016-12-16 05:34:21 +01:00
|
|
|
],
|
|
|
|
[
|
|
|
|
'A dog ate a cat while looking at a Foobar',
|
|
|
|
100,
|
|
|
|
'a',
|
|
|
|
// test that it does not highlight too much (eg every a)
|
|
|
|
'A dog ate a cat while looking at a Foobar',
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'A dog ate a cat while looking at a Foobar',
|
|
|
|
100,
|
|
|
|
'ate',
|
|
|
|
// it should highlight 3 letters or more.
|
2017-09-05 01:42:08 +02:00
|
|
|
'A dog <mark>ate</mark> a cat while looking at a Foobar',
|
2017-11-06 00:08:29 +01:00
|
|
|
],
|
|
|
|
[
|
|
|
|
'both schön and können have umlauts',
|
|
|
|
21,
|
|
|
|
'schön',
|
|
|
|
// check UTF8 support
|
2020-08-06 09:37:03 +02:00
|
|
|
'both <mark>schön</mark> and können…',
|
2018-03-01 11:39:30 +01:00
|
|
|
],
|
|
|
|
[
|
|
|
|
'both schön and können have umlauts',
|
|
|
|
21,
|
|
|
|
'',
|
2021-05-23 13:22:22 +02:00
|
|
|
// check non-existent search term
|
2020-08-06 09:37:03 +02:00
|
|
|
'both schön and können…',
|
2016-12-16 05:34:21 +01:00
|
|
|
]
|
2021-05-23 12:51:24 +02:00
|
|
|
];
|
|
|
|
}
|
2017-11-06 00:08:29 +01:00
|
|
|
|
2021-05-23 12:51:24 +02:00
|
|
|
/**
|
|
|
|
* each test is in the format input, word limit, add ellipsis (false or string), expected output
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function providerSummary()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
[
|
|
|
|
'This is some text. It is a test',
|
|
|
|
3,
|
|
|
|
false,
|
|
|
|
'This is some…',
|
|
|
|
],
|
|
|
|
[
|
|
|
|
// check custom ellipsis
|
|
|
|
'This is a test text in a longer sentence and a custom ellipsis.',
|
|
|
|
8,
|
|
|
|
'...', // regular dots instead of the ellipsis character
|
|
|
|
'This is a test text in a longer...',
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'both schön and können have umlauts',
|
|
|
|
5,
|
|
|
|
false,
|
|
|
|
'both schön and können have…',
|
|
|
|
],
|
|
|
|
[
|
|
|
|
// check invalid UTF8 handling — input is an invalid UTF sequence, output should be empty string
|
|
|
|
"\xf0\x28\x8c\xbc",
|
|
|
|
50,
|
|
|
|
false,
|
|
|
|
'',
|
|
|
|
],
|
2016-12-16 05:34:21 +01:00
|
|
|
];
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
/**
|
|
|
|
* @dataProvider providerContextSummary
|
|
|
|
* @param string $originalValue Input
|
2021-05-23 13:22:22 +02:00
|
|
|
* @param int $limit Number of characters
|
2016-12-16 05:34:21 +01:00
|
|
|
* @param string $keywords Keywords to highlight
|
|
|
|
* @param string $expectedValue Expected output (XML encoded safely)
|
2016-06-17 08:49:23 +02:00
|
|
|
*/
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testContextSummary($originalValue, $limit, $keywords, $expectedValue)
|
|
|
|
{
|
|
|
|
$text = DBField::create_field('Text', $originalValue);
|
|
|
|
$result = $text->obj('ContextSummary', [$limit, $keywords])->forTemplate();
|
|
|
|
// it should highlight 3 letters or more.
|
|
|
|
$this->assertEquals($expectedValue, $result);
|
|
|
|
}
|
2012-01-31 01:07:24 +01:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testRAW()
|
|
|
|
{
|
|
|
|
$data = DBField::create_field('Text', 'This & This');
|
|
|
|
$this->assertEquals($data->RAW(), 'This & This');
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testXML()
|
|
|
|
{
|
|
|
|
$data = DBField::create_field('Text', 'This & This');
|
|
|
|
$this->assertEquals($data->XML(), 'This & This');
|
|
|
|
}
|
2012-01-31 01:07:24 +01:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testHTML()
|
|
|
|
{
|
|
|
|
$data = DBField::create_field('Text', 'This & This');
|
|
|
|
$this->assertEquals($data->HTML(), 'This & This');
|
|
|
|
}
|
2012-01-31 01:07:24 +01:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testJS()
|
|
|
|
{
|
|
|
|
$data = DBField::create_field('Text', '"this is a test"');
|
|
|
|
$this->assertEquals($data->JS(), '\"this is a test\"');
|
|
|
|
}
|
2012-01-31 01:07:24 +01:00
|
|
|
|
2016-12-16 05:34:21 +01:00
|
|
|
public function testATT()
|
|
|
|
{
|
|
|
|
$data = DBField::create_field('Text', '"this is a test"');
|
|
|
|
$this->assertEquals($data->ATT(), '"this is a test"');
|
|
|
|
}
|
2017-07-18 15:19:16 +02:00
|
|
|
|
|
|
|
public function testValidUtf8()
|
|
|
|
{
|
|
|
|
// Install a UTF-8 locale
|
|
|
|
$this->previousLocaleSetting = setlocale(LC_CTYPE, 0);
|
2020-04-20 19:58:09 +02:00
|
|
|
$locales = ['en_US.UTF-8', 'en_NZ.UTF-8', 'de_DE.UTF-8'];
|
2017-07-18 15:19:16 +02:00
|
|
|
$localeInstalled = false;
|
|
|
|
foreach ($locales as $locale) {
|
|
|
|
if ($localeInstalled = setlocale(LC_CTYPE, $locale)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the system doesn't have any of the UTF-8 locales, exit early
|
|
|
|
if ($localeInstalled === false) {
|
|
|
|
$this->markTestIncomplete('Unable to run this test because of missing locale!');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$problematicText = html_entity_decode('This is a Test with non-breaking space!', ENT_COMPAT, 'UTF-8');
|
|
|
|
|
|
|
|
$textObj = new DBText('Test');
|
|
|
|
$textObj->setValue($problematicText);
|
|
|
|
|
|
|
|
$this->assertTrue(mb_check_encoding($textObj->FirstSentence(), 'UTF-8'));
|
|
|
|
}
|
2020-08-06 09:37:03 +02:00
|
|
|
|
|
|
|
public function testDefaultEllipsis()
|
|
|
|
{
|
|
|
|
$textObj = new DBText('Test');
|
2020-08-06 23:48:42 +02:00
|
|
|
$this->assertEquals('…', $textObj->defaultEllipsis());
|
2020-08-06 09:37:03 +02:00
|
|
|
}
|
2021-05-23 12:51:24 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider providerSummary
|
|
|
|
* @param string $originalValue Input
|
|
|
|
* @param int $words Number of words
|
|
|
|
* @param mixed $add Ellipsis (false for default or string for custom text)
|
|
|
|
* @param string $expectedValue Expected output (XML encoded safely)
|
|
|
|
*/
|
|
|
|
public function testSummary($originalValue, $words, $add, $expectedValue)
|
|
|
|
{
|
|
|
|
$text = DBField::create_field(DBText::class, $originalValue);
|
|
|
|
$result = $text->obj('Summary', [$words, $add])->forTemplate();
|
|
|
|
$this->assertEquals($expectedValue, $result);
|
|
|
|
}
|
2012-03-24 04:04:52 +01:00
|
|
|
}
|