diff options
| author | Riley Bruins <ribru17@hotmail.com> | 2024-07-27 08:34:30 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-27 17:34:30 +0200 |
| commit | f97e0de0053df1cb3b9f74b9b1239acced1b7d9a (patch) | |
| tree | 99659d6656483a4b8704bb944a234cb62ef79115 /tests | |
| parent | fix(query): properly apply predicate injections (diff) | |
| download | nvim-treesitter-f97e0de0053df1cb3b9f74b9b1239acced1b7d9a.tar nvim-treesitter-f97e0de0053df1cb3b9f74b9b1239acced1b7d9a.tar.gz nvim-treesitter-f97e0de0053df1cb3b9f74b9b1239acced1b7d9a.tar.bz2 nvim-treesitter-f97e0de0053df1cb3b9f74b9b1239acced1b7d9a.tar.lz nvim-treesitter-f97e0de0053df1cb3b9f74b9b1239acced1b7d9a.tar.xz nvim-treesitter-f97e0de0053df1cb3b9f74b9b1239acced1b7d9a.tar.zst nvim-treesitter-f97e0de0053df1cb3b9f74b9b1239acced1b7d9a.zip | |
feat: add rescript parser and queries (#6671)
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/indent/rescript/basic.res | 23 | ||||
| -rw-r--r-- | tests/indent/rescript/complex.res | 151 | ||||
| -rw-r--r-- | tests/indent/rescript/conditional.res | 104 | ||||
| -rw-r--r-- | tests/indent/rescript_spec.lua | 33 |
4 files changed, 311 insertions, 0 deletions
diff --git a/tests/indent/rescript/basic.res b/tests/indent/rescript/basic.res new file mode 100644 index 000000000..c5138a7b3 --- /dev/null +++ b/tests/indent/rescript/basic.res @@ -0,0 +1,23 @@ +@genType +type person = { + name: string, + age: int, +} + +@genType +type renderMe<'a> = React.component<{ + "randomString": string, + "poly": 'a, +}> + +@genType.import("./hookExample") @react.component +external make: ( + ~person: person, + ~children: React.element, + ~renderMe: renderMe<'a>, +) => React.element = "makeRenamed" + +@genType.import("./hookExample") +external foo: (~person: person) => string = "foo" + +let hi = 'a' diff --git a/tests/indent/rescript/complex.res b/tests/indent/rescript/complex.res new file mode 100644 index 000000000..1f21c3364 --- /dev/null +++ b/tests/indent/rescript/complex.res @@ -0,0 +1,151 @@ +let hit = ({hit, children}: DocSearch.hitComponent) => { + let toTitle = str => + str->Js.String2.charAt(0)->Js.String2.toUpperCase ++ Js.String2.sliceToEnd(str, ~from=1) + + let description = switch hit.url + ->Js.String2.split("/") + ->Js.Array2.sliceFrom(1) + ->Belt.List.fromArray { + | list{"blog" as r | "community" as r, ..._} => r->toTitle + | list{"docs", doc, version, ...rest} => + let path = rest->Belt.List.toArray + + let info = + path + ->Js.Array2.slice(~start=0, ~end_=Js.Array2.length(path) - 1) + ->Js.Array2.map(path => + switch path { + | "api" => "API" + | other => toTitle(other) + } + ) + + [doc->toTitle, version->toTitle]->Js.Array2.concat(info)->Js.Array2.joinWith(" / ") + | _ => "" + } + + <Next.Link href={hit.url} className="flex flex-col w-full"> + <span className="text-gray-60 captions px-4 pt-3 pb-1 block"> + {description->React.string} + </span> + children + </Next.Link> +} + +let transformItems = (items: DocSearch.transformItems) => { + items->Belt.Array.keepMap(item => { + let url = try Webapi.URL.make(item.url)->Some catch { + | Js.Exn.Error(obj) => + Js.Console.error2(`Failed to parse URL ${item.url}`, obj) + None + } + switch url { + | Some({pathname, hash}) => {...item, url: pathname ++ hash}->Some + | None => None + } + }) +} + +@react.component +let make = () => { + let (state, setState) = React.useState(_ => Inactive) + let router = Next.Router.useRouter() + + let version = switch Url.parse(router.route).version { + | Version(v) => v + | _ => "latest" + } + + let handleCloseModal = () => { + let () = switch ReactDOM.querySelector(".DocSearch-Modal") { + | Some(modal) => + switch ReactDOM.querySelector("body") { + | Some(body) => + open Webapi + body->Element.classList->ClassList.remove("DocSearch--active") + modal->Element.addEventListener("transitionend", () => { + setState(_ => Inactive) + }) + | None => setState(_ => Inactive) + } + | None => () + } + } + + React.useEffect(() => { + let isEditableTag = el => + switch el->tagName { + | "TEXTAREA" | "SELECT" | "INPUT" => true + | _ => false + } + + let focusSearch = e => { + switch activeElement { + | Some(el) if el->isEditableTag || el->isContentEditable => () + | _ => + setState(_ => Active) + e->keyboardEventPreventDefault + } + } + + let handleGlobalKeyDown = e => { + switch e.key { + | "/" => focusSearch(e) + | "k" if e.ctrlKey || e.metaKey => focusSearch(e) + | "Escape" => handleCloseModal() + | _ => () + } + } + addKeyboardEventListener("keydown", handleGlobalKeyDown) + Some(() => removeKeyboardEventListener("keydown", handleGlobalKeyDown)) + }, [setState]) + + let onClick = _ => { + setState(_ => Active) + } + + let onClose = React.useCallback(() => { + handleCloseModal() + }, [setState]) + + <> + <button onClick type_="button" className="text-gray-60 hover:text-fire-50 p-2"> + <Icon.MagnifierGlass className="fill-current" /> + </button> + {switch state { + | Active => + switch ReactDOM.querySelector("body") { + | Some(element) => + ReactDOM.createPortal( + <DocSearch + apiKey + appId + indexName + onClose + searchParameters={facetFilters: ["version:" ++ version]} + initialScrollY={window->scrollY} + transformItems={transformItems} + hitComponent=hit + /> + element, + ) + | None => React.null + } + | Inactive => React.null + }} + </> +} + +let comparable = (type key, ~cmp) => { + module N = MakeComparable({ + type t = key + let cmp = cmp + }) + module(N: Comparable with type t = key) +} + +<Next.Link href={hit.url} className="flex flex-col w-full"> +<span className="text-gray-60 captions px-4 pt-3 pb-1 block"> + {description->React.string} + children +</Next.Link> diff --git a/tests/indent/rescript/conditional.res b/tests/indent/rescript/conditional.res new file mode 100644 index 000000000..db8328f26 --- /dev/null +++ b/tests/indent/rescript/conditional.res @@ -0,0 +1,104 @@ +include UseClient +include UseQuery +include UseMutation +include UseSubscription + +type hookResponse<'ret> = Types.Hooks.hookResponse<'ret> = { + operation: Types.operation, + fetching: bool, + data: option<'ret>, + error: option<CombinedError.t>, + response: Types.Hooks.response<'ret>, + extensions: option<Js.Json.t>, + stale: bool, +} + +Js.Array2.slice(~start=0, ~end_=Js.Array2.length(moduleRoute) - 1) + +let pathModule = Path.join([dir, version, `${moduleName}.json`]) + +let {Api.LocMsg.row: row, column, shortMsg} = locMsg + +let message = `${"error"->red}: failed to compile examples from ${kind} ${test.id->cyan}\n${errorMessage}` + +let version = (evt->ReactEvent.Form.target)["value"] + +let rehypePlugins = + [Rehype.WithOptions([Plugin(Rehype.slug), SlugOption({prefix: slugPrefix ++ "-"})])]->Some + +module Item = { + type t = { + name: string, + sellIn: int, + quality: int, + } + + let make = (~name, ~sellIn, ~quality): t => { + name, + sellIn, + quality, + } +} + +let updateQuality = (items: array<Item.t>) => { + items->Js.Array2.map(item => { + let newItem = ref(item) + + call( + asdf, + asdf + ) + + if ( + newItem.contents.name != "Aged Brie" && 5 > 2 && + newItem.contents.name != "Backstage passes to a TAFKAL80ETC concert" + ) { + if newItem.contents.quality > 0 { + if newItem.contents.name != "Sulfuras, Hand of Ragnaros" { + newItem := {...newItem.contents, quality: newItem.contents.quality - 1} + } + } + } else if newItem.contents.quality < 50 { + newItem := {...newItem.contents, quality: newItem.contents.quality + 1} + + if newItem.contents.name == "Backstage passes to a TAFKAL80ETC concert" { + if newItem.contents.sellIn < 11 { + if newItem.contents.quality < 50 { + newItem := {...newItem.contents, quality: newItem.contents.quality + 1} + } + } + + if newItem.contents.sellIn < 6 { + if newItem.contents.quality < 50 { + newItem := {...newItem.contents, quality: newItem.contents.quality + 1} + } + } + } + } + + if newItem.contents.name != "Sulfuras, Hand of Ragnaros" { + newItem := {...newItem.contents, sellIn: newItem.contents.sellIn - 1} + } + + if newItem.contents.sellIn < 0 { + if newItem.contents.name != "Aged Brie" { + if newItem.contents.name != "Backstage passes to a TAFKAL80ETC concert" { + if newItem.contents.quality > 0 { + if newItem.contents.name != "Sulfuras, Hand of Ragnaros" { + newItem := {...newItem.contents, quality: newItem.contents.quality - 1} + } + } + } else { + newItem := { + ...newItem.contents, + quality: newItem.contents.quality - newItem.contents.quality, + } + } + } else if newItem.contents.quality < 50 { + newItem := {...newItem.contents, quality: newItem.contents.quality + 1} + } + } + + newItem.contents + }) +} diff --git a/tests/indent/rescript_spec.lua b/tests/indent/rescript_spec.lua new file mode 100644 index 000000000..5b1f06abd --- /dev/null +++ b/tests/indent/rescript_spec.lua @@ -0,0 +1,33 @@ +local Runner = require("tests.indent.common").Runner + +local run = Runner:new(it, "tests/indent/rescript", { + tabstop = 2, + shiftwidth = 2, + softtabstop = 0, + expandtab = true, +}) + +describe("indent ReScript:", function() + describe("whole file:", function() + run:whole_file(".", {}) + end) + + describe("new line:", function() + run:new_line("basic.res", { on_line = 5, text = "x", indent = 0 }) + run:new_line("basic.res", { on_line = 9, text = '"another": here,', indent = 2 }) + run:new_line("basic.res", { on_line = 10, text = "}", indent = 0 }) + run:new_line("basic.res", { on_line = 14, text = "~test: test,", indent = 2 }) + run:new_line("basic.res", { on_line = 18, text = "x", indent = 0 }) + + run:new_line("complex.res", { on_line = 3, text = "x", indent = 2 }) + run:new_line("complex.res", { on_line = 5, text = "x", indent = 4 }) + run:new_line("complex.res", { on_line = 17, text = "|", indent = 10 }) + run:new_line("complex.res", { on_line = 25, text = "x", indent = 2 }) + run:new_line("complex.res", { on_line = 60, text = "x", indent = 6 }) + run:new_line("complex.res", { on_line = 120, text = "x", indent = 14 }) + run:new_line("complex.res", { on_line = 136, text = "x", indent = 2 }) + + run:new_line("conditional.res", { on_line = 6, text = "test: bool,", indent = 2 }) + run:new_line("conditional.res", { on_line = 95, text = "x", indent = 10 }) + end) +end) |
