git.iko.soy/typeable/inflections-hs
on 8d7c0be help sign in
18 files changed+92−324
since splitsnapshots
unifiedsplit
.travis.yml+8−7 CHANGELOG.md−23 LICENSE+18−17 README.md+8−11 Text/Inflections.hs+12−34 Text/Inflections/Humanize.hs+3−24 Text/Inflections/Ordinal.hs+1 Text/Inflections/Parse/CamelCase.hs+5−12 Text/Inflections/Parse/SnakeCase.hs+4−11 Text/Inflections/Titleize.hs+2−2 Text/Inflections/Types.hs+1−2 docs/CODE_OF_CONDUCT.md−35 docs/CONTRIBUTING.md−13 inflections.cabal+10−20 stack.yaml+6−1 stack.yaml.lock−12 test/Text/Inflections/HumanizeSpec.hs+13−40 test/Text/InflectionsSpec.hs+1−60
.travis.yml+8−7
@@ -9,14 +9,14 @@ cache:
99
1010matrix:
1111 include:
12+ - env: CABALVER=1.24 GHCVER=7.6.3
13+ addons: {apt: {packages: [cabal-install-1.24,ghc-7.6.3], sources: [hvr-ghc]}}
14+ - env: CABALVER=1.24 GHCVER=7.8.4
15+ addons: {apt: {packages: [cabal-install-1.24,ghc-7.8.4,],sources: [hvr-ghc]}}
1216 - env: CABALVER=1.24 GHCVER=7.10.3
1317 addons: {apt: {packages: [cabal-install-1.24,ghc-7.10.3],sources: [hvr-ghc]}}
1418 - env: CABALVER=1.24 GHCVER=8.0.2
1519 addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2],sources: [hvr-ghc]}}
16− - env: CABALVER=2.2 GHCVER=8.2.2
17− addons: {apt: {packages: [cabal-install-2.2,ghc-8.2.2], sources: [hvr-ghc]}}
18− - env: CABALVER=2.2 GHCVER=8.4.3
19− addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.3], sources: [hvr-ghc]}}
2020
2121before_install:
2222 - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
@@ -33,11 +33,12 @@ script:
3333 *) cabal configure --enable-tests -v2 -f dev ;;
3434 esac
3535 - cabal build
36− - cabal sdist
3736 - case "$GHCVER" in
38− "8.4.3") cabal haddock | grep "100%" | wc -l | grep "1" ;;
39− *) cabal haddock | grep "100%" | wc -l | grep "13" ;;
37+ "7.6.3") true ;;
38+ *) cabal test --show-details=always ;;
4039 esac
40+ - cabal sdist
41+ - cabal haddock | grep "100%" | wc -l | grep "13"
4142
4243notifications:
4344 email: false
CHANGELOG.md−23
@@ -1,26 +1,3 @@
1−## Inflections 0.4.0.6
2−* Support `megaparsec` == 9.0
3−
4−## Inflections 0.4.0.5
5−* Support `megaparsec` == 8.0
6−
7−## Inflections 0.4.0.3
8−* Support `megaparsec` == 7.0*.
9−* **Drop support** for `GHC 7.8.4`.
10−
11−## Inflections 0.4.0.3
12−* Support `exceptions` == 0.10.*
13−
14−## Inflections 0.4.0.2
15−* Support `exceptions` == 0.9.*
16−
17−## Inflections 0.4.0.1
18−* Support `megaparsec` >= 6.4.0
19−
20−## Inflections 0.4.0.0
21−
22−* Update megaparsec to version 6.
23−
241## Inflections 0.3.0.0
252
263* A more type-safe API forbidding creation of invalid words.
LICENSE+18−17
@@ -1,21 +1,22 @@
1−MIT License
1+Copyright (c) 2014-2016 Justin Leitgeb
22
3−Copyright (c) 2022 Stack Builders Inc.
3+MIT License
44
5−Permission is hereby granted, free of charge, to any person obtaining a copy
6−of this software and associated documentation files (the "Software"), to deal
7−in the Software without restriction, including without limitation the rights
8−to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9−copies of the Software, and to permit persons to whom the Software is
10−furnished to do so, subject to the following conditions:
5+Permission is hereby granted, free of charge, to any person obtaining
6+a copy of this software and associated documentation files (the
7+"Software"), to deal in the Software without restriction, including
8+without limitation the rights to use, copy, modify, merge, publish,
9+distribute, sublicense, and/or sell copies of the Software, and to
10+permit persons to whom the Software is furnished to do so, subject to
11+the following conditions:
1112
12−The above copyright notice and this permission notice shall be included in all
13−copies or substantial portions of the Software.
13+The above copyright notice and this permission notice shall be
14+included in all copies or substantial portions of the Software.
1415
15−THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16−IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17−FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18−AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19−LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20−OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21−SOFTWARE.
16+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
README.md+8−11
@@ -49,10 +49,11 @@ If you want to specify a custom default replacement or approximation table for
4949the `transliterate` function, you should instead call the `transliterateCustom`
5050function which accepts a String for replacements and a Map for substitution.
5151
52−## Future work
52+## TODO
5353
54−Ideally, we want to implement other functions found in the Rails
55−inflections library. If you need one of those functions, please submit a pull request!
54+I'd like this library to implement other functions found in the Rails
55+inflections library. If you need one of those functions, please submit a pull
56+request!
5657
5758## Further documentation
5859
@@ -63,14 +64,10 @@ For more information, please see the the
6364
6465Justin Leitgeb <justin@stackbuilders.com>
6566
66−## License
67−
68−MIT, see [the LICENSE file](LICENSE).
69−
7067## Contributing
7168
72−Do you want to contribute to this project? Please take a look at our [contributing guideline](/docs/CONTRIBUTING.md) to know how you can help us build it.
69+You may submit pull requests to this repository on GitHub. Tests are appreciated with your contribution.
70+
71+## License
7372
74−---
75−<img src="https://cdn.stackbuilders.com/media/images/Sb-supports.original.png" alt="Stack Builders" width="50%"></img>
76−[Check out our libraries](https://github.com/stackbuilders/) | [Join our team](https://www.stackbuilders.com/join-us/)
73+MIT - see [the LICENSE file](LICENSE).
Text/Inflections.hs+12−34
@@ -96,7 +96,6 @@ module Text.Inflections
9696 , camelizeCustom
9797 , dasherize
9898 , humanize
99− , humanizeCustom
10099 , underscore
101100 , titleize
102101 , Transliterations
@@ -111,17 +110,15 @@ module Text.Inflections
111110 , toUnderscore
112111 , toDashed
113112 , toCamelCased
114− , toHumanized
115113 , betterThrow )
116114where
117115
118116import Control.Monad.Catch (MonadThrow (..))
119117import Data.Text (Text)
120−import Data.Void (Void)
121118import Text.Inflections.Camelize (camelize, camelizeCustom)
122119import Text.Inflections.Dasherize (dasherize)
123120import Text.Inflections.Data (Transliterations, defaultTransliterations)
124−import Text.Inflections.Humanize (humanize, humanizeCustom)
121+import Text.Inflections.Humanize (humanize)
125122import Text.Inflections.Ordinal (ordinal, ordinalize)
126123import Text.Inflections.Parameterize (parameterize, parameterizeCustom)
127124import Text.Inflections.Parse.CamelCase (parseCamelCase)
@@ -142,7 +139,7 @@ import Prelude hiding (Word)
142139--
143140-- >>> toUnderscore "FooBarBazz"
144141-- "foo_bar_bazz"
145−toUnderscore :: Text -> Either (ParseErrorBundle Text Void) Text
142+toUnderscore :: Text -> Either (ParseError Char Dec) Text
146143toUnderscore = fmap underscore . parseCamelCase []
147144
148145-- | Transforms CamelCasedString to snake-cased-string-with-dashes.
@@ -151,45 +148,26 @@ toUnderscore = fmap underscore . parseCamelCase []
151148--
152149-- >>> toDashed "FooBarBazz"
153150-- "foo-bar-bazz"
154−toDashed :: Text -> Either (ParseErrorBundle Text Void) Text
151+toDashed :: Text -> Either (ParseError Char Dec) Text
155152toDashed = fmap dasherize . parseCamelCase []
156153
157154-- | Transforms underscored_text to CamelCasedText. If first argument is
158−-- 'True' then the first character in the result string will be in upper case. If
159−-- 'False' then the first character will be in lower case.
155+-- 'True' then FirstCharacter in result string will be in upper case. If
156+-- 'False' then firstCharacter will be in lower case.
160157--
161−-- > toCamelCased c = fmap (camelizeCustom c) . parseSnakeCase []
158+-- > toCamelCased t = fmap (camelizeCustom t) . parseSnakeCase []
162159--
163160-- >>> toCamelCased True "foo_bar_bazz"
164161-- "FooBarBazz"
165162-- >>> toCamelCased False "foo_bar_bazz"
166163-- "fooBarBazz"
167164toCamelCased
168− :: Bool -- ^ Capitalize the first character
169− -> Text -- ^ Input
170− -> Either (ParseErrorBundle Text Void) Text -- ^ Output
171−toCamelCased c = fmap (camelizeCustom c) . parseSnakeCase []
165+ :: Bool -- ^ Capitalize the first character
166+ -> Text -- ^ Input
167+ -> Either (ParseError Char Dec) Text -- ^ Ouput
168+toCamelCased t = fmap (camelizeCustom t) . parseSnakeCase []
172169
173−-- | Transforms underscored_text to space-separated human-readable text.
174−-- If first argument is 'True' then the first character in the result
175−-- string will be in upper case. If 'False' then the first character will be
176−-- in lower case.
177−--
178−-- > toHumanized c = fmap (humanizeCustom c) . parseSnakeCase []
179−--
180−-- >>> toHumanized True "foo_bar_bazz"
181−-- "Foo bar bazz"
182−-- >>> toHumanized False "foo_bar_bazz"
183−-- "foo bar bazz"
184−--
185−-- /since 0.3.0.0/
186−toHumanized
187− :: Bool -- ^ Capitalize the first character
188− -> Text -- ^ Input
189− -> Either (ParseErrorBundle Text Void) Text -- ^ Output
190−toHumanized c = fmap (humanizeCustom c) . parseSnakeCase []
191−
192−-- | Lift something of type @'Either' ('ParseError' 'Char' 'Void') a@ to
170+-- | Lift something of type @'Either' ('ParseError' 'Char' 'Dec') a@ to
193171-- an instance of 'MonadThrow'. Useful when you want to shortcut on parsing
194172-- failures and you're in an instance of 'MonadThrow'.
195173--
@@ -197,6 +175,6 @@ toHumanized c = fmap (humanizeCustom c) . parseSnakeCase []
197175--
198176-- /since 0.3.0.0/
199177
200−betterThrow :: MonadThrow m => Either (ParseErrorBundle Text Void) a -> m a
178+betterThrow :: MonadThrow m => Either (ParseError Char Dec) a -> m a
201179betterThrow (Left err) = throwM (InflectionParsingFailed err)
202180betterThrow (Right x) = return x
Text/Inflections/Humanize.hs+3−24
@@ -13,8 +13,7 @@
1313{-# LANGUAGE OverloadedStrings #-}
1414
1515module Text.Inflections.Humanize
16− ( humanize
17− , humanizeCustom )
16+ ( humanize )
1817where
1918
2019import Data.Text (Text)
@@ -37,27 +36,7 @@ import Control.Applicative
3736humanize
3837 :: [SomeWord] -- ^ List of words, first of which will be capitalized
3938 -> Text -- ^ The humanized output
40−humanize = humanizeCustom True
41−
42−
43−-- | Separate words with spaces, optionally capitalizing the first word. Like
44−-- 'Text.Inflections.Titleize.titleize', this is meant for creating pretty
45−-- output.
46−--
47−-- >>> foo <- SomeWord <$> mkWord "foo"
48−-- >>> bar <- SomeWord <$> mkAcronym "bar"
49−-- >>> bazz <- SomeWord <$> mkWord "bazz"
50−-- >>> humanizeCustom True [foo,bar,bazz]
51−-- "Foo bar bazz"
52−-- >>> humanizeCustom False [foo,bar,bazz]
53−-- "foo bar bazz"
54−--
55−-- /since 0.3.0.0/
56−humanizeCustom
57− :: Bool -- ^ Whether to capitalize the first character in the output String
58− -> [SomeWord] -- ^ List of words, first of which will be capitalized
59− -> Text -- ^ The humanized output
60−humanizeCustom c xs' =
39+humanize xs' =
6140 case unSomeWord (T.replace "_" " ") <$> xs' of
6241 [] -> ""
63− (x:xs) -> T.unwords $ (if c then T.toTitle else T.toLower) x : (T.toLower <$> xs)
42+ (x:xs) -> T.unwords $ T.toTitle x : (T.toLower <$> xs)
Text/Inflections/Ordinal.hs+1
@@ -16,6 +16,7 @@ module Text.Inflections.Ordinal
1616 , ordinal )
1717where
1818
19+import Data.Monoid ((<>))
1920import Data.Text (Text)
2021import qualified Data.Text as T
2122
Text/Inflections/Parse/CamelCase.hs+5−12
@@ -17,16 +17,11 @@ module Text.Inflections.Parse.CamelCase
1717 ( parseCamelCase )
1818where
1919
20−# if MIN_VERSION_base(4,8,0)
21−import Control.Applicative (empty, many, (<|>))
22−#else
23−import Control.Applicative (empty, many, (<|>), (<$>), (<*))
24−#endif
20+import Control.Applicative
2521import Data.Text (Text)
26−import Data.Void (Void)
2722import Text.Inflections.Types
28−import Text.Megaparsec (Parsec, ParseErrorBundle, choice, eof, parse)
29−import Text.Megaparsec.Char
23+import Text.Megaparsec
24+import Text.Megaparsec.Text
3025import qualified Data.Text as T
3126
3227#if MIN_VERSION_base(4,8,0)
@@ -36,8 +31,6 @@ import Data.Foldable
3631import Prelude hiding (elem)
3732#endif
3833
39−type Parser = Parsec Void Text
40−
4134-- | Parse a CamelCase string.
4235--
4336-- >>> bar <- mkAcronym "bar"
@@ -51,7 +44,7 @@ type Parser = Parsec Void Text
5144parseCamelCase :: (Foldable f, Functor f)
5245 => f (Word 'Acronym) -- ^ Collection of acronyms
5346 -> Text -- ^ Input
54− -> Either (ParseErrorBundle Text Void) [SomeWord] -- ^ Result of parsing
47+ -> Either (ParseError Char Dec) [SomeWord] -- ^ Result of parsing
5548parseCamelCase acronyms = parse (parser acronyms) ""
5649
5750parser :: (Foldable f, Functor f)
@@ -66,7 +59,7 @@ acronym :: (Foldable f, Functor f)
6659 => f (Word 'Acronym)
6760 -> Parser (Word 'Acronym)
6861acronym acronyms = do
69− x <- choice (string . unWord <$> acronyms)
62+ x <- T.pack <$> choice (string . T.unpack . unWord <$> acronyms)
7063 case mkAcronym x of
7164 Nothing -> empty -- cannot happen if the system is sound
7265 Just acr -> return acr
Text/Inflections/Parse/SnakeCase.hs+4−11
@@ -16,16 +16,11 @@ module Text.Inflections.Parse.SnakeCase
1616 ( parseSnakeCase )
1717where
1818
19−# if MIN_VERSION_base(4,8,0)
20−import Control.Applicative (empty, some)
21−#else
22−import Control.Applicative (empty, some, (<$>), (<*))
23−#endif
19+import Control.Applicative
2420import Data.Text (Text)
25−import Data.Void (Void)
2621import Text.Inflections.Types
27−import Text.Megaparsec (Parsec, ParseErrorBundle, eof, sepBy, parse)
28−import Text.Megaparsec.Char
22+import Text.Megaparsec
23+import Text.Megaparsec.Text
2924import qualified Data.Text as T
3025
3126#if MIN_VERSION_base(4,8,0)
@@ -35,8 +30,6 @@ import Data.Foldable
3530import Prelude hiding (elem)
3631#endif
3732
38−type Parser = Parsec Void Text
39−
4033-- | Parse a snake_case string.
4134--
4235-- >>> bar <- mkAcronym "bar"
@@ -50,7 +43,7 @@ type Parser = Parsec Void Text
5043parseSnakeCase :: (Foldable f, Functor f)
5144 => f (Word 'Acronym) -- ^ Collection of acronyms
5245 -> Text -- ^ Input
53− -> Either (ParseErrorBundle Text Void) [SomeWord] -- ^ Result of parsing
46+ -> Either (ParseError Char Dec) [SomeWord] -- ^ Result of parsing
5447parseSnakeCase acronyms = parse (parser acronyms) ""
5548
5649parser :: (Foldable f, Functor f)
Text/Inflections/Titleize.hs+2−2
@@ -17,7 +17,7 @@ import Data.Text (Text)
1717import Text.Inflections.Types
1818import qualified Data.Text as T
1919
20−-- | Capitalize all the 'SomeWord' words in the input list.
20+-- | Capitalize all the Words in the input list.
2121--
2222-- >>> foo <- SomeWord <$> mkWord "foo"
2323-- >>> bar <- SomeWord <$> mkAcronym "bar"
@@ -25,6 +25,6 @@ import qualified Data.Text as T
2525-- >>> titleize [foo,bar,bazz]
2626-- "Foo bar Bazz"
2727titleize
28− :: [SomeWord] -- ^ List of words, of which all 'SomeWord' words will be capitalized and all acronyms will be left as is
28+ :: [SomeWord] -- ^ List of words, first of which will be capitalized
2929 -> Text -- ^ The titleized 'Text'
3030titleize = T.unwords . fmap (unSomeWord T.toTitle)
Text/Inflections/Types.hs+1−2
@@ -33,7 +33,6 @@ where
3333import Control.Monad.Catch
3434import Data.Char (isAlphaNum)
3535import Data.Data (Data)
36−import Data.Void (Void)
3736import Data.Text (Text)
3837import Data.Typeable (Typeable)
3938import GHC.Generics (Generic)
@@ -136,7 +135,7 @@ instance Transformable (Word 'Acronym) where
136135-- /since 0.3.0.0/
137136
138137data InflectionException
139− = InflectionParsingFailed (ParseErrorBundle Text Void)
138+ = InflectionParsingFailed (ParseError Char Dec)
140139 | InflectionInvalidWord Text
141140 | InflectionInvalidAcronym Text
142141 deriving (Eq, Show, Typeable, Data, Generic)
docs/CODE_OF_CONDUCT.mddeleted−35
@@ -1,35 +0,0 @@
1−# Code of conduct
2−
3−## Purpose
4−The primary goal of this Code of Conduct is to enable an open and welcoming environment. We pledge to making participation in our project a harassment-free experience for everyone, regardless of gender, sexual
5−orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof).
6−
7−## General recommendations
8−Examples of behavior that contributes to creating a positive environment include:
9−
10−- Using welcoming and inclusive language
11−- Being respectful of differing viewpoints and experiences
12−- Gracefully accepting constructive criticism
13−- Focusing on what is best for the community
14−- Showing empathy towards other community members
15−
16−Examples of unacceptable behavior by participants include:
17−
18−- The use of sexualized language or imagery and unwelcome sexual attention or advances
19−- Trolling, insulting/derogatory comments, and personal or political attacks
20−- Public or private harassment
21−- Publishing others' private information, such as a physical or electronic address, without explicit permission
22−- Other conduct which could reasonably be considered inappropriate in a professional setting
23−
24−## Maintainer responsibilities
25−Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
26−
27−Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
28−
29−## Scope
30−This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
31−
32−## Enforcement
33−Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [community@stackbuilders.com](mailto:community@stackbuilders.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
34−
35−Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
docs/CONTRIBUTING.mddeleted−13
@@ -1,13 +0,0 @@
1−
2−Thank you for your interest in contributing to this Stack Builders' library. To contribute, please take our [Code of Conduct](CODE_OF_CONDUCT.md) into account, along with the following recommendations:
3−
4−- When submitting contributions to this repository, please make sure to discuss with the maintainer(s) the change you want to make. You can do this through an issue, or by sending an email to [community@stackbuilders.com](mailto:community@stackbuilders.com)
5−
6−- Once the change has been discussed with the maintainer(s), feel free to open a Pull Request. Please include a link to the issue you're trying to solve, or a quick summary of the discussed changes.
7−
8−- If adding any new features that you think should be considered in the README file, please add that information in your Pull Request.
9−
10−- Once you get an approval from any of the maintainers, please merge your Pull Request. Keep in mind that some of our Stack Builders repositories use CI/CD pipelines, so you will need to pass all of the required checks before merging.
11−
12−## Getting help
13−Contact any of our current maintainers, or send us an email at [community@stackbuilders.com](mailto:community@stackbuilders.com) for more information. Thank you for contributing!
inflections.cabal+10−20
@@ -1,5 +1,5 @@
11name: inflections
2−version: 0.4.0.6
2+version: 0.3.0.0
33synopsis: Inflections library for Haskell
44description:
55 Inflections provides methods for singularization, pluralization,
@@ -48,13 +48,10 @@ library
4848 else
4949 ghc-options: -O2 -Wall
5050 build-depends: base >= 4.6 && < 5.0
51− , exceptions
52− , megaparsec
53− , text
54− , unordered-containers
55− if !impl(ghc >= 7.10)
56− build-depends: void == 0.7.*
57−
51+ , exceptions >= 0.6 && < 0.9
52+ , megaparsec >= 5.0 && < 6.0
53+ , text >= 0.2 && < 1.3
54+ , unordered-containers >= 0.2.7 && < 0.3
5855 default-language: Haskell2010
5956
6057test-suite test
@@ -62,19 +59,12 @@ test-suite test
6259 hs-source-dirs: test
6360 main-is: Spec.hs
6461 build-depends: inflections
65− , QuickCheck
62+ , QuickCheck >= 2.7.6 && < 3.0
6663 , base >= 4.6 && < 5.0
67− , containers
68− , hspec
69− , hspec-megaparsec
70− , megaparsec
71− , text
72− if !impl(ghc >= 7.10)
73− build-depends: void == 0.7.*
74−
75− if !impl(ghc >= 8.0)
76− build-depends: semigroups == 0.18.*
77−
64+ , hspec >= 2.0 && < 3.0
65+ , hspec-megaparsec >= 0.3 && < 0.4
66+ , megaparsec >= 5.1 && < 6.0
67+ , text >= 0.2 && < 1.3
7868 if flag(dev)
7969 ghc-options: -Wall -Werror
8070 else
stack.yaml+6−1
@@ -1 +1,6 @@
1−resolver: lts-21.3
1+resolver: lts-7.13
2+packages:
3+- '.'
4+extra-deps:
5+- hspec-megaparsec-0.3.0
6+- megaparsec-5.1.2
stack.yaml.lockdeleted−12
@@ -1,12 +0,0 @@
1−# This file was autogenerated by Stack.
2−# You should not edit this file by hand.
3−# For more information, please see the documentation at:
4−# https://docs.haskellstack.org/en/stable/lock_files
5−
6−packages: []
7−snapshots:
8−- completed:
9− sha256: 97710f56bf093fca0ee5d8dbe19d96b654c752e405b66795b4baedd84a794c60
10− size: 640010
11− url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/3.yaml
12− original: lts-21.3
test/Text/Inflections/HumanizeSpec.hs+13−40
@@ -12,43 +12,16 @@ import Control.Applicative
1212#endif
1313
1414spec :: Spec
15−spec = do
16− describe "humanize" $ do
17− it "converts snake case to a human-readable string" $ do
18− employee <- SomeWord <$> mkWord "employee"
19− salary <- SomeWord <$> mkWord "salary"
20− humanize [employee,salary] `shouldBe` "Employee salary"
21− it "turns underscores into spaces" $ do
22− employee <- SomeWord <$> mkWord "employee"
23− has <- SomeWord <$> mkWord "has"
24− salary <- SomeWord <$> mkWord "salary"
25− humanize [employee, has, salary] `shouldBe` "Employee has salary"
26− it "capitalizes the first word of a sentence" $ do
27− underground <- SomeWord <$> mkWord "underground"
28− humanize [underground] `shouldBe` "Underground"
29− describe "humanizeCustom False" $ do
30− it "converts snake case to a human-readable string" $ do
31− employee <- SomeWord <$> mkWord "employee"
32− salary <- SomeWord <$> mkWord "salary"
33− humanizeCustom False [employee,salary] `shouldBe` "employee salary"
34− it "turns underscores into spaces" $ do
35− employee <- SomeWord <$> mkWord "employee"
36− has <- SomeWord <$> mkWord "has"
37− salary <- SomeWord <$> mkWord "salary"
38− humanizeCustom False [employee, has, salary] `shouldBe` "employee has salary"
39− it "lower-cases the first word of a sentence" $ do
40− underground <- SomeWord <$> mkWord "underground"
41− humanizeCustom False [underground] `shouldBe` "underground"
42− describe "humanizeCustom True" $ do
43− it "converts snake case to a human-readable string" $ do
44− employee <- SomeWord <$> mkWord "employee"
45− salary <- SomeWord <$> mkWord "salary"
46− humanizeCustom True [employee,salary] `shouldBe` "Employee salary"
47− it "turns underscores into spaces" $ do
48− employee <- SomeWord <$> mkWord "employee"
49− has <- SomeWord <$> mkWord "has"
50− salary <- SomeWord <$> mkWord "salary"
51− humanizeCustom True [employee, has, salary] `shouldBe` "Employee has salary"
52− it "capitalizes the first word of a sentence" $ do
53− underground <- SomeWord <$> mkWord "underground"
54− humanizeCustom True [underground] `shouldBe` "Underground"
15+spec = describe "humazine" $ do
16+ it "converts snake case to a human-readable string" $ do
17+ employee <- SomeWord <$> mkWord "employee"
18+ salary <- SomeWord <$> mkWord "salary"
19+ humanize [employee,salary] `shouldBe` "Employee salary"
20+ it "turns underscores into spaces" $ do
21+ employee <- SomeWord <$> mkWord "employee"
22+ has <- SomeWord <$> mkWord "has"
23+ salary <- SomeWord <$> mkWord "salary"
24+ humanize [employee, has, salary] `shouldBe` "Employee has salary"
25+ it "capitalizes the first word of a sentence" $ do
26+ underground <- SomeWord <$> mkWord "underground"
27+ humanize [underground] `shouldBe` "Underground"
test/Text/InflectionsSpec.hs+1−60
@@ -1,60 +1,10 @@
1−{-# OPTIONS_GHC -fno-warn-orphans #-}
2−{-# LANGUAGE CPP #-}
31{-# LANGUAGE OverloadedStrings #-}
42
53module Text.InflectionsSpec (spec) where
64
7−import Data.Void
85import Test.Hspec
96import Test.QuickCheck
107import Text.Inflections
11−import Text.Megaparsec
12−import Data.Text
13−
14−import qualified Data.List.NonEmpty as NE
15−import qualified Data.Set as S
16−
17−#if !MIN_VERSION_base(4,8,0)
18−import Control.Applicative
19−#endif
20−
21−instance Arbitrary Text where
22− arbitrary = pack <$> (arbitrary :: Gen String)
23−
24−arbitraryParseErrorBundle :: Gen (ParseErrorBundle Text Void)
25−arbitraryParseErrorBundle = ParseErrorBundle <$> nonEmptyParseErrors <*> arbitraryPosState
26− where
27− posArbitrary = mkPos <$> ((+1) . abs <$> arbitrary)
28− nonEmptyParseErrors :: Gen (NE.NonEmpty (ParseError Text Void))
29− nonEmptyParseErrors = NE.fromList <$> listOf1 arbitraryParseError
30− arbitrarySourcePos :: Gen SourcePos
31− arbitrarySourcePos = SourcePos <$> arbitrary <*> posArbitrary <*> posArbitrary
32− arbitraryPosState :: Gen (PosState Text)
33− arbitraryPosState =
34− PosState
35− <$> arbitrary
36− <*> arbitrary
37− <*> arbitrarySourcePos
38− <*> posArbitrary
39− <*> arbitrary
40−
41−arbitraryParseError :: Gen (ParseError Text Void)
42−arbitraryParseError = oneof [trivialError, fancyError]
43− where
44− trivialError = TrivialError <$> arbitrary <*> maybeErrorItem <*> setErrorItem
45− fancyError = FancyError <$> arbitrary <*> setErrorFancy
46− setErrorFancy = S.fromList <$> listOf arbitraryErrorFancy
47− maybeErrorItem = oneof [ Just <$> arbitraryErrorItem, return Nothing]
48− setErrorItem = S.fromList <$> listOf arbitraryErrorItem
49−
50−arbitraryErrorFancy :: Gen (ErrorFancy e)
51−arbitraryErrorFancy = oneof [ ErrorFail <$> arbitrary ]
52−
53−arbitraryErrorItem :: (Arbitrary e) => Gen (ErrorItem e)
54−arbitraryErrorItem = oneof [ tokens_, labels_, return EndOfInput ]
55− where
56− tokens_ = Tokens <$> (NE.fromList <$> listOf1 arbitrary)
57− labels_ = Label <$> (NE.fromList <$> listOf1 arbitrary)
588
599spec :: Spec
6010spec = do
@@ -77,21 +27,12 @@ spec = do
7727 it "converts snake case to camel case with the first word capitalized" $
7828 toCamelCased True "underscored_text" `shouldBe` Right "UnderscoredText"
7929
80− describe "toHumanized" $ do
81− context "when the first argument is False" $
82− it "converts snake case to human-readable form with lower-case initial letter" $
83− toHumanized False "underscored_text" `shouldBe` Right "underscored text"
84− context "when the first argument is True" $
85− it "converts snake case to human-readable form with the first word capitalized" $
86− toHumanized True "underscored_text" `shouldBe` Right "Underscored text"
87−
8830 describe "betterThrow" $ do
8931 context "when given a parse error" $
9032 it "throws the correct exception" $
91− property $ forAll arbitraryParseErrorBundle $ \err ->
33+ property $ \err ->
9234 betterThrow (Left err) `shouldThrow`
9335 (== InflectionParsingFailed err)
94−
9536 context "when given a value in Right" $
9637 it "returns the value" $
9738 property $ \x ->