elm-pages 3.0.0-beta.14 → 3.0.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +1 -1
  2. package/codegen/elm-pages-codegen.js +4 -7
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  6. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  7. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  8. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  9. package/generator/src/compatibility-key.js +1 -1
  10. package/generator/src/error-formatter.js +7 -3
  11. package/generator/src/render.js +8 -17
  12. package/generator/src/request-cache.js +34 -4
  13. package/generator/static-code/hmr.js +16 -2
  14. package/package.json +1 -1
  15. package/src/ApiRoute.elm +1 -4
  16. package/src/BackendTask/Env.elm +10 -8
  17. package/src/BackendTask/File.elm +10 -10
  18. package/src/BackendTask/Glob.elm +2 -2
  19. package/src/BackendTask/Http.elm +49 -13
  20. package/src/BackendTask/Port.elm +50 -46
  21. package/src/BackendTask.elm +5 -5
  22. package/src/Exception.elm +70 -12
  23. package/src/Form.elm +3 -2
  24. package/src/Pages/Generate.elm +299 -102
  25. package/src/Pages/Internal/Platform/Cli.elm +17 -37
  26. package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
  27. package/src/Pages/Internal/Platform/GeneratorApplication.elm +17 -41
  28. package/src/Pages/Internal/Platform/StaticResponses.elm +11 -25
  29. package/src/Pages/Script.elm +2 -2
  30. package/src/Pages/StaticHttpRequest.elm +1 -23
  31. package/src/Server/Request.elm +3 -2
  32. package/src/MultiDict.elm +0 -49
  33. package/src/PairingHeap.elm +0 -137
  34. package/src/Parser/Extra/String.elm +0 -33
  35. package/src/Parser/Extra.elm +0 -69
  36. package/src/ProgramTest/ComplexQuery.elm +0 -360
  37. package/src/ProgramTest/EffectSimulation.elm +0 -122
  38. package/src/ProgramTest/Failure.elm +0 -367
  39. package/src/ProgramTest/HtmlHighlighter.elm +0 -116
  40. package/src/ProgramTest/HtmlParserHacks.elm +0 -58
  41. package/src/ProgramTest/HtmlRenderer.elm +0 -73
  42. package/src/ProgramTest/Program.elm +0 -30
  43. package/src/ProgramTest/StringLines.elm +0 -26
  44. package/src/ProgramTest/TestHtmlHacks.elm +0 -132
  45. package/src/ProgramTest/TestHtmlParser.elm +0 -201
  46. package/src/ProgramTest.elm +0 -2339
  47. package/src/Query/Extra.elm +0 -55
  48. package/src/SimulatedEffect/Cmd.elm +0 -69
  49. package/src/SimulatedEffect/Http.elm +0 -330
  50. package/src/SimulatedEffect/Navigation.elm +0 -69
  51. package/src/SimulatedEffect/Ports.elm +0 -62
  52. package/src/SimulatedEffect/Process.elm +0 -24
  53. package/src/SimulatedEffect/Sub.elm +0 -48
  54. package/src/SimulatedEffect/Task.elm +0 -252
  55. package/src/SimulatedEffect/Time.elm +0 -25
  56. package/src/SimulatedEffect.elm +0 -42
  57. package/src/String/Extra.elm +0 -6
  58. package/src/Test/Http.elm +0 -145
  59. package/src/TestResult.elm +0 -35
  60. package/src/TestState.elm +0 -305
  61. package/src/Url/Extra.elm +0 -100
  62. package/src/Vendored/Diff.elm +0 -321
  63. package/src/Vendored/Failure.elm +0 -217
  64. package/src/Vendored/FormatMonochrome.elm +0 -44
  65. package/src/Vendored/Highlightable.elm +0 -53
@@ -1,367 +0,0 @@
1
- module ProgramTest.Failure exposing (Failure(..), toString)
2
-
3
- import Html exposing (Html)
4
- import ProgramTest.ComplexQuery as ComplexQuery exposing (Failure(..), FailureContext1(..))
5
- import ProgramTest.TestHtmlHacks as TestHtmlHacks
6
- import Set
7
- import String.Extra
8
- import Test.Html.Query as Query
9
- import Test.Runner.Failure
10
- import Url exposing (Url)
11
- import Vendored.Failure
12
- import Vendored.FormatMonochrome
13
-
14
-
15
- type Failure
16
- = ChangedPage String Url
17
- -- Errors
18
- | ExpectFailed String String Test.Runner.Failure.Reason
19
- | SimulateFailed String String
20
- | SimulateFailedToFindTarget String String
21
- | SimulateLastEffectFailed String
22
- | InvalidLocationUrl String String
23
- | InvalidFlags String String
24
- | ProgramDoesNotSupportNavigation String
25
- | NoBaseUrl String String
26
- | NoMatchingHttpRequest Int Int String { method : String, url : String } (List ( String, String ))
27
- | MultipleMatchingHttpRequest Int Int String { method : String, url : String } (List ( String, String ))
28
- | EffectSimulationNotConfigured String
29
- | ViewAssertionFailed String (Html ()) ComplexQuery.Highlight ( ComplexQuery.FailureContext, ComplexQuery.Failure )
30
- | CustomFailure String String
31
-
32
-
33
- toString : Failure -> String
34
- toString failure =
35
- case failure of
36
- ChangedPage cause finalLocation ->
37
- cause ++ " caused the program to end by navigating to " ++ String.Extra.escape (Url.toString finalLocation) ++ ". NOTE: If this is what you intended, use ProgramTest.expectPageChange to end your test."
38
-
39
- ExpectFailed expectationName description reason ->
40
- expectationName
41
- ++ ":\n"
42
- ++ Vendored.Failure.format
43
- Vendored.FormatMonochrome.formatEquality
44
- description
45
- reason
46
-
47
- SimulateFailed functionName message ->
48
- functionName ++ ":\n" ++ message
49
-
50
- SimulateFailedToFindTarget functionName message ->
51
- functionName ++ ":\n" ++ message
52
-
53
- SimulateLastEffectFailed message ->
54
- "simulateLastEffect failed: " ++ message
55
-
56
- InvalidLocationUrl functionName invalidUrl ->
57
- functionName ++ ": " ++ "Not a valid absolute URL:\n" ++ String.Extra.escape invalidUrl
58
-
59
- InvalidFlags functionName message ->
60
- functionName ++ ":\n" ++ message
61
-
62
- ProgramDoesNotSupportNavigation functionName ->
63
- functionName ++ ": Program does not support navigation. Use ProgramTest.createApplication to create a ProgramTest that supports navigation."
64
-
65
- NoBaseUrl functionName relativeUrl ->
66
- functionName ++ ": The ProgramTest does not have a base URL and cannot resolve the relative URL " ++ String.Extra.escape relativeUrl ++ ". Use ProgramTest.withBaseUrl before calling ProgramTest.start to create a ProgramTest that can resolve relative URLs."
67
-
68
- NoMatchingHttpRequest expected actual functionName request pendingRequests ->
69
- String.concat
70
- [ functionName
71
- , ": "
72
- , "Expected "
73
- , case expected of
74
- 1 ->
75
- "HTTP request"
76
-
77
- _ ->
78
- "at least " ++ String.fromInt expected ++ " HTTP requests"
79
- , " ("
80
- , request.method
81
- , " "
82
- , request.url
83
- , ") to have been made and still be pending, "
84
- , case actual of
85
- 0 ->
86
- "but no such requests were made."
87
-
88
- _ ->
89
- "but only " ++ String.fromInt actual ++ " such requests were made."
90
- , "\n"
91
- , case pendingRequests of
92
- [] ->
93
- " No requests were made."
94
-
95
- _ ->
96
- String.concat
97
- [ " The following requests were made:\n"
98
- , String.join "\n" <|
99
- List.map (\( method, url ) -> " - " ++ method ++ " " ++ url) pendingRequests
100
- ]
101
- ]
102
-
103
- MultipleMatchingHttpRequest expected actual functionName request pendingRequests ->
104
- String.concat
105
- [ functionName
106
- , ": "
107
- , "Expected "
108
- , case expected of
109
- 1 ->
110
- "a single HTTP request"
111
-
112
- _ ->
113
- String.fromInt expected ++ " HTTP requests"
114
- , " ("
115
- , request.method
116
- , " "
117
- , request.url
118
- , ") to have been made, but "
119
- , String.fromInt actual
120
- , " such requests were made.\n"
121
- , case pendingRequests of
122
- [] ->
123
- " No requests were made."
124
-
125
- _ ->
126
- String.concat
127
- [ " The following requests were made:\n"
128
- , String.join "\n" <|
129
- List.map (\( method, url ) -> " - " ++ method ++ " " ++ url) pendingRequests
130
- ]
131
- , if expected == 1 && actual > 1 then
132
- let
133
- useInstead =
134
- if String.startsWith "simulate" functionName then
135
- "simulateHttpResponseAdvanced"
136
-
137
- else if String.startsWith "expect" functionName then
138
- "expectHttpRequests"
139
-
140
- else
141
- "ensureHttpRequests"
142
- in
143
- "\n\nNOTE: If you want to allow multiple requests to the same endpoint, use ProgramTest." ++ useInstead ++ "."
144
-
145
- else
146
- ""
147
- ]
148
-
149
- EffectSimulationNotConfigured functionName ->
150
- "TEST SETUP ERROR: In order to use " ++ functionName ++ ", you MUST use ProgramTest.withSimulatedEffects before calling ProgramTest.start"
151
-
152
- ViewAssertionFailed functionName html highlight reason ->
153
- let
154
- highlighter =
155
- if Set.isEmpty highlight then
156
- \_ _ _ -> True
157
-
158
- else
159
- \tag attrs children ->
160
- Set.member tag highlight
161
- in
162
- String.join "\n"
163
- [ TestHtmlHacks.renderHtml showColors.dim highlighter (Query.fromHtml html)
164
- , ""
165
- , "▼ " ++ functionName
166
- , ""
167
- , renderQueryFailureWithContext renderQueryFailure 0 True reason
168
- ]
169
-
170
- CustomFailure assertionName message ->
171
- assertionName ++ ": " ++ message
172
-
173
-
174
- renderQueryFailureWithContext : (Int -> Bool -> a -> String) -> Int -> Bool -> ( ComplexQuery.FailureContext, a ) -> String
175
- renderQueryFailureWithContext renderInner indent color failure =
176
- let
177
- indentS =
178
- String.repeat indent " "
179
- in
180
- case failure of
181
- ( [], inner ) ->
182
- renderInner indent color inner
183
-
184
- ( (Description description) :: baseFailure, inner ) ->
185
- String.join "\n" <|
186
- List.filter ((/=) "")
187
- [ indentS ++ renderDescriptionResult (colorsFor color) description ++ ":"
188
- , renderQueryFailureWithContext renderInner (indent + 2) color ( baseFailure, inner )
189
- ]
190
-
191
- ( (CheckSucceeded description checkContext) :: baseFailure, inner ) ->
192
- String.join "\n" <|
193
- List.filter ((/=) "")
194
- [ indentS ++ renderDescriptionResult (colorsFor color) (Ok description) ++ ":"
195
- , renderQueryFailureWithContext_ (\_ _ () -> "") (indent + 2) color ( checkContext, () )
196
- , renderQueryFailureWithContext renderInner indent color ( baseFailure, inner )
197
- ]
198
-
199
- ( (FindSucceeded (Just description) successfulChecks) :: baseFailure, inner ) ->
200
- String.join "\n" <|
201
- List.filter ((/=) "")
202
- [ indentS ++ renderDescriptionResult (colorsFor color) (Ok description) ++ ":"
203
- , renderSelectorResults (indent + 2) (colorsFor color) (List.map Ok (successfulChecks ()))
204
- , renderQueryFailureWithContext renderInner indent color ( baseFailure, inner )
205
- ]
206
-
207
- ( (FindSucceeded Nothing successfulChecks) :: baseFailure, inner ) ->
208
- String.join "\n" <|
209
- List.filter ((/=) "")
210
- [ renderSelectorResults indent (colorsFor color) (List.map Ok (successfulChecks ()))
211
- , renderQueryFailureWithContext renderInner indent color ( baseFailure, inner )
212
- ]
213
-
214
-
215
- renderQueryFailureWithContext_ : (Int -> Bool -> a -> String) -> Int -> Bool -> ( ComplexQuery.FailureContext, a ) -> String
216
- renderQueryFailureWithContext_ =
217
- renderQueryFailureWithContext
218
-
219
-
220
- renderQueryFailure : Int -> Bool -> ComplexQuery.Failure -> String
221
- renderQueryFailure indent color failure =
222
- let
223
- indentS =
224
- String.repeat indent " "
225
- in
226
- case failure of
227
- QueryFailed failureReason ->
228
- renderSelectorResults indent (colorsFor color) failureReason
229
-
230
- ComplexQuery.SimulateFailed string ->
231
- let
232
- colors =
233
- colorsFor color
234
- in
235
- indentS ++ renderSelectorResult colors (Err string)
236
-
237
- NoMatches description options ->
238
- let
239
- sortedByPriority =
240
- options
241
- |> List.sortBy (\( _, prio, _ ) -> -prio)
242
-
243
- maxPriority =
244
- List.head sortedByPriority
245
- |> Maybe.map (\( _, prio, _ ) -> prio)
246
- |> Maybe.withDefault 0
247
- in
248
- String.join "\n" <|
249
- List.concat
250
- [ [ indentS ++ description ++ ":" ]
251
- , sortedByPriority
252
- |> List.filter (\( _, prio, _ ) -> prio > maxPriority - 2)
253
- |> List.map (\( desc, prio, reason ) -> indentS ++ "- " ++ desc ++ "\n" ++ renderQueryFailureWithContext renderQueryFailure (indent + 4) (color && prio >= maxPriority - 1) reason)
254
- ]
255
-
256
- TooManyMatches description matches ->
257
- String.join "\n" <|
258
- List.concat
259
- [ [ indentS ++ description ++ ", but there were multiple successful matches:" ]
260
- , matches
261
- |> List.sortBy (\( _, prio, _ ) -> -prio)
262
- |> List.map (\( desc, _, todo ) -> indentS ++ "- " ++ desc)
263
- , [ ""
264
- , "If that's what you intended, use `ProgramTest.within` to focus in on a portion of"
265
- , "the view that contains only one of the matches."
266
- ]
267
- ]
268
-
269
-
270
- renderSelectorResults : Int -> Colors -> List (Result String String) -> String
271
- renderSelectorResults indent colors results =
272
- let
273
- indentS =
274
- String.repeat indent " "
275
- in
276
- List.map ((++) indentS << renderSelectorResult colors) (upToFirstErr results)
277
- |> String.join "\n"
278
-
279
-
280
- renderSelectorResult : Colors -> Result String String -> String
281
- renderSelectorResult colors result =
282
- case result of
283
- Ok selector ->
284
- String.concat
285
- [ colors.green "✓"
286
- , " "
287
- , colors.bold selector
288
- ]
289
-
290
- Err selector ->
291
- colors.red <|
292
- String.concat
293
- [ "✗"
294
- , " "
295
- , selector
296
- ]
297
-
298
-
299
- renderDescriptionResult : Colors -> Result String String -> String
300
- renderDescriptionResult colors result =
301
- case result of
302
- Ok selector ->
303
- String.concat
304
- [ colors.green "✓"
305
- , " "
306
- , selector
307
- ]
308
-
309
- Err selector ->
310
- String.concat
311
- [ colors.red "✗"
312
- , " "
313
- , selector
314
- ]
315
-
316
-
317
- upToFirstErr : List (Result x a) -> List (Result x a)
318
- upToFirstErr results =
319
- let
320
- step acc results_ =
321
- case results_ of
322
- [] ->
323
- acc
324
-
325
- (Err x) :: _ ->
326
- Err x :: acc
327
-
328
- (Ok a) :: rest ->
329
- step (Ok a :: acc) rest
330
- in
331
- step [] results
332
- |> List.reverse
333
-
334
-
335
- type alias Colors =
336
- { bold : String -> String
337
- , red : String -> String
338
- , green : String -> String
339
- , dim : String -> String
340
- }
341
-
342
-
343
- colorsFor : Bool -> Colors
344
- colorsFor show =
345
- if show then
346
- showColors
347
-
348
- else
349
- noColors
350
-
351
-
352
- showColors : Colors
353
- showColors =
354
- { bold = \s -> String.concat [ "\u{001B}[1m", s, "\u{001B}[0m" ]
355
- , red = \s -> String.concat [ "\u{001B}[31m", s, "\u{001B}[0m" ]
356
- , green = \s -> String.concat [ "\u{001B}[32m", s, "\u{001B}[0m" ]
357
- , dim = \s -> String.concat [ "\u{001B}[2m", s, "\u{001B}[0m" ]
358
- }
359
-
360
-
361
- noColors : Colors
362
- noColors =
363
- { bold = identity
364
- , red = identity
365
- , green = identity
366
- , dim = identity
367
- }
@@ -1,116 +0,0 @@
1
- module ProgramTest.HtmlHighlighter exposing (Attribute, Node(..), NodeF(..), fold, foldWithOriginal, highlight, isNonHiddenElement)
2
-
3
- import Html.Parser
4
-
5
-
6
- type NodeF a
7
- = TextF String
8
- | ElementF String (List Attribute) (List a)
9
- | CommentF String
10
-
11
-
12
- type alias Attribute =
13
- ( String, String )
14
-
15
-
16
- fold : (NodeF a -> a) -> Html.Parser.Node -> a
17
- fold f node =
18
- case node of
19
- Html.Parser.Text text ->
20
- f (TextF text)
21
-
22
- Html.Parser.Element tag attrs children ->
23
- f (ElementF tag attrs (List.map (fold f) children))
24
-
25
- Html.Parser.Comment string ->
26
- f (CommentF string)
27
-
28
-
29
- foldWithOriginal : (NodeF ( Html.Parser.Node, a ) -> a) -> Html.Parser.Node -> a
30
- foldWithOriginal f node =
31
- case node of
32
- Html.Parser.Text text ->
33
- f (TextF text)
34
-
35
- Html.Parser.Element tag attrs children ->
36
- f (ElementF tag attrs (List.map (\child -> ( child, foldWithOriginal f child )) children))
37
-
38
- Html.Parser.Comment string ->
39
- f (CommentF string)
40
-
41
-
42
- type Node
43
- = Text String
44
- | Element String (List Attribute) (List Node)
45
- | Comment String
46
- | Hidden String
47
-
48
-
49
- highlight : (String -> List Attribute -> List Html.Parser.Node -> Bool) -> Html.Parser.Node -> Node
50
- highlight predicate =
51
- foldWithOriginal <|
52
- \node ->
53
- case node of
54
- TextF text ->
55
- Text text
56
-
57
- ElementF tag attrs children ->
58
- let
59
- foldedChildren =
60
- List.map Tuple.second children
61
- in
62
- if predicate tag attrs (List.map Tuple.first children) || List.any isNonHiddenElement foldedChildren then
63
- Element tag attrs foldedChildren
64
-
65
- else
66
- let
67
- bestId =
68
- List.concatMap identity
69
- [ List.filter (Tuple.first >> (==) "id") attrs
70
- , List.filter (Tuple.first >> (==) "name") attrs
71
- , List.filter (Tuple.first >> (==) "class") attrs
72
- ]
73
- |> List.head
74
- |> Maybe.map (\( name, value ) -> " " ++ name ++ "=\"" ++ value ++ "\"")
75
- |> Maybe.withDefault ""
76
-
77
- bestContent =
78
- case foldedChildren of
79
- [] ->
80
- ""
81
-
82
- [ Text single ] ->
83
- truncate 15 (String.trim single)
84
-
85
- _ ->
86
- "..."
87
- in
88
- Hidden ("<" ++ tag ++ bestId ++ ">" ++ bestContent ++ "</" ++ tag ++ ">")
89
-
90
- CommentF string ->
91
- Comment string
92
-
93
-
94
- isNonHiddenElement : Node -> Bool
95
- isNonHiddenElement node =
96
- case node of
97
- Text _ ->
98
- False
99
-
100
- Element _ _ _ ->
101
- True
102
-
103
- Comment _ ->
104
- False
105
-
106
- Hidden _ ->
107
- False
108
-
109
-
110
- truncate : Int -> String -> String
111
- truncate max input =
112
- if String.length input < max - 3 then
113
- input
114
-
115
- else
116
- String.left (max - 3) input ++ "..."
@@ -1,58 +0,0 @@
1
- module ProgramTest.HtmlParserHacks exposing (parse, trimText)
2
-
3
- import Html.Parser
4
- import Parser
5
- import ProgramTest.StringLines as StringLines
6
-
7
-
8
- parse : String -> Result (List Parser.DeadEnd) (List Html.Parser.Node)
9
- parse input =
10
- case Html.Parser.run input of
11
- Ok nodes ->
12
- Ok nodes
13
-
14
- Err errs ->
15
- case fixError errs input of
16
- Nothing ->
17
- Err errs
18
-
19
- Just nodes ->
20
- Ok nodes
21
-
22
-
23
- fixError : List Parser.DeadEnd -> String -> Maybe (List Html.Parser.Node)
24
- fixError errs input =
25
- case errs of
26
- [] ->
27
- Nothing
28
-
29
- { row, col, problem } :: rest ->
30
- case problem of
31
- Parser.UnexpectedChar ->
32
- case StringLines.charAt row (col - 1) input of
33
- Just "<" ->
34
- parse (StringLines.replaceAt row (col - 1) "&lt;" input)
35
- |> Result.toMaybe
36
-
37
- _ ->
38
- fixError rest input
39
-
40
- _ ->
41
- fixError rest input
42
-
43
-
44
- trimText : Html.Parser.Node -> Html.Parser.Node
45
- trimText node =
46
- case node of
47
- Html.Parser.Text string ->
48
- Html.Parser.Text (String.trim string)
49
-
50
- Html.Parser.Element string list nodes ->
51
- Html.Parser.Element string
52
- list
53
- (List.map trimText nodes
54
- |> List.filter ((/=) (Html.Parser.Text ""))
55
- )
56
-
57
- Html.Parser.Comment string ->
58
- Html.Parser.Comment string
@@ -1,73 +0,0 @@
1
- module ProgramTest.HtmlRenderer exposing (render)
2
-
3
- import ProgramTest.HtmlHighlighter as HtmlHighlighter exposing (Node(..))
4
-
5
-
6
- render : (String -> String) -> Int -> List HtmlHighlighter.Node -> String
7
- render colorHidden indent nodes =
8
- case nodes of
9
- [] ->
10
- ""
11
-
12
- (Text text) :: rest ->
13
- case String.trim (String.replace "\n" " " text) of
14
- "" ->
15
- render colorHidden indent rest
16
-
17
- trimmed ->
18
- String.repeat indent " " ++ trimmed ++ "\n" ++ render colorHidden indent rest
19
-
20
- (Comment text) :: rest ->
21
- String.repeat indent " " ++ "<!--" ++ text ++ "-->\n" ++ render colorHidden indent rest
22
-
23
- (Element tag attrs []) :: rest ->
24
- String.repeat indent " "
25
- ++ "<"
26
- ++ tag
27
- ++ renderAttrs attrs
28
- ++ "></"
29
- ++ tag
30
- ++ ">\n"
31
- ++ render colorHidden indent rest
32
-
33
- (Element tag attrs children) :: rest ->
34
- String.repeat indent " "
35
- ++ "<"
36
- ++ tag
37
- ++ renderAttrs attrs
38
- ++ ">\n"
39
- ++ render colorHidden (indent + 4) children
40
- ++ String.repeat indent " "
41
- ++ "</"
42
- ++ tag
43
- ++ ">\n"
44
- ++ render colorHidden indent rest
45
-
46
- (Hidden short) :: rest ->
47
- String.repeat indent " " ++ colorHidden short ++ "\n" ++ render colorHidden indent rest
48
-
49
-
50
- renderAttrs : List HtmlHighlighter.Attribute -> String
51
- renderAttrs attrs =
52
- case attrs of
53
- [] ->
54
- ""
55
-
56
- some ->
57
- " " ++ String.join " " (List.map renderAttr some)
58
-
59
-
60
- renderAttr : ( String, String ) -> String
61
- renderAttr ( name, value ) =
62
- case ( name, value ) of
63
- ( "htmlfor", _ ) ->
64
- "for=\"" ++ value ++ "\""
65
-
66
- ( _, "true" ) ->
67
- name ++ "=true"
68
-
69
- ( _, "false" ) ->
70
- name ++ "=false"
71
-
72
- _ ->
73
- name ++ "=\"" ++ value ++ "\""
@@ -1,30 +0,0 @@
1
- module ProgramTest.Program exposing (Program, renderView)
2
-
3
- import Browser
4
- import Html exposing (Html)
5
- import Test.Html.Query as Query
6
- import Url exposing (Url)
7
-
8
-
9
- {-| Since we can't inspect `Platform.Program`s in Elm,
10
- this type represents the same thing as a record that we can access.
11
-
12
- Note that we also parameterize `effect` and `sub` separately because
13
- `Platform.Cmd` and `Platform.Sub` are not inspectable in Elm.
14
-
15
- -}
16
- type alias Program model msg effect sub =
17
- { update : msg -> model -> ( model, effect )
18
- , view : model -> Html msg
19
- , onUrlRequest : Maybe (Browser.UrlRequest -> msg)
20
- , onUrlChange : Maybe (Url -> msg)
21
- , subscriptions : Maybe (model -> sub)
22
- , withinFocus : Query.Single msg -> Query.Single msg
23
- }
24
-
25
-
26
- renderView : Program model msg effect sub -> model -> Query.Single msg
27
- renderView program model =
28
- program.view model
29
- |> Query.fromHtml
30
- |> program.withinFocus
@@ -1,26 +0,0 @@
1
- module ProgramTest.StringLines exposing (charAt, replaceAt)
2
-
3
-
4
- charAt : Int -> Int -> String -> Maybe String
5
- charAt row col input =
6
- String.lines input
7
- |> List.drop (row - 1)
8
- |> List.head
9
- |> Maybe.map
10
- (String.dropLeft (col - 1)
11
- >> String.left 1
12
- )
13
-
14
-
15
- replaceAt : Int -> Int -> String -> String -> String
16
- replaceAt row col replacement input =
17
- String.lines input
18
- |> List.indexedMap
19
- (\i line ->
20
- if i == (row - 1) then
21
- String.left (col - 1) line ++ replacement ++ String.dropLeft col line
22
-
23
- else
24
- line
25
- )
26
- |> String.join "\n"