|
| 1 | +{- |
| 2 | +Copyright 2023 Google LLC |
| 3 | +
|
| 4 | +Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +you may not use this file except in compliance with the License. |
| 6 | +You may obtain a copy of the License at |
| 7 | +
|
| 8 | + https://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +
|
| 10 | +Unless required by applicable law or agreed to in writing, software |
| 11 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +See the License for the specific language governing permissions and |
| 14 | +limitations under the License. |
| 15 | +-} |
| 16 | + |
| 17 | +-- | |
| 18 | +-- Description: Tests for the "Format" module. |
| 19 | +-- Copyright: Copyright 2023 Google LLC |
| 20 | +-- License: Apache-2.0 |
| 21 | + |
| 22 | +module FormatSpec (spec) where |
| 23 | + |
| 24 | +import Data.Aeson |
| 25 | +import Data.Aeson.KeyMap qualified as KeyMap |
| 26 | +import Data.Char |
| 27 | +import Data.Text (Text) |
| 28 | +import Data.Text qualified as Text |
| 29 | +import Data.Vector qualified as Vector |
| 30 | +import Format |
| 31 | +import Test.Hspec |
| 32 | +import Test.Hspec.QuickCheck |
| 33 | +import Test.QuickCheck |
| 34 | +import Test.QuickCheck.Instances.Text () |
| 35 | + |
| 36 | +spec :: Spec |
| 37 | +spec = do |
| 38 | + describe "formatMessages" $ do |
| 39 | + it "formats a particular message" $ |
| 40 | + formatMessages |
| 41 | + ( objectWithMessage $ |
| 42 | + Text.unlines |
| 43 | + [ "Bad.hs:16:9-20: Warning: Use /=", |
| 44 | + "Found:", |
| 45 | + " not (a == b)", |
| 46 | + "Perhaps:", |
| 47 | + " a /= b", |
| 48 | + "Note: incorrect if either value is NaN" |
| 49 | + ] |
| 50 | + ) |
| 51 | + `shouldBe` objectWithMessage |
| 52 | + ( Text.unlines |
| 53 | + [ "Bad.hs:16:9-20: Warning: Use /=", |
| 54 | + " ", |
| 55 | + "Found:", |
| 56 | + " not (a == b)", |
| 57 | + " ", |
| 58 | + "Perhaps:", |
| 59 | + " a /= b", |
| 60 | + " ", |
| 61 | + "Note: incorrect if either value is NaN" |
| 62 | + ] |
| 63 | + ) |
| 64 | + |
| 65 | + prop "formats messages in general" $ |
| 66 | + forAll (listOf chooseSection) $ \sections -> |
| 67 | + let message = mconcat sections |
| 68 | + message' = Text.replace " " " " $ Text.intercalate " \n" sections |
| 69 | + in counterexample (show message) $ |
| 70 | + counterexample (show message') $ |
| 71 | + formatMessages (objectWithMessage message) `shouldBe` objectWithMessage message' |
| 72 | + |
| 73 | +objectWithMessage :: Text -> Value |
| 74 | +objectWithMessage message = |
| 75 | + Object . KeyMap.singleton "runs" $ |
| 76 | + Array . Vector.singleton . Object . KeyMap.singleton "results" $ |
| 77 | + Array . Vector.singleton . Object . KeyMap.singleton "message" $ |
| 78 | + Object . KeyMap.singleton "text" $ |
| 79 | + String message |
| 80 | + |
| 81 | +chooseSection :: Gen Text |
| 82 | +chooseSection = do |
| 83 | + note <- arbitrary `suchThat` isNonEmptyLine |
| 84 | + codelines <- map (" " <>) <$> arbitrary `suchThat` all isNonEmptyLine |
| 85 | + return $ Text.unlines $ note : codelines |
| 86 | + where |
| 87 | + isNonEmptyLine s = |
| 88 | + not |
| 89 | + ( Text.null s |
| 90 | + || Text.take 1 s == " " |
| 91 | + || Text.elem '\n' s |
| 92 | + || Text.elem '\r' s |
| 93 | + || Text.all isSpace s |
| 94 | + ) |
| 95 | + && Text.all (\c -> isAlphaNum c || c == ' ') s |
0 commit comments