# typed: true # frozen_string_literal: true require "test_helper" module RubyIndexer class PrefixTreeTest < Minitest::Test def test_empty tree = PrefixTree.new assert_empty(tree.search("")) assert_empty(tree.search("foo")) end def test_single_item tree = PrefixTree.new tree.insert("foo", "foo") assert_equal(["foo"], tree.search("")) assert_equal(["foo"], tree.search("foo")) assert_empty(tree.search("bar")) end def test_multiple_items tree = PrefixTree[String].new ["foo", "bar", "baz"].each { |item| tree.insert(item, item) } assert_equal(["foo", "bar", "baz"], tree.search("")) assert_equal(["bar", "baz"], tree.search("b")) assert_equal(["foo"], tree.search("fo")) assert_equal(["bar", "baz"], tree.search("ba")) assert_equal(["baz"], tree.search("baz")) assert_empty(tree.search("qux")) end def test_multiple_prefixes tree = PrefixTree[String].new ["fo", "foo"].each { |item| tree.insert(item, item) } assert_equal(["fo", "foo"], tree.search("")) assert_equal(["fo", "foo"], tree.search("f")) assert_equal(["fo", "foo"], tree.search("fo")) assert_equal(["foo"], tree.search("foo")) assert_empty(tree.search("fooo")) end def test_multiple_prefixes_with_shuffled_order tree = PrefixTree[String].new [ "foo/bar/base", "foo/bar/on", "foo/bar/support/selection", "foo/bar/support/runner", "foo/internal", "foo/bar/document", "foo/bar/code", "foo/bar/support/rails", "foo/bar/diagnostics", "foo/bar/document2", "foo/bar/support/runner2", "foo/bar/support/diagnostic", "foo/document", "foo/bar/formatting", "foo/bar/support/highlight", "foo/bar/semantic", "foo/bar/support/prefix", "foo/bar/folding", "foo/bar/selection", "foo/bar/support/syntax", "foo/bar/document3", "foo/bar/hover", "foo/bar/support/semantic", "foo/bar/support/source", "foo/bar/inlay", "foo/requests", "foo/bar/support/formatting", "foo/bar/path", "foo/executor", ].each { |item| tree.insert(item, item) } assert_equal( [ "foo/bar/support/selection", "foo/bar/support/semantic", "foo/bar/support/syntax", "foo/bar/support/source", "foo/bar/support/runner", "foo/bar/support/runner2", "foo/bar/support/rails", "foo/bar/support/diagnostic", "foo/bar/support/highlight", "foo/bar/support/prefix", "foo/bar/support/formatting", ], tree.search("foo/bar/support"), ) end def test_deletion tree = PrefixTree[String].new ["foo/bar", "foo/baz"].each { |item| tree.insert(item, item) } assert_equal(["foo/bar", "foo/baz"], tree.search("foo")) tree.delete("foo/bar") assert_empty(tree.search("foo/bar")) assert_equal(["foo/baz"], tree.search("foo")) end def test_delete_does_not_impact_other_keys_with_the_same_value tree = PrefixTree[String].new tree.insert("key1", "value") tree.insert("key2", "value") assert_equal(["value", "value"], tree.search("key")) tree.delete("key2") assert_empty(tree.search("key2")) assert_equal(["value"], tree.search("key1")) end def test_deleted_node_is_removed_from_the_tree tree = PrefixTree[String].new tree.insert("foo/bar", "foo/bar") assert_equal(["foo/bar"], tree.search("foo")) tree.delete("foo/bar") root = tree.instance_variable_get(:@root) assert_empty(root.children) end def test_deleting_non_terminal_nodes tree = PrefixTree[String].new tree.insert("abc", "value1") tree.insert("abcdef", "value2") tree.delete("abcdef") assert_empty(tree.search("abcdef")) assert_equal(["value1"], tree.search("abc")) end def test_overriding_values tree = PrefixTree[Integer].new tree.insert("foo/bar", 123) assert_equal([123], tree.search("foo/bar")) tree.insert("foo/bar", 456) assert_equal([456], tree.search("foo/bar")) end end end