wyreframe 0.1.0

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 (117) hide show
  1. package/README.md +123 -0
  2. package/dist/index.d.ts +267 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +195 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +63 -0
  7. package/src/parser/Core/Bounds.mjs +61 -0
  8. package/src/parser/Core/Bounds.res +65 -0
  9. package/src/parser/Core/Grid.mjs +268 -0
  10. package/src/parser/Core/Grid.res +265 -0
  11. package/src/parser/Core/Position.mjs +83 -0
  12. package/src/parser/Core/Position.res +54 -0
  13. package/src/parser/Core/Types.mjs +435 -0
  14. package/src/parser/Core/Types.res +331 -0
  15. package/src/parser/Core/__tests__/Bounds_test.mjs +326 -0
  16. package/src/parser/Core/__tests__/Bounds_test.res +412 -0
  17. package/src/parser/Core/__tests__/Grid_test.mjs +322 -0
  18. package/src/parser/Core/__tests__/Grid_test.res +319 -0
  19. package/src/parser/Core/__tests__/Types_test.mjs +614 -0
  20. package/src/parser/Core/__tests__/Types_test.res +650 -0
  21. package/src/parser/Detector/BoxTracer.mjs +302 -0
  22. package/src/parser/Detector/BoxTracer.res +374 -0
  23. package/src/parser/Detector/HierarchyBuilder.mjs +158 -0
  24. package/src/parser/Detector/HierarchyBuilder.res +315 -0
  25. package/src/parser/Detector/ShapeDetector.mjs +134 -0
  26. package/src/parser/Detector/ShapeDetector.res +236 -0
  27. package/src/parser/Detector/__tests__/BoxTracer_test.mjs +70 -0
  28. package/src/parser/Detector/__tests__/BoxTracer_test.res +92 -0
  29. package/src/parser/Detector/__tests__/HierarchyBuilder_test.mjs +489 -0
  30. package/src/parser/Detector/__tests__/HierarchyBuilder_test.res +849 -0
  31. package/src/parser/Detector/__tests__/ShapeDetector_test.mjs +377 -0
  32. package/src/parser/Detector/__tests__/ShapeDetector_test.res +563 -0
  33. package/src/parser/Errors/ErrorContext.mjs +106 -0
  34. package/src/parser/Errors/ErrorContext.res +191 -0
  35. package/src/parser/Errors/ErrorMessages.mjs +289 -0
  36. package/src/parser/Errors/ErrorMessages.res +303 -0
  37. package/src/parser/Errors/ErrorTypes.mjs +105 -0
  38. package/src/parser/Errors/ErrorTypes.res +169 -0
  39. package/src/parser/Interactions/InteractionMerger.mjs +266 -0
  40. package/src/parser/Interactions/InteractionMerger.res +450 -0
  41. package/src/parser/Interactions/InteractionParser.mjs +88 -0
  42. package/src/parser/Interactions/InteractionParser.res +127 -0
  43. package/src/parser/Interactions/SimpleInteractionParser.mjs +278 -0
  44. package/src/parser/Interactions/SimpleInteractionParser.res +262 -0
  45. package/src/parser/Interactions/__tests__/InteractionMerger_test.mjs +576 -0
  46. package/src/parser/Interactions/__tests__/InteractionMerger_test.res +646 -0
  47. package/src/parser/Parser.gen.tsx +96 -0
  48. package/src/parser/Parser.mjs +212 -0
  49. package/src/parser/Parser.res +481 -0
  50. package/src/parser/Scanner/__tests__/Grid_manual.mjs +214 -0
  51. package/src/parser/Scanner/__tests__/Grid_manual.res +141 -0
  52. package/src/parser/Semantic/ASTBuilder.mjs +197 -0
  53. package/src/parser/Semantic/ASTBuilder.res +288 -0
  54. package/src/parser/Semantic/AlignmentCalc.mjs +41 -0
  55. package/src/parser/Semantic/AlignmentCalc.res +104 -0
  56. package/src/parser/Semantic/Elements/ButtonParser.mjs +58 -0
  57. package/src/parser/Semantic/Elements/ButtonParser.res +131 -0
  58. package/src/parser/Semantic/Elements/CheckboxParser.mjs +58 -0
  59. package/src/parser/Semantic/Elements/CheckboxParser.res +79 -0
  60. package/src/parser/Semantic/Elements/CodeTextParser.mjs +50 -0
  61. package/src/parser/Semantic/Elements/CodeTextParser.res +111 -0
  62. package/src/parser/Semantic/Elements/ElementParser.mjs +15 -0
  63. package/src/parser/Semantic/Elements/ElementParser.res +83 -0
  64. package/src/parser/Semantic/Elements/EmphasisParser.mjs +46 -0
  65. package/src/parser/Semantic/Elements/EmphasisParser.res +67 -0
  66. package/src/parser/Semantic/Elements/InputParser.mjs +41 -0
  67. package/src/parser/Semantic/Elements/InputParser.res +97 -0
  68. package/src/parser/Semantic/Elements/LinkParser.mjs +60 -0
  69. package/src/parser/Semantic/Elements/LinkParser.res +156 -0
  70. package/src/parser/Semantic/Elements/TextParser.mjs +19 -0
  71. package/src/parser/Semantic/Elements/TextParser.res +42 -0
  72. package/src/parser/Semantic/Elements/__tests__/ButtonParser_test.mjs +189 -0
  73. package/src/parser/Semantic/Elements/__tests__/ButtonParser_test.res +257 -0
  74. package/src/parser/Semantic/Elements/__tests__/CheckboxParser_test.mjs +202 -0
  75. package/src/parser/Semantic/Elements/__tests__/CheckboxParser_test.res +250 -0
  76. package/src/parser/Semantic/Elements/__tests__/CodeTextParser_manual.mjs +293 -0
  77. package/src/parser/Semantic/Elements/__tests__/CodeTextParser_manual.res +134 -0
  78. package/src/parser/Semantic/Elements/__tests__/InputParser_test.mjs +253 -0
  79. package/src/parser/Semantic/Elements/__tests__/InputParser_test.res +304 -0
  80. package/src/parser/Semantic/Elements/__tests__/LinkParser_test.mjs +289 -0
  81. package/src/parser/Semantic/Elements/__tests__/LinkParser_test.res +402 -0
  82. package/src/parser/Semantic/Elements/__tests__/TextParser_test.mjs +149 -0
  83. package/src/parser/Semantic/Elements/__tests__/TextParser_test.res +167 -0
  84. package/src/parser/Semantic/ParserRegistry.mjs +82 -0
  85. package/src/parser/Semantic/ParserRegistry.res +145 -0
  86. package/src/parser/Semantic/SemanticParser.mjs +850 -0
  87. package/src/parser/Semantic/SemanticParser.res +1368 -0
  88. package/src/parser/Semantic/__tests__/ASTBuilder_test.mjs +187 -0
  89. package/src/parser/Semantic/__tests__/ASTBuilder_test.res +192 -0
  90. package/src/parser/Semantic/__tests__/ParserRegistry_test.mjs +154 -0
  91. package/src/parser/Semantic/__tests__/ParserRegistry_test.res +191 -0
  92. package/src/parser/Semantic/__tests__/SemanticParser_integration_test.mjs +768 -0
  93. package/src/parser/Semantic/__tests__/SemanticParser_integration_test.res +1069 -0
  94. package/src/parser/Semantic/__tests__/SemanticParser_manual.mjs +1329 -0
  95. package/src/parser/Semantic/__tests__/SemanticParser_manual.res +544 -0
  96. package/src/parser/TestMain.mjs +21 -0
  97. package/src/parser/TestMain.res +14 -0
  98. package/src/parser/TextExtractor.mjs +179 -0
  99. package/src/parser/TextExtractor.res +264 -0
  100. package/src/parser/__tests__/GridScanner_integration.test.mjs +632 -0
  101. package/src/parser/__tests__/GridScanner_integration.test.res +816 -0
  102. package/src/parser/__tests__/Performance.test.mjs +244 -0
  103. package/src/parser/__tests__/Performance.test.res +371 -0
  104. package/src/parser/__tests__/PerformanceFixtures.mjs +200 -0
  105. package/src/parser/__tests__/PerformanceFixtures.res +284 -0
  106. package/src/parser/__tests__/WyreframeParser_integration.test.mjs +770 -0
  107. package/src/parser/__tests__/WyreframeParser_integration.test.res +1008 -0
  108. package/src/parser/__tests__/fixtures/alignment-test.txt +9 -0
  109. package/src/parser/__tests__/fixtures/all-elements.txt +16 -0
  110. package/src/parser/__tests__/fixtures/login-scene.txt +17 -0
  111. package/src/parser/__tests__/fixtures/multi-scene.txt +25 -0
  112. package/src/parser/__tests__/fixtures/nested-boxes.txt +15 -0
  113. package/src/parser/__tests__/fixtures/simple-box.txt +5 -0
  114. package/src/parser/__tests__/fixtures/with-dividers.txt +14 -0
  115. package/src/renderer/Renderer.gen.tsx +32 -0
  116. package/src/renderer/Renderer.mjs +391 -0
  117. package/src/renderer/Renderer.res +558 -0
@@ -0,0 +1,191 @@
1
+ // ParserRegistry_test.res
2
+ // Unit tests for ParserRegistry module
3
+
4
+ open Vitest
5
+
6
+ describe("ParserRegistry", t => {
7
+ describe("make", t => {
8
+ test("creates an empty registry", t => {
9
+ let registry = ParserRegistry.make()
10
+ t->expect(registry.parsers->Array.length)->Expect.toBe(0)
11
+ })
12
+ })
13
+
14
+ describe("register", t => {
15
+ test("adds a parser to the registry", t => {
16
+ let registry = ParserRegistry.make()
17
+ let parser = TextParser.make()
18
+
19
+ registry->ParserRegistry.register(parser)
20
+
21
+ t->expect(registry.parsers->Array.length)->Expect.toBe(1)
22
+ })
23
+
24
+ test("sorts parsers by priority (descending)", t => {
25
+ let registry = ParserRegistry.make()
26
+
27
+ // Register parsers in random order
28
+ registry->ParserRegistry.register(TextParser.make()) // priority 1
29
+ registry->ParserRegistry.register(InputParser.make()) // priority 90
30
+ registry->ParserRegistry.register(CheckboxParser.make()) // priority 85
31
+ registry->ParserRegistry.register(LinkParser.make()) // priority 80
32
+
33
+ // Verify they are sorted by priority descending
34
+ t->expect(Array.getUnsafe(registry.parsers, 0).priority)->Expect.toBe(90) // InputParser
35
+ t->expect(Array.getUnsafe(registry.parsers, 1).priority)->Expect.toBe(85) // CheckboxParser
36
+ t->expect(Array.getUnsafe(registry.parsers, 2).priority)->Expect.toBe(80) // LinkParser
37
+ t->expect(Array.getUnsafe(registry.parsers, 3).priority)->Expect.toBe(1) // TextParser
38
+ })
39
+
40
+ test("maintains sort order when registering multiple parsers", t => {
41
+ let registry = ParserRegistry.make()
42
+
43
+ registry->ParserRegistry.register(LinkParser.make()) // priority 80
44
+ registry->ParserRegistry.register(InputParser.make()) // priority 90
45
+ registry->ParserRegistry.register(TextParser.make()) // priority 1
46
+
47
+ t->expect(Array.getUnsafe(registry.parsers, 0).priority)->Expect.toBe(90)
48
+ t->expect(Array.getUnsafe(registry.parsers, 1).priority)->Expect.toBe(80)
49
+ t->expect(Array.getUnsafe(registry.parsers, 2).priority)->Expect.toBe(1)
50
+ })
51
+ })
52
+
53
+ describe("parse", t => {
54
+ let testPosition = Types.Position.make(0, 0)
55
+ let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=10, ~right=10)
56
+
57
+ test("tries parsers in priority order", t => {
58
+ let registry = ParserRegistry.make()
59
+ registry->ParserRegistry.register(InputParser.make())
60
+ registry->ParserRegistry.register(TextParser.make())
61
+
62
+ // Should match InputParser (higher priority)
63
+ let result = registry->ParserRegistry.parse("#email", testPosition, testBounds)
64
+
65
+ switch result {
66
+ | Types.Input({id}) => t->expect(id)->Expect.toBe("email")
67
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Input element
68
+ }
69
+ })
70
+
71
+ test("falls back to lower priority parser if higher priority fails", t => {
72
+ let registry = ParserRegistry.make()
73
+ registry->ParserRegistry.register(InputParser.make())
74
+ registry->ParserRegistry.register(TextParser.make())
75
+
76
+ // Should fall back to TextParser (InputParser won't match)
77
+ let result = registry->ParserRegistry.parse("plain text", testPosition, testBounds)
78
+
79
+ switch result {
80
+ | Types.Text({content}) => t->expect(content)->Expect.toBe("plain text")
81
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Text element
82
+ }
83
+ })
84
+
85
+ test("parses checkbox content correctly", t => {
86
+ let registry = ParserRegistry.make()
87
+ registry->ParserRegistry.register(CheckboxParser.make())
88
+ registry->ParserRegistry.register(TextParser.make())
89
+
90
+ let result = registry->ParserRegistry.parse("[x] Accept terms", testPosition, testBounds)
91
+
92
+ switch result {
93
+ | Types.Checkbox({checked, label}) => {
94
+ t->expect(checked)->Expect.toBe(true)
95
+ t->expect(label)->Expect.toBe("Accept terms")
96
+ }
97
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Checkbox element
98
+ }
99
+ })
100
+
101
+ test("parses link content correctly", t => {
102
+ let registry = ParserRegistry.make()
103
+ registry->ParserRegistry.register(LinkParser.make())
104
+ registry->ParserRegistry.register(TextParser.make())
105
+
106
+ let result = registry->ParserRegistry.parse("\"Click Here\"", testPosition, testBounds)
107
+
108
+ switch result {
109
+ | Types.Link({text, id}) => {
110
+ t->expect(text)->Expect.toBe("Click Here")
111
+ t->expect(id)->Expect.toBe("click-here")
112
+ }
113
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
114
+ }
115
+ })
116
+
117
+ test("returns text element as fallback when no parser matches", t => {
118
+ // Create registry without TextParser to test fallback
119
+ let registry = ParserRegistry.make()
120
+ registry->ParserRegistry.register(InputParser.make())
121
+
122
+ let result = registry->ParserRegistry.parse("unmatched content", testPosition, testBounds)
123
+
124
+ switch result {
125
+ | Types.Text({content}) => t->expect(content)->Expect.toBe("unmatched content")
126
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected fallback Text element
127
+ }
128
+ })
129
+ })
130
+
131
+ describe("makeDefault", t => {
132
+ test("creates registry with built-in parsers", t => {
133
+ let registry = ParserRegistry.makeDefault()
134
+
135
+ // Should have at least InputParser, CheckboxParser, LinkParser, TextParser
136
+ t->expect(registry.parsers->Array.length)->Expect.Int.toBeGreaterThanOrEqual(4)
137
+ })
138
+
139
+ test("default registry can parse input fields", t => {
140
+ let registry = ParserRegistry.makeDefault()
141
+ let testPosition = Types.Position.make(5, 10)
142
+ let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=20, ~right=30)
143
+
144
+ let result = registry->ParserRegistry.parse("#password", testPosition, testBounds)
145
+
146
+ switch result {
147
+ | Types.Input({id}) => t->expect(id)->Expect.toBe("password")
148
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Input element
149
+ }
150
+ })
151
+
152
+ test("default registry can parse checkboxes", t => {
153
+ let registry = ParserRegistry.makeDefault()
154
+ let testPosition = Types.Position.make(0, 0)
155
+ let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=10, ~right=10)
156
+
157
+ let result = registry->ParserRegistry.parse("[ ] Unchecked", testPosition, testBounds)
158
+
159
+ switch result {
160
+ | Types.Checkbox({checked}) => t->expect(checked)->Expect.toBe(false)
161
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Checkbox element
162
+ }
163
+ })
164
+
165
+ test("default registry can parse links", t => {
166
+ let registry = ParserRegistry.makeDefault()
167
+ let testPosition = Types.Position.make(0, 0)
168
+ let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=10, ~right=10)
169
+
170
+ let result = registry->ParserRegistry.parse("\"Sign Up\"", testPosition, testBounds)
171
+
172
+ switch result {
173
+ | Types.Link({text}) => t->expect(text)->Expect.toBe("Sign Up")
174
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
175
+ }
176
+ })
177
+
178
+ test("default registry falls back to text for unrecognized content", t => {
179
+ let registry = ParserRegistry.makeDefault()
180
+ let testPosition = Types.Position.make(0, 0)
181
+ let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=10, ~right=10)
182
+
183
+ let result = registry->ParserRegistry.parse("Random text", testPosition, testBounds)
184
+
185
+ switch result {
186
+ | Types.Text({content}) => t->expect(content)->Expect.toBe("Random text")
187
+ | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Text element
188
+ }
189
+ })
190
+ })
191
+ })