1+ initialProgram : |
2+ # USERNAME CHECKER MVU PRELUDE #
3+
4+ type UsernameCriteria =
5+ + MinLength(Int)
6+ + StartsWithLetter
7+ + NoSpaces in
8+
9+ type UsernameValidity =
10+ + Invalid
11+ + Valid
12+
13+ type Username = String in
14+ type Criteria = [UsernameCriteria] in
15+ type Validity = UsernameValidity in
16+
17+ type Model = (Username, Criteria, Validity) in
18+
19+ let initialModel: Model = (
20+ "",
21+ [
22+ MinLength(5),
23+ StartsWithLetter,
24+ NoSpaces
25+ ],
26+ Invalid
27+ ) in
28+
29+ type Action =
30+ + UpdateUsername(String)
31+ + ClearCriteria
32+ + AddCriterion(UsernameCriteria)
33+ + RemoveCriterion(UsernameCriteria) in
34+
35+ let meetsMinLength: (String, Int) -> Bool =
36+ fun username, len ->
37+ string_length(username) >= len in
38+
39+ let string_contains: (String, String) -> Bool = fun s1: String, s2: String ->
40+ let len = string_length(s1) in
41+ let check = fun idx: Int ->
42+ if idx >= len
43+ then false
44+ else
45+ let char = string_sub(s1, idx, 1) in
46+ if string_eq(char, s2)
47+ then true
48+ else check(idx + 1)
49+ in
50+ check(0)
51+ in
52+
53+ let hasFromSet: (String, String) -> Bool =
54+ fun username: Username, set: String ->
55+ let loop: String -> Bool =
56+ fun s: String ->
57+ if string_length(s) == 0
58+ then false
59+ else
60+ let first = string_sub(s, 0, 1) in
61+ if string_contains(set, first)
62+ then true
63+ else loop(string_sub(s, 1, string_length(s) - 1))
64+ in loop(username)
65+ in
66+
67+ let hasNoSpaces: String -> Bool =
68+ fun username: Username ->
69+ not (hasFromSet(username, " ")) in
70+
71+ let startsWithLetter: Username -> Bool =
72+ fun username: Username ->
73+ if string_length(username) == 0
74+ then false
75+ else
76+ let first_char = string_sub(username, 0, 1) in
77+ string_contains("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", first_char) in
78+
79+ let meetsCriterion: (Username, UsernameCriteria) -> Bool =
80+ fun username, criterion ->
81+ case criterion
82+ | StartsWithLetter => startsWithLetter(username)
83+ | NoSpaces => hasNoSpaces(username)
84+ | MinLength(len) => meetsMinLength(username, len)
85+ end in
86+
87+ let metCriteria: (Username, [UsernameCriteria]) -> [Bool] =
88+ fun username, criteria ->
89+ filter(
90+ criteria,
91+ fun c: UsernameCriteria -> meetsCriterion(username, c)
92+ ) in
93+
94+ let Validity_of: Int -> UsernameValidity =
95+ fun num_criteria_met ->
96+ case num_criteria_met
97+ | 3 => Valid
98+ | _ => Invalid
99+ end in
100+
101+ let calculateValidity: (Username, [UsernameCriteria]) -> UsernameValidity =
102+ fun username, criteria ->
103+ Validity_of(length(metCriteria(username, criteria))) in
104+
105+
106+ let update: (Model, Action) -> Model =
107+ ?
108+ in
109+
110+ prompt : |
111+ Write the Usernames update function
112+ tests : |
113+ test
114+ let model = update(initialModel, ClearCriteria) in
115+ let (_, criteria, _) = model in
116+ length(criteria) == 0
117+ end;
118+
119+ test
120+ let model = update(initialModel, ClearCriteria) in
121+ let model = update(model, AddCriterion(MinLength(5))) in
122+ let model = update(model, UpdateUsername("abcd")) in
123+ let (_, _, validity) = model in
124+ validity == Invalid
125+ end;
126+
127+ test
128+ let model = update(initialModel, ClearCriteria) in
129+ let model = update(model, AddCriterion(MinLength(5))) in
130+ let model = update(model, UpdateUsername("abcde")) in
131+ let (_, _, validity) = model in
132+ validity == Valid
133+ end;
134+
135+ test
136+ let model = update(initialModel, ClearCriteria) in
137+ let model = update(model, AddCriterion(StartsWithLetter)) in
138+ let model = update(model, UpdateUsername("1user")) in
139+ let (_, _, validity) = model in
140+ validity == Invalid
141+ end;
142+
143+ test
144+ let model = update(initialModel, ClearCriteria) in
145+ let model = update(model, AddCriterion(StartsWithLetter)) in
146+ let model = update(model, UpdateUsername("User")) in
147+ let (_, _, validity) = model in
148+ validity == Valid
149+ end;
150+
151+ test
152+ let model = update(initialModel, ClearCriteria) in
153+ let model = update(model, AddCriterion(NoSpaces)) in
154+ let model = update(model, UpdateUsername("User name")) in
155+ let (_, _, validity) = model in
156+ validity == Invalid
157+ end;
158+
159+ test
160+ let model = update(initialModel, ClearCriteria) in
161+ let model = update(model, AddCriterion(NoSpaces)) in
162+ let model = update(model, UpdateUsername("Username")) in
163+ let (_, _, validity) = model in
164+ validity == Valid
165+ end;
166+
167+ test
168+ let model = update(initialModel, UpdateUsername("User1")) in
169+ let (_, _, validity) = model in
170+ validity == Valid
171+ end;
172+
173+ test
174+ let model = update(initialModel, UpdateUsername("1 us")) in
175+ let (_, _, validity) = model in
176+ validity == Invalid
177+ end;
0 commit comments