Skip to content

house: Fix tests to match x-common and add working stub solution. #348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions exercises/house/HINTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Hints

This exercise is about [code refactoring](https://en.wikipedia.org/wiki/Refactoring),
so we are providing you with a solution that already passes the tests.

The challenge is to rewrite it until you are proud of it, and learn
something in the process.

If you don't know where to start, here are some ideas:

- Try to reduce repetition to a minimum.
- Try to make the code readable.

Take your time.
Copy link
Member

@petertseng petertseng Sep 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://www.youtube.com/watch?v=RuqaVryDRd0&t=10

Ignore this comment of mine, it is not serious.


Change one thing at a time and check if your solution still passes the tests.

Have fun!
4 changes: 3 additions & 1 deletion exercises/house/src/Example.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
module House (rhyme) where

import Data.List (intercalate)

rhyme :: String
rhyme = unlines $ map ("This is " ++) $ scanl1 f pieces
rhyme = intercalate "\n" $ map ("This is " ++) $ scanl1 f pieces
where f tail' piece = piece ++ ' ' : tail'

pieces :: [String]
Expand Down
90 changes: 89 additions & 1 deletion exercises/house/src/House.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,92 @@
module House (rhyme) where

rhyme :: String
rhyme = undefined
rhyme = "This is the house that Jack built.\n\
\\n\
\This is the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the farmer sowing his corn\n\
\that kept the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the horse and the hound and the horn\n\
\that belonged to the farmer sowing his corn\n\
\that kept the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n"
212 changes: 119 additions & 93 deletions exercises/house/test/Tests.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Test.Hspec (Spec, describe, it, shouldBe)
import Control.Monad (unless)
import Test.Hspec (Spec, describe, expectationFailure, it, shouldBe)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)

import House (rhyme)
Expand All @@ -8,96 +9,121 @@ main = hspecWith defaultConfig {configFastFail = True} specs

specs :: Spec
specs = describe "house" $
it "rhyme" $ rhyme `shouldBe` expected

describe "rhyme" $ do

-- First we test the input, line by line, to give more
-- useful error messages.

it "matches lines" $ sequence_ lineAssertions

-- Finally, because testing lines we are unable
-- to detect a missing newline at the end of the
-- lyrics, we test the full song.

it "matches full song" $ rhyme `shouldBe` lyrics
where
expected = "This is the house that Jack built.\n\
\\n\
\This is the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the farmer sowing his corn\n\
\that kept the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the horse and the hound and the horn\n\
\that belonged to the farmer sowing his corn\n\
\that kept the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\"

lineAssertions = zipWith checkLine [1 :: Int ..] $ zipMaybe (lines rhyme) (lines lyrics)

checkLine lineno (got, want) =
unless (got == want) $
expectationFailure $ "mismatch at line " ++ show lineno ++ "\nexpected: " ++ show want ++ "\n but got: " ++ show got

zipMaybe [] [] = []
zipMaybe (x:xs) [] = (Just x , Nothing) : zipMaybe xs []
zipMaybe [] (y:ys) = (Nothing, Just y ) : zipMaybe [] ys
zipMaybe (x:xs) (y:ys) = (Just x , Just y ) : zipMaybe xs ys

-- Lyrics extracted from `exercism/x-common` on 2016-09-23.

lyrics :: String
lyrics = "This is the house that Jack built.\n\
\\n\
\This is the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the farmer sowing his corn\n\
\that kept the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n\
\\n\
\This is the horse and the hound and the horn\n\
\that belonged to the farmer sowing his corn\n\
\that kept the rooster that crowed in the morn\n\
\that woke the priest all shaven and shorn\n\
\that married the man all tattered and torn\n\
\that kissed the maiden all forlorn\n\
\that milked the cow with the crumpled horn\n\
\that tossed the dog\n\
\that worried the cat\n\
\that killed the rat\n\
\that ate the malt\n\
\that lay in the house that Jack built.\n"