diff --git a/.coveralls.yml b/.coveralls.yml
deleted file mode 100644
index 9160059..0000000
--- a/.coveralls.yml
+++ /dev/null
@@ -1 +0,0 @@
-service_name: travis-ci
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..c492e7a
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,29 @@
+name: Test
+on: [push, pull_request]
+jobs:
+ test:
+ name: Test PHP ${{ matrix.php-version }}
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ php-version: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1']
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+ - name: PHP Version
+ run: php --version
+ - name: Composer Version
+ run: composer --version
+ - name: Install Dependencies
+ run: COMPOSER_MEMORY_LIMIT=-1 composer install
+ - name: Run Tests
+ run: vendor/bin/phpunit --coverage-clover ./coverage.xml
+ - name: Upload Coverage
+ if: ${{ matrix.php-version == '8.1' }}
+ uses: codecov/codecov-action@v1
+ with:
+ file: ./coverage.xml
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a2144a3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+composer.lock
+composer.phar
+.phpunit.result.cache
+/vendor/
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 24b1527..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-language: php
-dist: trusty
-sudo: required
-
-matrix:
- include:
- - php: 5.3
- dist: precise
- - php: 5.4
- - php: 5.5
- - php: 5.6
- - php: 7.0
- - php: 7.1
- - php: 7.2
- - php: hhvm
- env: HHVM=true
-
-install:
- - composer install
- - if [[ $HHVM == true ]]; then composer require "phpunit/phpunit:5.7"; fi
-
-before_script:
- - mkdir -p build/logs
- - cd tests
-
-script:
- - if [[ $HHVM == true ]]; then ../vendor/bin/phpunit --colors --coverage-clover ../build/logs/clover.xml .; fi
- - if [[ $HHVM != true ]]; then phpunit --colors --coverage-clover ../build/logs/clover.xml .; fi
-
-
-after_success:
- - cd ..
- - php vendor/bin/coveralls --config .coveralls.yml -v
diff --git a/FUNDING.yml b/FUNDING.yml
new file mode 100644
index 0000000..9396c28
--- /dev/null
+++ b/FUNDING.yml
@@ -0,0 +1 @@
+github: joshtronic
diff --git a/LICENSE b/LICENSE
index 46c6d1c..cc7838a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2014, 2015, 2016, 2017, 2018 Josh Sherman
+Copyright (c) 2014-2022 Josh Sherman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 848057d..2b29143 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,17 @@
# php-loremipsum
-[](https://travis-ci.org/joshtronic/php-loremipsum)
-[](https://coveralls.io/github/joshtronic/php-loremipsum?branch=master)
-[](https://packagist.org/packages/joshtronic/php-loremipsum)
+[](https://github.com/joshtronic/php-loremipsum/blob/master/LICENSE)
+
+[](https://github.com/joshtronic/php-loremipsum/actions)
+[](https://codecov.io/gh/joshtronic/php-loremipsum)
+[](https://packagist.org/packages/joshtronic/php-loremipsum)
-Lorem ipsum generator in PHP without dependencies. Compatible with PHP 5.3+ as
-well as HHVM.
-
-## Origins
-
-Once upon a time, I was attempting to find a lorem ipsum generator over on
-[Packagist](https://packagist.org/search/?q=lorem%20ipsum). I was presented
-with many options, and some of those options were good. Unfortunately, the
-bulk of those options depended on Symphony or the Zend Framework. This
-wouldn’t have been a big deal but under the circumstances, I wanted something
-that was not tightly coupled to these frameworks because I wanted to use the
-generator in my _own_ framework.
-
-I had decided to use
-[badcow/lorem-ipsum](https://packagist.org/packages/badcow/lorem-ipsum)
-because it did not have any dependencies nor did it rely on any external APIs.
-As I started to use the library, I found that I was going to have to fight
-with it to get it to do what I wanted. After digging through the code, I
-realized that I was going to end up gutting most of it to bend it to my will.
-I know when you overhaul someone’s code the liklihood of them accepting a pull
-request goes down dramatically, hence building this library while taking cues
-from it’s predecessor.
-
-Also, the aforementioned package had a bunch of “setter” and “getter” methods
-that were grossing me out :scream:
+Lorem ipsum generator in PHP without dependencies. Compatible with PHP 5.3+.
## Installation
-The preferred installation method is via `composer`. First add the following
-to your `composer.json`
+The preferred installation method is via `composer`. First add the following to
+your `composer.json`:
```json
"require": {
@@ -41,7 +19,7 @@ to your `composer.json`
}
```
-Then run `composer update`
+Then run `composer update`.
## Usage
@@ -58,21 +36,21 @@ echo '1 word: ' . $lipsum->word();
echo '5 words: ' . $lipsum->words(5);
```
-### Generating sentences
+### Generating Sentences
```php
-echo '1 sentence: ' . $lipsum->sentence();
+echo '1 sentence: ' . $lipsum->sentence();
echo '5 sentences: ' . $lipsum->sentences(5);
```
-### Generating paragraphs
+### Generating Paragraphs
```php
-echo '1 paragraph: ' . $lipsum->paragraph();
+echo '1 paragraph: ' . $lipsum->paragraph();
echo '5 paragraphs: ' . $lipsum->paragraphs(5);
```
-### Wrapping text with HTML tags
+### Wrapping Text with HTML Tags
If you would like to wrap the generated text with a tag, pass it as the second
parameter:
@@ -99,7 +77,7 @@ echo $lipsum->words(3, '
$1');
// Generates: .........
```
-### Return as an array
+### Return as an Array
Perhaps you want an array instead of a string:
@@ -117,16 +95,25 @@ print_r($lipsum->wordsArray(5, 'li'));
## Assumptions
-Instead of having an option as to whether or not a string should start the
-generated output with “Lorem ipsum dolor sit amet, consectetur adipiscing
-elit.” a few assumptions are baked in. The first string generated will always
-start with the traditional “Lorem ipsum…”. Subsequent strings may contain
+The first string generated will always start with the traditional "Lorem ipsum
+dolor sit amet, consectetur adipiscing elit". Subsequent strings may contain
those words but will not explicitly start with them.
## Contributing
-Suggestions and bug reports are always welcome, but karma points are earned
-for pull requests.
+Suggestions and bug reports are always welcome, but karma points are earned for
+pull requests.
-Unit tests are required for all contributions. You can run the test suite
-from the `tests` directory simply by running `phpunit .`
+Unit tests are required for all contributions. You can run the test suite from
+the project's root directory simply by running `phpunit`.
+
+## Credits
+
+`php-loremipsum` was originally inspired by
+[badcow/lorem-ipsum](https://packagist.org/packages/badcow/lorem-ipsum) with a
+goal of being a dependency free lorem ipsum generator with flexible generation
+options.
+
+## License
+
+MIT
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..657d8f7
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,20 @@
+codecov:
+ require_ci_to_pass: yes
+
+coverage:
+ precision: 2
+ round: down
+ range: "70...100"
+
+parsers:
+ gcov:
+ branch_detection:
+ conditional: yes
+ loop: yes
+ method: no
+ macro: no
+
+comment:
+ layout: "reach,diff,flags,tree"
+ behavior: default
+ require_changes: no
diff --git a/composer.json b/composer.json
index 9c35393..a28a4b3 100644
--- a/composer.json
+++ b/composer.json
@@ -1,31 +1,34 @@
{
"name": "joshtronic/php-loremipsum",
"description": "Lorem ipsum generator in PHP without dependencies",
- "version": "1.0.3",
+ "version": "2.1.0",
"type": "library",
"keywords": [
- "lorem",
- "ipsum",
- "generator"
+ "lorem",
+ "ipsum",
+ "generator"
],
"homepage": "https://github.com/joshtronic/php-loremipsum",
"license": "MIT",
- "authors": [
- {
- "name": "Josh Sherman",
- "email": "hello@joshtronic.com",
- "homepage": "https://joshtronic.com"
- }
- ],
+ "authors": [{
+ "name": "Josh Sherman",
+ "email": "hello@joshtronic.com",
+ "homepage": "https://joshtronic.com"
+ }],
"require": {
- "php": ">=5.3.0"
+ "php": ">=5.3"
},
"require-dev": {
- "satooshi/php-coveralls": "~1.0"
+ "phpunit/phpunit": "^4.8.36 || ^9.0"
},
"autoload": {
- "psr-4": {
- "joshtronic\\": "src/"
- }
+ "psr-4": {
+ "joshtronic\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "joshtronic\\Tests\\": "tests/"
+ }
}
-}
+ }
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..0292a3b
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,14 @@
+parameters:
+
+ paths:
+ - src
+
+ # The level 8 is the highest level
+ level: max
+
+ excludePaths:
+ - ./*/*/FileToBeExcluded.php
+
+ checkMissingIterableValueType: true
+
+ #editorUrl: 'vscode://file/%%file%%:%%line%%'
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000..8fe6c98
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ tests
+
+
+
+
+ ./src
+
+
+
diff --git a/src/LoremIpsum.php b/src/LoremIpsum.php
index 393c9b6..863b8d5 100644
--- a/src/LoremIpsum.php
+++ b/src/LoremIpsum.php
@@ -9,7 +9,7 @@
* Redistribution of these files must retain the above copyright notice.
*
* @author Josh Sherman
- * @copyright Copyright 2014, 2015, 2016, 2017, 2018 Josh Sherman
+ * @copyright Copyright 2014-2022 Josh Sherman
* @license http://www.opensource.org/licenses/mit-license.html
* @link https://github.com/joshtronic/php-loremipsum
*/
@@ -24,7 +24,7 @@ class LoremIpsum
* Whether or not we should be starting the string with "Lorem ipsum..."
*
* @access private
- * @var boolean
+ * @var mixed
*/
private $first = true;
@@ -35,9 +35,9 @@ class LoremIpsum
* a complete list exists and if so, where to get it.
*
* @access private
- * @var array
+ * @var array
*/
- public $words = array(
+ private $words = array(
// Lorem ipsum...
'lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit',
@@ -83,7 +83,7 @@ class LoremIpsum
*/
public function word($tags = false)
{
- return $this->words(1, $tags);
+ return strval($this->words(1, $tags));
}
/**
@@ -94,7 +94,7 @@ class LoremIpsum
* @access public
* @param integer $count how many words to generate
* @param mixed $tags string or array of HTML tags to wrap output with
- * @return array generated lorem ipsum words
+ * @return mixed generated lorem ipsum words
*/
public function wordsArray($count = 1, $tags = false)
{
@@ -114,6 +114,7 @@ class LoremIpsum
*/
public function words($count = 1, $tags = false, $array = false)
{
+ $count = (int) $count;
$words = array();
$word_count = 0;
@@ -151,7 +152,7 @@ class LoremIpsum
*/
public function sentence($tags = false)
{
- return $this->sentences(1, $tags);
+ return strval($this->sentences(1, $tags));
}
/**
@@ -162,7 +163,7 @@ class LoremIpsum
* @access public
* @param integer $count how many sentences to generate
* @param mixed $tags string or array of HTML tags to wrap output with
- * @return array generated lorem ipsum sentences
+ * @return mixed generated lorem ipsum sentences
*/
public function sentencesArray($count = 1, $tags = false)
{
@@ -204,7 +205,7 @@ class LoremIpsum
*/
public function paragraph($tags = false)
{
- return $this->paragraphs(1, $tags);
+ return strval($this->paragraphs(1, $tags));
}
/**
@@ -215,15 +216,18 @@ class LoremIpsum
* @access public
* @param integer $count how many paragraphs to generate
* @param mixed $tags string or array of HTML tags to wrap output with
- * @return array generated lorem ipsum paragraphs
+ * @return array generated lorem ipsum paragraphs
*/
public function paragraphsArray($count = 1, $tags = false)
{
+ // The $array parameter set to true means an array is returned.
+ // Return type is mixed, we should probably cast to array.
+ // @phpstan-ignore-next-line
return $this->paragraphs($count, $tags, true);
}
/**
- * Paragraphss
+ * Paragraphs
*
* Generates paragraphs of lorem ipsum.
*
@@ -238,10 +242,13 @@ class LoremIpsum
$paragraphs = array();
for ($i = 0; $i < $count; $i++) {
- $paragraphs[] = $this->sentences($this->gauss(5.8, 1.93));
+ $paragraphs[] = strval($this->sentences($this->gauss(5.8, 1.93)));
}
- return $this->output($paragraphs, $tags, $array, "\n\n");
+ if ($array) {
+ return $this->output($paragraphs, $tags, $array, "\n\n");
+ }
+ return strval($this->output($paragraphs, $tags, false, "\n\n"));
}
/**
@@ -255,7 +262,7 @@ class LoremIpsum
* @access private
* @param double $mean average value
* @param double $std_dev stadnard deviation
- * @return double calculated distribution
+ * @return int calculated distribution
*/
private function gauss($mean, $std_dev)
{
@@ -263,7 +270,7 @@ class LoremIpsum
$y = mt_rand() / mt_getrandmax();
$z = sqrt(-2 * log($x)) * cos(2 * pi() * $y);
- return $z * $std_dev + $mean;
+ return intval($z * $std_dev + $mean);
}
/**
@@ -273,6 +280,7 @@ class LoremIpsum
* the first time we are generating the text.
*
* @access private
+ * @return void
*/
private function shuffle()
{
@@ -298,18 +306,18 @@ class LoremIpsum
* first word of the sentence.
*
* @access private
- * @param array $sentences the sentences we would like to punctuate
+ * @param array $sentences the sentences we would like to punctuate
+ * @return void
*/
private function punctuate(&$sentences)
{
foreach ($sentences as $key => $sentence) {
$words = count($sentence);
-
// Only worry about commas on sentences longer than 4 words
if ($words > 4) {
$mean = log($words, 6);
$std_dev = $mean / 6;
- $commas = round($this->gauss($mean, $std_dev));
+ $commas = $this->gauss($mean, $std_dev);
for ($i = 1; $i <= $commas; $i++) {
$word = round($i * $words / ($commas + 1));
@@ -333,7 +341,7 @@ class LoremIpsum
* into a string or not.
*
* @access private
- * @param array $strings an array of generated strings
+ * @param array $strings an array of generated strings
* @param mixed $tags string or array of HTML tags to wrap output with
* @param boolean $array whether an array or a string should be returned
* @param string $delimiter the string to use when calling implode()
@@ -351,11 +359,13 @@ class LoremIpsum
foreach ($strings as $key => $string) {
foreach ($tags as $tag) {
- // Detects / applies back reference
- if ($tag[0] == '<') {
- $string = str_replace('$1', $string, $tag);
- } else {
- $string = sprintf('<%1$s>%2$s%1$s>', $tag, $string);
+ if (is_string($tag)) {
+ // Detects / applies back reference
+ if ($tag[0] == '<') {
+ $string = str_replace('$1', $string, $tag);
+ } else {
+ $string = sprintf('<%1$s>%2$s%1$s>', $tag, $string);
+ }
}
$strings[$key] = $string;
@@ -370,4 +380,3 @@ class LoremIpsum
return $strings;
}
}
-
diff --git a/tests/LoremIpsumTest.php b/tests/LoremIpsumTest.php
index e568b4d..77c5906 100644
--- a/tests/LoremIpsumTest.php
+++ b/tests/LoremIpsumTest.php
@@ -1,130 +1,198 @@
=')) {
+ return 'assertMatchesRegularExpression';
+ }
- public function setUp()
- {
- $this->lipsum = new joshtronic\LoremIpsum();
+ return 'assertRegExp';
}
- public function testWord()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testWord($assertRegExp)
{
- $this->assertRegExp('/^[a-z]+$/i', $this->lipsum->word());
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp('/^[a-z]+$/i', $lipsum->word());
}
- public function testWords()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testWords($assertRegExp)
{
- $this->assertRegExp(
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp(
'/^[a-z]+ [a-z]+ [a-z]+$/i',
- $this->lipsum->words(3)
+ $lipsum->words(3)
);
}
- public function testWordsArray()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testWordsArray($assertRegExp)
{
- $words = $this->lipsum->wordsArray(3);
+ $lipsum = new LoremIpsum();
+ $words = $lipsum->wordsArray(3);
$this->assertTrue(is_array($words));
$this->assertCount(3, $words);
foreach ($words as $word) {
- $this->assertRegExp('/^[a-z]+$/i', $word);
+ $this->$assertRegExp('/^[a-z]+$/i', $word);
}
}
- public function testWordsExceedingVocab()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testWordsExceedingVocab($assertRegExp)
{
- $this->assertCount(500, $this->lipsum->wordsArray(500));
+ $lipsum = new LoremIpsum();
+ $this->assertCount(500, $lipsum->wordsArray(500));
}
- public function testSentence()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testSentence($assertRegExp)
{
- $this->assertRegExp('/^[a-z, ]+\.$/i', $this->lipsum->sentence());
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp('/^[a-z, ]+\.$/i', $lipsum->sentence());
}
- public function testSentences()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testSentences($assertRegExp)
{
- $this->assertRegExp('/^[a-z, ]+\. [a-z, ]+\. [a-z, ]+\.$/i', $this->lipsum->sentences(3));
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp(
+ '/^[a-z, ]+\. [a-z, ]+\. [a-z, ]+\.$/i',
+ $lipsum->sentences(3)
+ );
}
- public function testSentencesArray()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testSentencesArray($assertRegExp)
{
- $sentences = $this->lipsum->sentencesArray(3);
+ $lipsum = new LoremIpsum();
+ $sentences = $lipsum->sentencesArray(3);
$this->assertTrue(is_array($sentences));
$this->assertCount(3, $sentences);
foreach ($sentences as $sentence) {
- $this->assertRegExp('/^[a-z, ]+\.$/i', $sentence);
+ $this->$assertRegExp('/^[a-z, ]+\.$/i', $sentence);
}
}
- public function testParagraph()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testParagraph($assertRegExp)
{
- $this->assertRegExp('/^([a-z, ]+\.)+$/i', $this->lipsum->paragraph());
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp('/^([a-z, ]+\.)+$/i', $lipsum->paragraph());
}
- public function testParagraphs()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testParagraphs($assertRegExp)
{
- $this->assertRegExp(
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp(
'/^([a-z, ]+\.)+\n\n([a-z, ]+\.)+\n\n([a-z, ]+\.)+$/i',
- $this->lipsum->paragraphs(3)
+ $lipsum->paragraphs(3)
);
}
- public function testParagraphsArray()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testParagraphsArray($assertRegExp)
{
- $paragraphs = $this->lipsum->paragraphsArray(3);
+ $lipsum = new LoremIpsum();
+ $paragraphs = $lipsum->paragraphsArray(3);
$this->assertTrue(is_array($paragraphs));
$this->assertCount(3, $paragraphs);
foreach ($paragraphs as $paragraph) {
- $this->assertRegExp('/^([a-z, ]+\.)+$/i', $paragraph);
+ $this->$assertRegExp('/^([a-z, ]+\.)+$/i', $paragraph);
}
}
- public function testMarkupString()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testMarkupString($assertRegExp)
{
- $this->assertRegExp(
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp(
'/^[a-z]+<\/li>$/i',
- $this->lipsum->word('li')
+ $lipsum->word('li')
);
}
- public function testMarkupArray()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testMarkupArray($assertRegExp)
{
- $this->assertRegExp(
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp(
'/^[a-z]+<\/p><\/div>$/i',
- $this->lipsum->word(array('div', 'p'))
+ $lipsum->word(array('div', 'p'))
);
}
- public function testMarkupBackReference()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testMarkupBackReference($assertRegExp)
{
- $this->assertRegExp(
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp(
'/^
[a-z]+<\/a><\/li>$/i',
- $this->lipsum->word('$1')
+ $lipsum->word('$1')
);
}
- public function testMarkupArrayReturn()
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testMarkupArrayReturn($assertRegExp)
{
- $words = $this->lipsum->wordsArray(3, 'li');
+ $lipsum = new LoremIpsum();
+ $words = $lipsum->wordsArray(3, 'li');
$this->assertTrue(is_array($words));
$this->assertCount(3, $words);
foreach ($words as $word) {
- $this->assertRegExp('/^[a-z]+<\/li>$/i', $word);
+ $this->$assertRegExp('/^[a-z]+<\/li>$/i', $word);
}
}
+
+ /**
+ * @depends testAssertRegExp
+ */
+ public function testSkipNonStringTag($assertRegExp)
+ {
+ $lipsum = new LoremIpsum();
+ $this->$assertRegExp('/^[a-z]+$/i', $lipsum->word(123));
+ $this->$assertRegExp('/^[a-z]+$/i', $lipsum->word(array(1, 2, 3)));
+ $this->$assertRegExp('/^[a-z]+$/i', $lipsum->word(true));
+ }
}