Skip to content
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
131 changes: 111 additions & 20 deletions exercises/practice/word-count/WordCountTest.lean
Original file line number Diff line number Diff line change
@@ -1,44 +1,135 @@
import LeanTest
import Std
import WordCount

open LeanTest

def sort (list : List (String × Nat)) : List (String × Nat) :=
list.mergeSort (fun x y => x.fst <= y.fst)

def sortedResult (sentence : String) : List (String × Nat) :=
WordCount.countWords sentence |> Std.HashMap.toList |> sort

def wordCountTests : TestSuite :=
(TestSuite.empty "WordCount")
|>.addTest "count one word" (do
return assertEqual (sort [("word", 1)]) (sortedResult "word"))
return assertEqual [
("word", 1)
] $ WordCount.countWords "word"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "count one of each word" (do
return assertEqual (sort [("one", 1), ("of", 1), ("each", 1)]) (sortedResult "one of each"))
return assertEqual [
("each", 1),
("of", 1),
("one", 1)
] $ WordCount.countWords "one of each"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "multiple occurrences of a word" (do
return assertEqual (sort [("one", 1), ("fish", 4), ("two", 1), ("red", 1), ("blue", 1)]) (sortedResult "one fish two fish red fish blue fish"))
return assertEqual [
("blue", 1),
("fish", 4),
("one", 1),
("red", 1),
("two", 1)
] $ WordCount.countWords "one fish two fish red fish blue fish"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "handles cramped lists" (do
return assertEqual (sort [("one", 1), ("two", 1), ("three", 1)]) (sortedResult "one,two,three"))
return assertEqual [
("one", 1),
("three", 1),
("two", 1)
] $ WordCount.countWords "one,two,three"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "handles expanded lists" (do
return assertEqual (sort [("one", 1), ("two", 1), ("three", 1)]) (sortedResult "one,\ntwo,\nthree"))
return assertEqual [
("one", 1),
("three", 1),
("two", 1)
] $ WordCount.countWords "one,\ntwo,\nthree"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "ignore punctuation" (do
return assertEqual (sort [("car", 1), ("carpet", 1), ("as", 1), ("java", 1), ("javascript", 1)]) (sortedResult "car: carpet as java: javascript!!&@$%^&"))
return assertEqual [
("as", 1),
("car", 1),
("carpet", 1),
("java", 1),
("javascript", 1)
] $ WordCount.countWords "car: carpet as java: javascript!!&@$%^&"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "include numbers" (do
return assertEqual (sort [("testing", 2), ("1", 1), ("2", 1)]) (sortedResult "testing, 1, 2 testing"))
return assertEqual [
("1", 1),
("2", 1),
("testing", 2)
] $ WordCount.countWords "testing, 1, 2 testing"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "normalize case" (do
return assertEqual (sort [("go", 3), ("stop", 2)]) (sortedResult "go Go GO Stop stop"))
return assertEqual [
("go", 3),
("stop", 2)
] $ WordCount.countWords "go Go GO Stop stop"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "with apostrophes" (do
return assertEqual (sort [("first", 1), ("don't", 2), ("laugh", 1), ("then", 1), ("cry", 1), ("you're", 1), ("getting", 1), ("it", 1)] ) (sortedResult "'First: don't laugh. Then: don't cry. You're getting it.'"))
return assertEqual [
("cry", 1),
("don't", 2),
("first", 1),
("getting", 1),
("it", 1),
("laugh", 1),
("then", 1),
("you're", 1)
] $ WordCount.countWords "'First: don't laugh. Then: don't cry. You're getting it.'"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "with quotations" (do
return assertEqual (sort [("joe", 1), ("can't", 1), ("tell", 1), ("between", 1), ("large", 2), ("and", 1)]) (sortedResult "Joe can't tell between 'large' and large."))
return assertEqual [
("and", 1),
("between", 1),
("can't", 1),
("joe", 1),
("large", 2),
("tell", 1)
] $ WordCount.countWords "Joe can't tell between 'large' and large."
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "substrings from the beginning" (do
return assertEqual (sort [("joe", 1), ("can't", 1), ("tell", 1), ("between", 1), ("app", 1), ("apple", 1), ("and", 1), ("a", 1)]) (sortedResult "Joe can't tell between app, apple and a."))
return assertEqual [
("a", 1),
("and", 1),
("app", 1),
("apple", 1),
("between", 1),
("can't", 1),
("joe", 1),
("tell", 1)
] $ WordCount.countWords "Joe can't tell between app, apple and a."
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "multiple spaces not detected as a word" (do
return assertEqual (sort [("multiple", 1), ("whitespaces", 1)]) (sortedResult " multiple whitespaces"))
return assertEqual [
("multiple", 1),
("whitespaces", 1)
] $ WordCount.countWords " multiple whitespaces"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "alternating word separators not detected as a word" (do
return assertEqual (sort [("one", 1), ("two", 1), ("three", 1)]) (sortedResult ",\n,one,\n ,two \n 'three'"))
return assertEqual [
("one", 1),
("three", 1),
("two", 1)
] $ WordCount.countWords ",\n,one,\n ,two \n 'three'"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)
|>.addTest "quotation for word with apostrophe" (do
return assertEqual (sort [("can", 1), ("can't", 2)]) (sortedResult "can, can't, 'can't'"))
return assertEqual [
("can", 1),
("can't", 2)
] $ WordCount.countWords "can, can't, 'can't'"
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2)

def main : IO UInt32 := do
runTestSuitesWithExitCode [wordCountTests]
2 changes: 2 additions & 0 deletions generators/Generator/Generator.lean
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Generator.WordCountGenerator
import Generator.SgfParsingGenerator
import Generator.DndCharacterGenerator
import Generator.BankAccountGenerator
Expand Down Expand Up @@ -92,6 +93,7 @@ abbrev endBodyGenerator := String -> String

def dispatch : Std.HashMap String (introGenerator × testCaseGenerator × endBodyGenerator) :=
Std.HashMap.ofList [
("WordCount", (WordCountGenerator.genIntro, WordCountGenerator.genTestCase, WordCountGenerator.genEnd)),
("SgfParsing", (SgfParsingGenerator.genIntro, SgfParsingGenerator.genTestCase, SgfParsingGenerator.genEnd)),
("DndCharacter", (DndCharacterGenerator.genIntro, DndCharacterGenerator.genTestCase, DndCharacterGenerator.genEnd)),
("BankAccount", (BankAccountGenerator.genIntro, BankAccountGenerator.genTestCase, BankAccountGenerator.genEnd)),
Expand Down
40 changes: 40 additions & 0 deletions generators/Generator/Generator/WordCountGenerator.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Lean.Data.Json
import Std
import Helper

open Lean
open Std
open Helper

namespace WordCountGenerator

def genIntro (exercise : String) : String := s!"import LeanTest
import Std
import {exercise}

open LeanTest

def {exercise.decapitalize}Tests : TestSuite :=
(TestSuite.empty \"{exercise}\")"

def genTestCase (exercise : String) (case : TreeMap.Raw String Json) : String :=
let input := case.get! "input"
let expected := case.get! "expected" |> (serializeObjectAsList · λ k v => s!"(\"{k}\", {v})")
let description := case.get! "description"
|> (·.compress)
let funName := getFunName (case.get! "property")
let call := s!"$ {exercise}.{funName} {insertAllInputs input}
|>.toList
|>.mergeSort λ (k1, _) (k2, _) => k1 ≤ k2"
s!"
|>.addTest {description} (do
return assertEqual {expected} {call})"

def genEnd (exercise : String) : String :=
s!"

def main : IO UInt32 := do
runTestSuitesWithExitCode [{exercise.decapitalize}Tests]
"

end WordCountGenerator
Loading