@@ -1,10 +1,72 @@
1−module TodoBench where
1+module Realistic.Todo (benchmark) where
22
3+import Benchmark
34import String
45
5−---- MODEL ----
66
7−-- The full application state of our todo app.
7+benchmark : Benchmark.Benchmark
8+benchmark =
9+ Benchmark.suite "todomvc business logic"
10+ [ run "type in 5 todos, each 15 characters long" typingActions
11+ , run "do everything" batchActions
12+ ]
13+
14+
15+run : String -> List Action -> Benchmark.Benchmark
16+run description actions =
17+ Benchmark.test
18+ (description ++ " - " ++ toString (List.length actions) ++ " actions")
19+ (\_ -> List.foldl update emptyModel actions)
20+
21+
22+typingActions =
23+ let
24+ enter i =
25+ List.map (\n -> UpdateField (String.repeat n "X")) [1..15]
26+ ++ [ Add ]
27+ in
28+ List.concatMap enter [1..5]
29+
30+
31+batchActions =
32+ let
33+ addTask i =
34+ [ UpdateField ("My task " ++ toString i)
35+ , Add
36+ ]
37+
38+ editTask i =
39+ [ EditingTask i True
40+ , UpdateTask i "New Task text"
41+ , EditingTask i False
42+ ]
43+
44+ check i =
45+ Check i True
46+
47+ uncheck i =
48+ Check i False
49+
50+ isEven i =
51+ i % 2 == 0
52+ in
53+ List.concat
54+ [ List.concatMap addTask [1..50]
55+ , [CheckAll True, CheckAll False]
56+ , List.concatMap editTask (List.filter isEven [1 .. 50])
57+ , List.map check [5, 7, 9, 13, 17, 23, 37]
58+ , List.map uncheck [7, 13, 23, 37]
59+ , [DeleteComplete, Delete 7, Delete 23]
60+ , List.concatMap addTask [51..80]
61+ , List.map check (List.filter isEven [51..80])
62+ , [DeleteComplete, CheckAll True, DeleteComplete]
63+ ]
64+
65+
66+
67+-- MODEL
68+
69+
870type alias Model =
971 { tasks : List Task
1072 , field : String
@@ -39,11 +101,10 @@ emptyModel =
39101 }
40102
41103
42−---- UPDATE ----
43104
44−-- A description of the kinds of actions that can be performed on the model of
45−-- our application. See the following post for more info on this pattern and
46−-- some alternatives: http://elm-lang.org/learn/Architecture.elm
105+-- UPDATE
106+
107+
47108type Action
48109 = NoOp
49110 | UpdateField String
@@ -57,7 +118,6 @@ type Action
57118 | ChangeVisibility String
58119
59120
60−-- How we update our Model on a given Action?
61121update : Action -> Model -> Model
62122update action model =
63123 case action of
@@ -65,68 +125,43 @@ update action model =
65125
66126 Add ->
67127 { model |
68− uid <- model.uid + 1,
69− field <- "",
70− tasks <-
128+ uid = model.uid + 1,
129+ field = "",
130+ tasks =
71131 if String.isEmpty model.field
72132 then model.tasks
73133 else model.tasks ++ [newTask model.field model.uid]
74134 }
75135
76136 UpdateField str ->
77− { model | field <- str }
137+ { model | field = str }
78138
79139 EditingTask id isEditing ->
80− let updateTask t = if t.id == id then { t | editing <- isEditing } else t
140+ let updateTask t = if t.id == id then { t | editing = isEditing } else t
81141 in
82− { model | tasks <- List.map updateTask model.tasks }
142+ { model | tasks = List.map updateTask model.tasks }
83143
84144 UpdateTask id task ->
85− let updateTask t = if t.id == id then { t | description <- task } else t
145+ let updateTask t = if t.id == id then { t | description = task } else t
86146 in
87− { model | tasks <- List.map updateTask model.tasks }
147+ { model | tasks = List.map updateTask model.tasks }
88148
89149 Delete id ->
90− { model | tasks <- List.filter (\t -> t.id /= id) model.tasks }
150+ { model | tasks = List.filter (\t -> t.id /= id) model.tasks }
91151
92152 DeleteComplete ->
93− { model | tasks <- List.filter (not << .completed) model.tasks }
153+ { model | tasks = List.filter (not << .completed) model.tasks }
94154
95155 Check id isCompleted ->
96− let updateTask t = if t.id == id then { t | completed <- isCompleted } else t
156+ let updateTask t = if t.id == id then { t | completed = isCompleted } else t
97157 in
98− { model | tasks <- List.map updateTask model.tasks }
158+ { model | tasks = List.map updateTask model.tasks }
99159
100160 CheckAll isCompleted ->
101− let updateTask t = { t | completed <- isCompleted }
161+ let updateTask t = { t | completed = isCompleted }
102162 in
103− { model | tasks <- List.map updateTask model.tasks }
163+ { model | tasks = List.map updateTask model.tasks }
104164
105165 ChangeVisibility visibility ->
106− { model | visibility <- visibility }
107−
108−testActions =
109− List.concat
110− [ List.concatMap --Add 50 tasks
111− (\i -> [UpdateField <| "My task " ++ toString i, Add]) [1 .. 50]
112− , [CheckAll True] --Check them all
113− , [CheckAll False] --Uncheck them all
114− , List.concatMap --Alter the text of even numbered tasks
115− (\i -> [EditingTask i True, UpdateTask i "New Task text", Add] ) <| List.filter (\x -> x % 2 == 0 ) [1 .. 50]
116− --Check and uncheck some more tasks
117− , [Check 5 True, Check 7 True, Check 9 True, Check 13 True, Check 17 True, Check 23 True, Check 37 True]
118− , [Check 7 False, Check 13 False, Check 23 False, Check 37 False]
119− , [DeleteComplete] --Delete our checked tasks
120− , [Delete 7, Delete 23] --Delete a few more tasks
121− , List.concatMap --Add a few more tasks
122− (\i -> [UpdateField <| "Second batch task " ++ toString i, Add]) [51 .. 80]
123− , List.map --Check off and delete every other task
124− (\i -> Check i True ) <| List.filter (\x -> x % 2 == 0 ) [1 .. 80]
125− , [DeleteComplete]
126− , [CheckAll True, DeleteComplete] --Check and delete the remaining tasks
127− ]
128−
129−
130−evalActions : List Action -> Model
131−evalActions actions =
132− List.foldr update emptyModel actions
166+ { model | visibility = visibility }
167+