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 -[![Build Status](https://travis-ci.org/joshtronic/php-loremipsum.svg?branch=master)](https://travis-ci.org/joshtronic/php-loremipsum) -[![Coverage Status](https://coveralls.io/repos/github/joshtronic/php-loremipsum/badge.svg?branch=master)](https://coveralls.io/github/joshtronic/php-loremipsum?branch=master) -[![Total Downloads](https://poser.pugx.org/joshtronic/php-loremipsum/downloads)](https://packagist.org/packages/joshtronic/php-loremipsum) +[![License](https://img.shields.io/packagist/l/joshtronic/php-loremipsum?style=for-the-badge)](https://github.com/joshtronic/php-loremipsum/blob/master/LICENSE) +![PHP Version](https://img.shields.io/packagist/php-v/joshtronic/php-loremipsum?style=for-the-badge) +[![Test Status](https://img.shields.io/github/workflow/status/joshtronic/php-loremipsum/Test?style=for-the-badge)](https://github.com/joshtronic/php-loremipsum/actions) +[![Code Coverage](https://img.shields.io/codecov/c/github/joshtronic/php-loremipsum?style=for-the-badge)](https://codecov.io/gh/joshtronic/php-loremipsum) +[![Monthly Downloads](https://img.shields.io/packagist/dm/joshtronic/php-loremipsum?style=for-the-badge)](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', $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', $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)); + } }