ranger-compiler 3.5.0 → 3.5.2
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.
- package/CHANGELOG.md +1160 -19
- package/LICENSE +3 -1
- package/README.md +124 -29
- package/dist/Lang.rgr +1188 -290
- package/dist/api.d.ts +2343 -879
- package/dist/api.js +79924 -56922
- package/dist/lib/JSON.rgr +102 -91
- package/dist/lib/Shell.rgr +4 -4
- package/dist/lib/apple/AppleToolchain.rgr +4 -4
- package/dist/lib/apple/README.md +5 -4
- package/dist/lib/apple/apple_test.rgr +1 -1
- package/dist/lib/core/README.md +1 -1
- package/dist/lib/evg/EVG.rgr +12 -0
- package/dist/lib/evg/EVGA11yFromTree.rgr +302 -0
- package/dist/lib/evg/EVGA11yTree.rgr +894 -0
- package/dist/lib/evg/EVGBox.rgr +267 -0
- package/dist/lib/evg/EVGBoxShorthandTest.rgr +220 -0
- package/dist/lib/evg/EVGCodepoint.rgr +316 -0
- package/dist/lib/evg/EVGColor.rgr +700 -0
- package/dist/lib/evg/EVGCommands.rgr +177 -0
- package/dist/lib/evg/EVGComponent.rgr +331 -0
- package/dist/lib/evg/EVGComponentTest.rgr +387 -0
- package/dist/lib/evg/EVGConnector.rgr +541 -0
- package/dist/lib/evg/EVGConnectorTest.rgr +306 -0
- package/dist/lib/evg/EVGDisplayList.rgr +4186 -0
- package/dist/lib/evg/EVGEasing.rgr +370 -0
- package/dist/lib/evg/EVGEffectTest.rgr +253 -0
- package/dist/lib/evg/EVGElement.rgr +4914 -0
- package/dist/lib/evg/EVGFixedTest.rgr +289 -0
- package/dist/lib/evg/EVGFlexRulesTest.rgr +317 -0
- package/dist/lib/evg/EVGFlexWrapTest.rgr +246 -0
- package/dist/lib/evg/EVGFling.rgr +244 -0
- package/dist/lib/evg/EVGFocus.rgr +400 -0
- package/dist/lib/evg/EVGFocusTest.rgr +399 -0
- package/dist/lib/evg/EVGGradient.rgr +322 -0
- package/dist/lib/evg/EVGGrapheme.rgr +190 -0
- package/dist/lib/evg/EVGGrid.rgr +975 -0
- package/dist/lib/evg/EVGHitTest.rgr +208 -0
- package/dist/lib/evg/EVGHoles.rgr +294 -0
- package/dist/lib/evg/EVGHostMeasurerTest.rgr +281 -0
- package/dist/lib/evg/EVGHostTextMeasurer.rgr +331 -0
- package/dist/lib/evg/EVGHostTree.rgr +834 -0
- package/dist/lib/evg/EVGHostTreeTest.rgr +447 -0
- package/dist/lib/evg/EVGImageDecode.rgr +117 -0
- package/dist/lib/evg/EVGImageMeasurer.rgr +86 -0
- package/dist/lib/evg/EVGInspect.rgr +883 -0
- package/dist/lib/evg/EVGInvalidateTest.rgr +432 -0
- package/dist/lib/evg/EVGJsonTest.rgr +535 -0
- package/dist/lib/evg/EVGLayout.rgr +4220 -0
- package/dist/lib/evg/EVGMeasure.rgr +1267 -0
- package/dist/lib/evg/EVGOverlayTest.rgr +626 -0
- package/dist/lib/evg/EVGPatch.rgr +1721 -0
- package/dist/lib/evg/EVGPatchTest.rgr +692 -0
- package/dist/lib/evg/EVGPopoverTest.rgr +395 -0
- package/dist/lib/evg/EVGReconcile.rgr +226 -0
- package/dist/lib/evg/EVGReconcileTest.rgr +421 -0
- package/dist/lib/evg/EVGReject.rgr +126 -0
- package/dist/lib/evg/EVGRelayoutTest.rgr +375 -0
- package/dist/lib/evg/EVGRtlLayoutTest.rgr +319 -0
- package/dist/lib/evg/EVGRuler.rgr +232 -0
- package/dist/lib/evg/EVGRulerTest.rgr +172 -0
- package/dist/lib/evg/EVGSelectChrome.rgr +178 -0
- package/dist/lib/evg/EVGStyleCacheTest.rgr +419 -0
- package/dist/lib/evg/EVGStyleSheet.rgr +2148 -0
- package/dist/lib/evg/EVGStyleStateTest.rgr +407 -0
- package/dist/lib/evg/EVGStyleVarTest.rgr +471 -0
- package/dist/lib/evg/EVGText.rgr +105 -0
- package/dist/lib/evg/EVGTextEngine.rgr +536 -0
- package/dist/lib/evg/EVGTextMeasurer.rgr +720 -0
- package/dist/lib/evg/EVGTimingTest.rgr +1417 -0
- package/dist/lib/evg/EVGToolbar.rgr +1369 -0
- package/dist/lib/evg/EVGTransition.rgr +728 -0
- package/dist/lib/evg/EVGTreeJson.rgr +721 -0
- package/dist/lib/evg/EVGUnit.rgr +554 -0
- package/dist/lib/evg/EVGViewportUnitTest.rgr +236 -0
- package/dist/lib/evg/EvgApp.rgr +189 -0
- package/dist/lib/evg/EvgBitmapTracer.rgr +4277 -0
- package/dist/lib/evg/EvgBitmapTracerTest.rgr +2119 -0
- package/dist/lib/evg/EvgHost.rgr +451 -0
- package/dist/lib/evg/EvgTest.rgr +91 -0
- package/dist/lib/evg/EvgTraceColor.rgr +236 -0
- package/dist/lib/evg/EvgTraceCurve.rgr +648 -0
- package/dist/lib/evg/EvgTraceFit.rgr +767 -0
- package/dist/lib/evg/EvgTracePath.rgr +435 -0
- package/dist/lib/evg/EvgTraceTypes.rgr +559 -0
- package/dist/lib/evg/EvgViewport.rgr +313 -0
- package/dist/lib/evg/FxDemoDoc.rgr +185 -0
- package/dist/lib/evg/HOSTS.md +227 -0
- package/dist/lib/evg/ISSUES.md +835 -0
- package/dist/lib/evg/PLAN_ACCESSIBILITY.md +650 -0
- package/dist/lib/evg/PLAN_CSS_LAYOUT_AND_FONTS.md +1124 -0
- package/dist/lib/evg/PLAN_EFFECTS.md +431 -0
- package/dist/lib/evg/PLAN_EVG.md +518 -0
- package/dist/lib/evg/PLAN_EVG_RENDERER.md +1674 -0
- package/dist/lib/evg/PLAN_INSPECTOR.md +788 -0
- package/dist/lib/evg/PLAN_LINKS_AND_FORMS.md +157 -0
- package/dist/lib/evg/PLAN_NATIVE_HOSTS.md +671 -0
- package/dist/lib/evg/PLAN_VECTOR_IR.md +664 -0
- package/dist/lib/evg/PLAN_VIEW_TRANSFORM.md +322 -0
- package/dist/lib/evg/PathBuilder.rgr +333 -0
- package/dist/lib/evg/README.md +1236 -0
- package/dist/lib/evg/SPEC.md +1252 -0
- package/dist/lib/evg/SVGPathParser.rgr +1199 -0
- package/dist/lib/evg/SvgParser.rgr +1736 -0
- package/dist/lib/evg/TODO_EVG_RENDERER.md +595 -0
- package/dist/lib/evg/VectorShapes.rgr +331 -0
- package/dist/lib/evg/VectorStroke.rgr +107 -0
- package/dist/lib/evg/VectorViewBox.rgr +380 -0
- package/dist/lib/evg/agent/README.md +290 -0
- package/dist/lib/evg/agent/evg_agent.rgr +899 -0
- package/dist/lib/evg/agent/fixtures/broken.evg.json +7 -0
- package/dist/lib/evg/agent/fixtures/card.evg.json +9 -0
- package/dist/lib/evg/agent/fixtures/connector.css +63 -0
- package/dist/lib/evg/agent/fixtures/connector.evg.json +14 -0
- package/dist/lib/evg/agent/fixtures/drawn.evg.json +129 -0
- package/dist/lib/evg/agent/fixtures/gradient.evg.json +4 -0
- package/dist/lib/evg/agent/fixtures/popover.css +99 -0
- package/dist/lib/evg/agent/fixtures/popover.evg.json +30 -0
- package/dist/lib/evg/agent/roundtrip.sh +74 -0
- package/dist/lib/evg/agent/smoke.sh +230 -0
- package/dist/lib/evg/android/README.md +97 -0
- package/dist/lib/evg/android/androidstubs/AndroidStubs.kt +175 -0
- package/dist/lib/evg/android/androidstubs/Annotation.kt +10 -0
- package/dist/lib/evg/android/androidstubs/App.kt +30 -0
- package/dist/lib/evg/android/androidstubs/Content.kt +41 -0
- package/dist/lib/evg/android/androidstubs/ContentRes.kt +12 -0
- package/dist/lib/evg/android/androidstubs/InputMethod.kt +46 -0
- package/dist/lib/evg/android/androidstubs/Net.kt +6 -0
- package/dist/lib/evg/android/androidstubs/Os.kt +30 -0
- package/dist/lib/evg/android/androidstubs/Util.kt +15 -0
- package/dist/lib/evg/android/androidstubs/View.kt +113 -0
- package/dist/lib/evg/android/androidstubs/Widget.kt +16 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidEvgSurface.kt +323 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidTextMeasurer.kt +56 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/RippleEffect.kt +262 -0
- package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtEvgSurface.kt +238 -0
- package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtTextMeasurer.kt +85 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgEngineThread.kt +115 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgPainter.kt +231 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgSurface.kt +117 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/RecordingSurface.kt +94 -0
- package/dist/lib/evg/apple/README.md +128 -0
- package/dist/lib/evg/apple/Sources/CoreGraphicsEvgSurface.swift +329 -0
- package/dist/lib/evg/apple/Sources/CoreTextMeasurer.swift +70 -0
- package/dist/lib/evg/apple/Sources/EvgEngineQueue.swift +105 -0
- package/dist/lib/evg/apple/Sources/EvgPainter.swift +225 -0
- package/dist/lib/evg/apple/Sources/EvgSurface.swift +163 -0
- package/dist/lib/evg/apple/Sources/RecordingSurface.swift +110 -0
- package/dist/lib/evg/bench/EvgLayoutBench.rgr +34 -0
- package/dist/lib/evg/bench/README.md +64 -0
- package/dist/lib/evg/bench/layout-bench.mjs +316 -0
- package/dist/lib/evg/bench/layout-cases.mjs +510 -0
- package/dist/lib/evg/bench/layout-conformance.mjs +254 -0
- package/dist/lib/evg/bin/.gitignore +17 -0
- package/dist/lib/evg/evg_test.rgr +313 -0
- package/dist/lib/evg/gl/README.md +198 -0
- package/dist/lib/evg/gl/a11y-paint-check.mjs +73 -0
- package/dist/lib/evg/gl/blur-check.mjs +399 -0
- package/dist/lib/evg/gl/boxmodel.json +1 -0
- package/dist/lib/evg/gl/demo.html +46 -0
- package/dist/lib/evg/gl/effect-presets.css +285 -0
- package/dist/lib/evg/gl/effect-presets.js +63 -0
- package/dist/lib/evg/gl/effect-shots.mjs +135 -0
- package/dist/lib/evg/gl/evg-a11y.js +566 -0
- package/dist/lib/evg/gl/evg-binary.js +160 -0
- package/dist/lib/evg/gl/evg-engine.js +296 -0
- package/dist/lib/evg/gl/evg-fx.js +237 -0
- package/dist/lib/evg/gl/evg-gestures.js +209 -0
- package/dist/lib/evg/gl/evg-list.js +167 -0
- package/dist/lib/evg/gl/evg-measure.js +186 -0
- package/dist/lib/evg/gl/evg-textinput.js +303 -0
- package/dist/lib/evg/gl/evg-view.js +144 -0
- package/dist/lib/evg/gl/evg-webgl.js +3942 -0
- package/dist/lib/evg/gl/fx-check.mjs +998 -0
- package/dist/lib/evg/gl/fx-demo.html +166 -0
- package/dist/lib/evg/gl/fx-demo.js +2 -0
- package/dist/lib/evg/gl/fx-serve.mjs +47 -0
- package/dist/lib/evg/gl/gestures-check.mjs +189 -0
- package/dist/lib/evg/gl/list-binary-check.mjs +152 -0
- package/dist/lib/evg/gl/measure-check.mjs +135 -0
- package/dist/lib/evg/gl/rotation-check.mjs +207 -0
- package/dist/lib/evg/gl/shift-check.mjs +113 -0
- package/dist/lib/evg/gl/stroke-check.mjs +168 -0
- package/dist/lib/evg/gl/text-snap-check.mjs +139 -0
- package/dist/lib/evg/gl/view-check.mjs +343 -0
- package/dist/lib/evg/gl/view-policy-check.mjs +184 -0
- package/dist/lib/evg/html/evg-dom.js +318 -0
- package/dist/lib/evg/html/evg-html.js +600 -0
- package/dist/lib/evg/inspect/README.md +415 -0
- package/dist/lib/evg/inspect/browser-smoke.mjs +115 -0
- package/dist/lib/evg/inspect/evg-inspect.js +947 -0
- package/dist/lib/evg/inspect/shots/css.png +0 -0
- package/dist/lib/evg/inspect/shots/dashboard.png +0 -0
- package/dist/lib/evg/inspect/shots/pptx-slide.png +0 -0
- package/dist/lib/evg/inspect/shots/state.png +0 -0
- package/dist/lib/evg/inspect/shots.mjs +226 -0
- package/dist/lib/evg/oracle/css-blur.json +576 -0
- package/dist/lib/evg/oracle/css-box.json +157 -0
- package/dist/lib/evg/oracle/css-timing.json +709 -0
- package/dist/lib/evg/oracle/css_blur_oracle.mjs +529 -0
- package/dist/lib/evg/oracle/css_box_oracle.mjs +106 -0
- package/dist/lib/evg/oracle/css_timing_oracle.mjs +389 -0
- package/dist/lib/evg/original/EVGColor.clj +310 -0
- package/dist/lib/evg/original/EVGColorContext.rgr +178 -0
- package/dist/lib/evg/original/SVGPath.rgr +627 -0
- package/dist/lib/evg/original/Vec2.crgr +103 -0
- package/dist/lib/evg/ranger.json +9 -0
- package/dist/lib/evg/showcase/README.md +246 -0
- package/dist/lib/evg/showcase/assets/emblem.svg +30 -0
- package/dist/lib/evg/showcase/assets/rosette.svg +22 -0
- package/dist/lib/evg/showcase/build.mjs +651 -0
- package/dist/lib/evg/showcase/pages/album.tsx +30 -0
- package/dist/lib/evg/showcase/pages/boxmodel.tsx +37 -0
- package/dist/lib/evg/showcase/pages/cards.tsx +41 -0
- package/dist/lib/evg/showcase/pages/chart_api.tsx +170 -0
- package/dist/lib/evg/showcase/pages/charts.tsx +219 -0
- package/dist/lib/evg/showcase/pages/drawing.tsx +160 -0
- package/dist/lib/evg/showcase/pages/emoji.tsx +91 -0
- package/dist/lib/evg/showcase/pages/flex.tsx +46 -0
- package/dist/lib/evg/showcase/pages/more.tsx +332 -0
- package/dist/lib/evg/showcase/pages/plots.tsx +262 -0
- package/dist/lib/evg/showcase/pages/svg.tsx +63 -0
- package/dist/lib/evg/showcase/pages/tables.tsx +209 -0
- package/dist/lib/evg/showcase/pages/typography.tsx +43 -0
- package/dist/lib/evg/showcase/pages/units.tsx +35 -0
- package/dist/lib/evg/showcase/pages/variants.tsx +233 -0
- package/dist/lib/evg/showcase/pages/vector.tsx +75 -0
- package/dist/lib/evg/showcase/pages/views.tsx +223 -0
- package/dist/lib/evg/showcase/tests/chart_api_smoke.mjs +339 -0
- package/dist/lib/evg/showcase/tests/gl_smoke.mjs +125 -0
- package/dist/lib/evg/showcase/themes/chart_api-default.css +15 -0
- package/dist/lib/evg/showcase/themes/charts-default.css +29 -0
- package/dist/lib/evg/showcase/themes/drawing-default.css +35 -0
- package/dist/lib/evg/showcase/themes/more-default.css +128 -0
- package/dist/lib/evg/showcase/themes/plots-default.css +18 -0
- package/dist/lib/evg/showcase/themes/showcase.css +508 -0
- package/dist/lib/evg/showcase/themes/tables-default.css +123 -0
- package/dist/lib/evg/showcase/themes/variants-default.css +15 -0
- package/dist/lib/evg/showcase/themes/views-default.css +15 -0
- package/dist/lib/evg/tools/bench_vs_potrace.mjs +290 -0
- package/dist/lib/evg/tools/evg_image_tool.rgr +488 -0
- package/dist/lib/evg/tools/evg_trace_bench.rgr +114 -0
- package/dist/lib/evg/tools/evg_trace_cli.rgr +662 -0
- package/dist/lib/evg/tools/evg_trace_cpp_bench.rgr +83 -0
- package/dist/lib/evg/tools/run_trace_bench.sh +74 -0
- package/dist/lib/evg/tools/run_trace_cli_smoke.sh +128 -0
- package/dist/lib/evg/web/responsive/EvgResponsiveCheck.rgr +271 -0
- package/dist/lib/evg/web/responsive/EvgResponsiveDemo.rgr +531 -0
- package/dist/lib/evg/web/responsive/README.md +97 -0
- package/dist/lib/evg/web/responsive/build.mjs +90 -0
- package/dist/lib/evg/web/responsive/dom-check.mjs +169 -0
- package/dist/lib/evg/web/responsive/index.html +177 -0
- package/dist/lib/evg/web/responsive/smoke.mjs +221 -0
- package/dist/lib/evg/web/tools/assets-client.mjs +95 -0
- package/dist/lib/evg/web/tools/boot-bench.mjs +189 -0
- package/dist/lib/evg/web/tools/inline-assets.mjs +119 -0
- package/dist/lib/evg/web/tools/minify.mjs +60 -0
- package/dist/lib/evg/web/tracer/build.mjs +87 -0
- package/dist/lib/evg/web/tracer/index.html +2805 -0
- package/dist/lib/evg/web/tracer/sample.png +0 -0
- package/dist/lib/evg/web/tracer/smoke.mjs +1162 -0
- package/dist/lib/evgr/Cargo.lock +21 -0
- package/dist/lib/evgr/Cargo.toml +19 -0
- package/dist/lib/evgr/README.md +140 -0
- package/dist/lib/evgr/bench/NativeBench.rgr +246 -0
- package/dist/lib/evgr/bench/compare.mjs +252 -0
- package/dist/lib/evgr/bench/speed.mjs +277 -0
- package/dist/lib/evgr/bin/.gitignore +3 -0
- package/dist/lib/evgr/src/bin/bench.rs +106 -0
- package/dist/lib/evgr/src/bin/smoke.rs +13 -0
- package/dist/lib/evgr/src/grid.rs +730 -0
- package/dist/lib/evgr/src/lib.rs +1003 -0
- package/dist/lib/evgr/src/style.rs +468 -0
- package/dist/lib/evgr/src/text.rs +83 -0
- package/dist/lib/image/BitReader.rgr +171 -0
- package/dist/lib/image/Buffer.rgr +173 -0
- package/dist/lib/image/DCT.rgr +283 -0
- package/dist/lib/image/Deflate.rgr +339 -0
- package/dist/lib/image/HuffmanDecoder.rgr +181 -0
- package/dist/lib/image/ImageBuffer.rgr +706 -0
- package/dist/lib/image/JPEGDecoder.rgr +808 -0
- package/dist/lib/image/PNGDecoder.rgr +544 -0
- package/dist/lib/image/PNGEncoder.rgr +388 -0
- package/dist/lib/image/PPMImage.rgr +224 -0
- package/dist/lib/image/ProgressiveJPEGDecoder.rgr +1154 -0
- package/dist/lib/image/README.md +33 -0
- package/dist/lib/image/RasterBuffer.rgr +294 -0
- package/dist/lib/image/VP8BoolDecoder.rgr +163 -0
- package/dist/lib/image/WebPDecoder.rgr +433 -0
- package/dist/lib/image/WebPLossless.rgr +1035 -0
- package/dist/lib/image/WebPLossy.rgr +1929 -0
- package/dist/lib/image/ranger.json +9 -0
- package/dist/lib/image/testdata/webp/anim_2f_24x16.webp +0 -0
- package/dist/lib/image/testdata/webp/fixtures.txt +33 -0
- package/dist/lib/image/testdata/webp/gen_fixtures.py +261 -0
- package/dist/lib/image/testdata/webp/ll_1x1.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_alpha_29x21.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_gradient_64x64.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_meta_32x32.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_noise_17x9.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal11_23x11.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal2_19x7.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal40_16x16.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal4_13x5.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_photo_40x30.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_predictors_64x32.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_1x1.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f0_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f1_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f2_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f3_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f0_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f1_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f2_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f3_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alpha_33x17.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_exif_15x11.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_i16_96x80.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_nofilter_24x20.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_odd_17x9.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_photo_48x40.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_q100_20x18.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_sharp_40x36.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_simple_filter_33x31.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_vpx_parts8_37x45.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_vpx_skip_96x80.webp +0 -0
- package/dist/lib/image/tests/WebPDecodeTool.rgr +81 -0
- package/dist/lib/image/tests/WebPDecoderTest.rgr +1162 -0
- package/dist/lib/image/tests/run_webp_tests.sh +39 -0
- package/dist/lib/rust/RsJson.rgr +468 -0
- package/dist/lib/rust/RsPrelude.rgr +1663 -0
- package/dist/lib/shell_test.rgr +7 -7
- package/dist/lib/stdlib.rgr +21 -5
- package/dist/lib/zip/ranger.json +6 -0
- package/dist/rgrc.js +87318 -67610
- package/package.json +1010 -1040
- package/dist/README.md +0 -117
- package/dist/package.json +0 -47
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
; ==============================================================================
|
|
3
|
+
; EvgHost.rgr — the viewport every native host puts around an EVG app.
|
|
4
|
+
; ==============================================================================
|
|
5
|
+
;
|
|
6
|
+
; PLAN_WEB_LOADING.md S8. A UIKit view, an Android View and a browser page all
|
|
7
|
+
; do the same job around a Ranger app: hold the window's size and the part of
|
|
8
|
+
; it the system covers, convert a window point to a page point, turn a touch
|
|
9
|
+
; into a press that a drag can cancel, time a fling against the host's real
|
|
10
|
+
; clock, carry the keyboard's text in and the display list out.
|
|
11
|
+
;
|
|
12
|
+
; That was written three times. This is it once, against `EvgApp` — the
|
|
13
|
+
; conversation rather than any one application — so an app that extends
|
|
14
|
+
; `EvgApp` gets iOS, Android and the browser by declaring a subclass, and a
|
|
15
|
+
; rule fixed here is fixed on every platform at once.
|
|
16
|
+
;
|
|
17
|
+
; WHAT A SUBCLASS ADDS is only what is genuinely its own: how its app is
|
|
18
|
+
; loaded, and anything it answers that no other app would be asked. It puts
|
|
19
|
+
; its app in `app`, loads it, and calls `began` with the window.
|
|
20
|
+
;
|
|
21
|
+
; Units are the host's business and not this file's. iOS hands it points,
|
|
22
|
+
; Android density-independent pixels, a browser CSS pixels, and each scales
|
|
23
|
+
; its own canvas; what crosses is one coordinate system per platform and the
|
|
24
|
+
; same arithmetic.
|
|
25
|
+
;
|
|
26
|
+
; Everything here is checked on Node — `check_rt_ios.rgr` and
|
|
27
|
+
; `check_rt_android.rgr` drive it through RealTrainer's subclass, 42 and 40
|
|
28
|
+
; assertions — so a Mac and an emulator are needed only for the Swift and the
|
|
29
|
+
; Kotlin on top.
|
|
30
|
+
|
|
31
|
+
Import "EvgApp.rgr"
|
|
32
|
+
Import "EvgViewport.rgr"
|
|
33
|
+
|
|
34
|
+
class EvgHost {
|
|
35
|
+
|
|
36
|
+
; The application, as the conversation rather than as itself: a subclass
|
|
37
|
+
; puts its own app here and this class never learns which one it is.
|
|
38
|
+
def app:EvgApp (new EvgApp)
|
|
39
|
+
def started:boolean false
|
|
40
|
+
|
|
41
|
+
; The window, the safe area and where the page sits inside them — all of
|
|
42
|
+
; it in `EvgViewport`, which the dashboard's host owns one of too. This
|
|
43
|
+
; one is in mode 0: the page IS the window, so the scale is one, the pan
|
|
44
|
+
; is zero and a pinch has nothing to do.
|
|
45
|
+
def vp:EvgViewport (new EvgViewport)
|
|
46
|
+
|
|
47
|
+
; The last point a finger was seen at, in page pixels. A press is two
|
|
48
|
+
; events -- down marks the control, up activates it -- and the demo's
|
|
49
|
+
; `press` takes the id, so the id has to survive between them. A drag
|
|
50
|
+
; that scrolls cancels the press, as it does under a finger in the
|
|
51
|
+
; browser.
|
|
52
|
+
def lastPageX:double 0.0
|
|
53
|
+
def lastPageY:double 0.0
|
|
54
|
+
def pressedId:string ""
|
|
55
|
+
def dragged:double 0.0
|
|
56
|
+
; The clock a pan is timed against. A pan callback carries no timestamp of
|
|
57
|
+
; its own here, so `tick` advances this and a pan measures itself against
|
|
58
|
+
; the frame it arrived in — several pans inside one frame share that
|
|
59
|
+
; frame's time, which is what `EVGFling.track` is written to expect.
|
|
60
|
+
def nowMs:double 0.0
|
|
61
|
+
def lastPanMs:double 0.0
|
|
62
|
+
; A finger that landed on the scrollbar's thumb drags the thumb, not the
|
|
63
|
+
; page, until it lifts. `barY` follows it in page units.
|
|
64
|
+
def barDrag:boolean false
|
|
65
|
+
def barY:double 0.0
|
|
66
|
+
|
|
67
|
+
Constructor () {
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
; --- lifecycle ------------------------------------------------------------
|
|
71
|
+
|
|
72
|
+
; The window and the five texts the browser page embeds: the stylesheet,
|
|
73
|
+
; the session's COMPACT, the two state machines and the reference seed.
|
|
74
|
+
; An empty machine or seed is left unloaded rather than parsed, so a
|
|
75
|
+
; bundle that lacks one still opens the page.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
; WHAT EVERY `start` DOES, whatever the app it started. A subclass loads
|
|
79
|
+
; its own app — one takes a stylesheet and a seed, another takes a file —
|
|
80
|
+
; and then calls this: the window is taken, the page is laid out for it,
|
|
81
|
+
; and the host is open for business.
|
|
82
|
+
; `coarse` is a finger rather than a mouse, as the host reports it: the
|
|
83
|
+
; stylesheet's `(pointer: coarse)` block gives the targets their size. A
|
|
84
|
+
; phone says true and means it; a browser asks a media query and may mean
|
|
85
|
+
; either, which is why this is a parameter and not an assumption.
|
|
86
|
+
fn began:void (w:double h:double coarse:boolean) {
|
|
87
|
+
vp.resize(w h)
|
|
88
|
+
app.setPointerCoarse(coarse)
|
|
89
|
+
started = true
|
|
90
|
+
this.fitPage()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
; A rotation, Split View, Stage Manager, the keyboard. The page keeps every
|
|
94
|
+
; bit of its state; only its size changes, and the layout answers for it.
|
|
95
|
+
fn resize:void (w:double h:double) {
|
|
96
|
+
vp.resize(w h)
|
|
97
|
+
this.fitPage()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fn setSafeArea:void (top:double bottom:double left:double right:double) {
|
|
101
|
+
vp.setSafeArea(top bottom left right)
|
|
102
|
+
this.fitPage()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
; --- the viewport ---------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
fn usableWidth:double () {
|
|
108
|
+
return (vp.usableWidth())
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
fn usableHeight:double () {
|
|
112
|
+
return (vp.usableHeight())
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
; The page is the usable window, exactly: no scale, no offset but the
|
|
116
|
+
; safe area's. The demo lays itself out at that size.
|
|
117
|
+
fn fitPage:void () {
|
|
118
|
+
if (started == false) {
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
app.setPageSize((this.usableWidth()) (this.usableHeight()))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
; What the host translates the context by before it paints, and what it
|
|
125
|
+
; scales by — one, always. The names are the dashboard port's, so the two
|
|
126
|
+
; hosts read alike.
|
|
127
|
+
fn scale:double () {
|
|
128
|
+
return (vp.scale())
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
fn zoom:double () {
|
|
132
|
+
return (vp.zoom())
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
fn offsetX:double () {
|
|
136
|
+
return (vp.offsetX())
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
fn offsetY:double () {
|
|
140
|
+
return (vp.offsetY())
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
fn pageWidth:double () {
|
|
144
|
+
return (app.widthPx())
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
fn pageHeight:double () {
|
|
148
|
+
return (app.heightPx())
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
; A window point to a page pixel, and whether it lands on the page at all.
|
|
152
|
+
fn toPageX:double (x:double) {
|
|
153
|
+
return (vp.toPageX(x))
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
fn toPageY:double (y:double) {
|
|
157
|
+
return (vp.toPageY(y))
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
fn onPage:boolean (x:double y:double) {
|
|
161
|
+
def px:double (this.toPageX(x))
|
|
162
|
+
def py:double (this.toPageY(y))
|
|
163
|
+
if ((px < 0.0) || (py < 0.0)) {
|
|
164
|
+
return false
|
|
165
|
+
}
|
|
166
|
+
if (px > (this.usableWidth())) {
|
|
167
|
+
return false
|
|
168
|
+
}
|
|
169
|
+
if (py > (this.usableHeight())) {
|
|
170
|
+
return false
|
|
171
|
+
}
|
|
172
|
+
return true
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
; No zoom on a page that is already the window's size: a pinch changes
|
|
176
|
+
; nothing and says so, and a double tap has nothing to reset.
|
|
177
|
+
; A pinch and a double tap go to the viewport, which answers false in
|
|
178
|
+
; mode 0 — a page that IS the window has nothing to zoom out of. A host
|
|
179
|
+
; that later puts this class in mode 1 gets both for nothing.
|
|
180
|
+
fn pinch:boolean (factor:double focusX:double focusY:double) {
|
|
181
|
+
def moved:boolean (vp.pinch(factor focusX focusY))
|
|
182
|
+
if moved {
|
|
183
|
+
this.fitPage()
|
|
184
|
+
app.rebuild()
|
|
185
|
+
}
|
|
186
|
+
return moved
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
fn resetZoom:boolean () {
|
|
190
|
+
def moved:boolean (vp.resetZoom())
|
|
191
|
+
if moved {
|
|
192
|
+
this.fitPage()
|
|
193
|
+
app.rebuild()
|
|
194
|
+
}
|
|
195
|
+
return moved
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
; A drag scrolls the document, as a finger does in the browser: the
|
|
199
|
+
; content follows the finger. Past a few points of travel the press under
|
|
200
|
+
; the finger is a drag and not a tap, and the mark comes off.
|
|
201
|
+
fn canPan:boolean () {
|
|
202
|
+
return started
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
; The same drag, from a host that has its own timestamps.
|
|
206
|
+
;
|
|
207
|
+
; `panBy` measures how long a move took from `nowMs`, which `tick`
|
|
208
|
+
; advances — a touch callback on a phone carries no timestamp, so the
|
|
209
|
+
; frame it arrived in is the best clock there is. A browser's pointer
|
|
210
|
+
; event carries one, and a host that has a real interval should not have
|
|
211
|
+
; to throw it away and use the frame's instead.
|
|
212
|
+
fn panAt:boolean (dx:double dy:double dtMs:double) {
|
|
213
|
+
nowMs = (nowMs + dtMs)
|
|
214
|
+
return (this.panBy(dx dy))
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
fn panBy:boolean (dx:double dy:double) {
|
|
218
|
+
if (started == false) {
|
|
219
|
+
return false
|
|
220
|
+
}
|
|
221
|
+
dragged = (dragged + (dy * dy) + (dx * dx))
|
|
222
|
+
if ((dragged > 36.0) && ((strlen pressedId) > 0)) {
|
|
223
|
+
pressedId = ""
|
|
224
|
+
app.setPressed("")
|
|
225
|
+
}
|
|
226
|
+
; HOW LONG the move took as well as how far, because that is what
|
|
227
|
+
; decides where the lift throws the page. Without it a swipe on the
|
|
228
|
+
; phone stopped the instant the finger left, which no other iOS
|
|
229
|
+
; scroll does.
|
|
230
|
+
def dt:double (nowMs - lastPanMs)
|
|
231
|
+
lastPanMs = nowMs
|
|
232
|
+
if barDrag {
|
|
233
|
+
barY = (barY + dy)
|
|
234
|
+
return (app.scrollbarDrag(barY))
|
|
235
|
+
}
|
|
236
|
+
return (app.scrollDrag((0.0 - dy) dt))
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
; --- the frame ------------------------------------------------------------
|
|
240
|
+
|
|
241
|
+
fn frame:EVGDisplayList () {
|
|
242
|
+
return (app.display())
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
; The clock. `dtMs` is the REAL milliseconds since the last frame, which is
|
|
246
|
+
; what makes a dropped frame shorten an animation rather than stretch it.
|
|
247
|
+
; The host clamps a long gap; this answers whether anything moved.
|
|
248
|
+
fn tick:boolean (dtMs:double) {
|
|
249
|
+
if (started == false) {
|
|
250
|
+
return false
|
|
251
|
+
}
|
|
252
|
+
nowMs = (nowMs + dtMs)
|
|
253
|
+
; `app.tick` carries the momentum forward as well as the clock — see
|
|
254
|
+
; `RealTrainerDemo.scrollDrag` — so a glide needs nothing from the
|
|
255
|
+
; host beyond the frames it is already asking for.
|
|
256
|
+
return (app.tick(dtMs))
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
; --- input ----------------------------------------------------------------
|
|
260
|
+
|
|
261
|
+
fn hitAt:string (x:double y:double) {
|
|
262
|
+
if ((this.onPage(x y)) == false) {
|
|
263
|
+
return ""
|
|
264
|
+
}
|
|
265
|
+
return (app.hitId((this.toPageX(x)) (this.toPageY(y))))
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
; A finger lands: mark whatever is under it as pressed, and remember the id
|
|
269
|
+
; so the release can activate the same control even if the finger moved a
|
|
270
|
+
; little first.
|
|
271
|
+
fn pressAt:boolean (x:double y:double) {
|
|
272
|
+
lastPageX = (this.toPageX(x))
|
|
273
|
+
lastPageY = (this.toPageY(y))
|
|
274
|
+
dragged = 0.0
|
|
275
|
+
; A finger down catches the page where it is, the way it does
|
|
276
|
+
; everywhere else on the phone.
|
|
277
|
+
app.scrollHalt()
|
|
278
|
+
lastPanMs = nowMs
|
|
279
|
+
if (app.scrollbarGrab(lastPageX lastPageY)) {
|
|
280
|
+
barDrag = true
|
|
281
|
+
barY = lastPageY
|
|
282
|
+
pressedId = ""
|
|
283
|
+
return true
|
|
284
|
+
}
|
|
285
|
+
def id:string (this.hitAt(x y))
|
|
286
|
+
pressedId = id
|
|
287
|
+
app.setPressed(id)
|
|
288
|
+
return ((strlen id) > 0)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
; The finger lifts. The control under it is activated -- the demo decides
|
|
292
|
+
; what that means -- and the pressed mark comes off either way. A field
|
|
293
|
+
; takes the focus, so the host knows to raise the keyboard.
|
|
294
|
+
fn releasePress:boolean () {
|
|
295
|
+
if barDrag {
|
|
296
|
+
barDrag = false
|
|
297
|
+
app.scrollbarRelease()
|
|
298
|
+
return true
|
|
299
|
+
}
|
|
300
|
+
; The finger left. If it was moving, the page carries on — the app
|
|
301
|
+
; decides from the speed it tracked whether that was a throw or a
|
|
302
|
+
; stop, and `tick` does the rest.
|
|
303
|
+
def threw:boolean (app.scrollRelease())
|
|
304
|
+
def id:string pressedId
|
|
305
|
+
pressedId = ""
|
|
306
|
+
app.setPressed("")
|
|
307
|
+
if threw {
|
|
308
|
+
return true
|
|
309
|
+
}
|
|
310
|
+
if ((strlen id) == 0) {
|
|
311
|
+
return true
|
|
312
|
+
}
|
|
313
|
+
if (app.hasField(id)) {
|
|
314
|
+
if ((app.focusedField()) != id) {
|
|
315
|
+
app.setFocus(id)
|
|
316
|
+
app.rebuild()
|
|
317
|
+
}
|
|
318
|
+
return true
|
|
319
|
+
}
|
|
320
|
+
if ((strlen (app.focusedField())) > 0) {
|
|
321
|
+
app.setFocus("")
|
|
322
|
+
app.rebuild()
|
|
323
|
+
}
|
|
324
|
+
return (app.press(id))
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
fn cancelPress:boolean () {
|
|
328
|
+
if barDrag {
|
|
329
|
+
barDrag = false
|
|
330
|
+
app.scrollbarRelease()
|
|
331
|
+
return true
|
|
332
|
+
}
|
|
333
|
+
def threw:boolean (app.scrollRelease())
|
|
334
|
+
if ((strlen pressedId) == 0) {
|
|
335
|
+
return threw
|
|
336
|
+
}
|
|
337
|
+
pressedId = ""
|
|
338
|
+
app.setPressed("")
|
|
339
|
+
return true
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
; A pointer that is not pressing: a trackpad on an iPad, or the Simulator's
|
|
343
|
+
; mouse. Answers whether the hover actually changed, so a host does not
|
|
344
|
+
; repaint on every move.
|
|
345
|
+
fn hoverAt:boolean (x:double y:double) {
|
|
346
|
+
def barChanged:boolean (app.scrollbarHover((this.toPageX(x)) (this.toPageY(y))))
|
|
347
|
+
if (app.overScrollbar()) {
|
|
348
|
+
if ((strlen (app.hoveredId())) > 0) {
|
|
349
|
+
app.setHover("")
|
|
350
|
+
return true
|
|
351
|
+
}
|
|
352
|
+
return barChanged
|
|
353
|
+
}
|
|
354
|
+
def id:string (this.hitAt(x y))
|
|
355
|
+
if (id == (app.hoveredId())) {
|
|
356
|
+
return barChanged
|
|
357
|
+
}
|
|
358
|
+
app.setHover(id)
|
|
359
|
+
return true
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
fn clearHover:boolean () {
|
|
363
|
+
if ((strlen (app.hoveredId())) == 0) {
|
|
364
|
+
return false
|
|
365
|
+
}
|
|
366
|
+
app.setHover("")
|
|
367
|
+
return true
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
; --- the keyboard ---------------------------------------------------------
|
|
371
|
+
|
|
372
|
+
; The field that has the focus, or nothing — the host raises the keyboard
|
|
373
|
+
; while there is one and lowers it when there is none.
|
|
374
|
+
fn focusedField:string () {
|
|
375
|
+
return (app.focusedField())
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
; What the keyboard typed, into the focused field.
|
|
379
|
+
fn typeText:boolean (text:string) {
|
|
380
|
+
if ((strlen (app.focusedField())) == 0) {
|
|
381
|
+
return false
|
|
382
|
+
}
|
|
383
|
+
return (app.typeText(text))
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
; A named key — "Backspace", "Enter", "ArrowLeft"... — as the browser
|
|
387
|
+
; names them.
|
|
388
|
+
fn key:boolean (name:string shift:boolean ctrl:boolean) {
|
|
389
|
+
return (app.keyWith(name shift ctrl))
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
; The focused field's text, for a host that mirrors it into a native
|
|
393
|
+
; field of its own.
|
|
394
|
+
fn fieldStateJson:string () {
|
|
395
|
+
def tid:string (app.focusedField())
|
|
396
|
+
if ((strlen tid) == 0) {
|
|
397
|
+
return "{}"
|
|
398
|
+
}
|
|
399
|
+
return (app.fieldStateJson(tid))
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
fn blur:boolean () {
|
|
403
|
+
if ((strlen (app.focusedField())) == 0) {
|
|
404
|
+
return false
|
|
405
|
+
}
|
|
406
|
+
app.setFocus("")
|
|
407
|
+
app.rebuild()
|
|
408
|
+
return true
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
; --- what the app is doing ------------------------------------------------
|
|
412
|
+
|
|
413
|
+
fn sceneName:string () {
|
|
414
|
+
return (app.sceneName())
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
; A route, as the browser's `?route=` opens one: `/calendar/cal-train`,
|
|
418
|
+
; `/new-calendar`, `/summary/yearsheet`.
|
|
419
|
+
fn openRoute:boolean (route:string) {
|
|
420
|
+
return (app.openRoute(route))
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
fn styleErrorCount:int () {
|
|
424
|
+
return (app.styleErrorCount())
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
fn styleErrorAt:string (i:int) {
|
|
428
|
+
return (app.styleErrorAt(i))
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
; --- the names the Android host learned first --------------------------
|
|
432
|
+
;
|
|
433
|
+
; The Kotlin side asks for `panX` and `panY` where the Swift side asks for
|
|
434
|
+
; `offsetX` and `offsetY`. They are the same number — where in the window
|
|
435
|
+
; the page's top left corner sits — and the two ports simply named it
|
|
436
|
+
; twice. Both names answer here rather than either host being edited to
|
|
437
|
+
; suit the merge.
|
|
438
|
+
fn panX:double () {
|
|
439
|
+
return (this.offsetX())
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
fn panY:double () {
|
|
443
|
+
return (this.offsetY())
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
; No `main` here, deliberately. This facade is a LIBRARY: an app's entry
|
|
447
|
+
; point is the hand-written host — `ios/main.swift` calling
|
|
448
|
+
; `UIApplicationMain`, an Android `Activity` — and a static method named
|
|
449
|
+
; `main`, with or without a call at the bottom, would make the compiler
|
|
450
|
+
; emit a program that runs on load, which is not what a library is.
|
|
451
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; EvgTest — the small assertion harness the EVG suites under lib/ use.
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
; The same shape as the gallery's RgTest: each check prints " PASS <name>" /
|
|
7
|
+
; " FAIL <name>", and summary() prints a grep-able "ALL PASS" (or
|
|
8
|
+
; "SOME FAILED") plus a "passed=X failed=Y" line. It lives here so that
|
|
9
|
+
; nothing under lib/evg imports gallery/ — lib is MIT and the gallery is not.
|
|
10
|
+
; ==============================================================================
|
|
11
|
+
|
|
12
|
+
class EvgTest {
|
|
13
|
+
def passed:int 0
|
|
14
|
+
def failed:int 0
|
|
15
|
+
def suite:string ""
|
|
16
|
+
|
|
17
|
+
sfn forSuite:EvgTest (name:string) {
|
|
18
|
+
def t:EvgTest (new EvgTest)
|
|
19
|
+
t.suite = name
|
|
20
|
+
print ("### " + name)
|
|
21
|
+
return t
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fn ok:void (name:string cond:boolean) {
|
|
25
|
+
if cond {
|
|
26
|
+
this.passed = (this.passed + 1)
|
|
27
|
+
print (" PASS " + name)
|
|
28
|
+
} {
|
|
29
|
+
this.failed = (this.failed + 1)
|
|
30
|
+
print (" FAIL " + name)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fn no:void (name:string cond:boolean) {
|
|
35
|
+
this.ok(name (cond == false))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fn eqInt:void (name:string got:int want:int) {
|
|
39
|
+
if (got == want) {
|
|
40
|
+
this.passed = (this.passed + 1)
|
|
41
|
+
print (" PASS " + name)
|
|
42
|
+
} {
|
|
43
|
+
this.failed = (this.failed + 1)
|
|
44
|
+
print (" FAIL " + name + " got=" + (to_string got) + " want=" + (to_string want))
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fn eqStr:void (name:string got:string want:string) {
|
|
49
|
+
if (got == want) {
|
|
50
|
+
this.passed = (this.passed + 1)
|
|
51
|
+
print (" PASS " + name)
|
|
52
|
+
} {
|
|
53
|
+
this.failed = (this.failed + 1)
|
|
54
|
+
print (" FAIL " + name + " got=" + got + " want=" + want)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fn eqBool:void (name:string got:boolean want:boolean) {
|
|
59
|
+
if (got == want) {
|
|
60
|
+
this.passed = (this.passed + 1)
|
|
61
|
+
print (" PASS " + name)
|
|
62
|
+
} {
|
|
63
|
+
this.failed = (this.failed + 1)
|
|
64
|
+
print (" FAIL " + name)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
fn near:void (name:string got:double want:double) {
|
|
69
|
+
def d:double (got - want)
|
|
70
|
+
if (d < 0.0) {
|
|
71
|
+
d = (0.0 - d)
|
|
72
|
+
}
|
|
73
|
+
if (d < 0.000001) {
|
|
74
|
+
this.passed = (this.passed + 1)
|
|
75
|
+
print (" PASS " + name)
|
|
76
|
+
} {
|
|
77
|
+
this.failed = (this.failed + 1)
|
|
78
|
+
print (" FAIL " + name + " got=" + (to_string got) + " want=" + (to_string want))
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
fn summary:void () {
|
|
83
|
+
print "== summary =="
|
|
84
|
+
print ("passed=" + (to_string this.passed) + " failed=" + (to_string this.failed))
|
|
85
|
+
if (this.failed == 0) {
|
|
86
|
+
print "ALL PASS"
|
|
87
|
+
} {
|
|
88
|
+
print "SOME FAILED"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|