(*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *)

open OUnit2

let run ctxt expected name content =
  let open Parsing_service_js in
  let file = File_key.SourceFile "/dummy.js" in
  let (_docblock_errors, info) = parse_docblock ~max_tokens:docblock_max_tokens file content in
  let parse_options =
    {
      parse_fail = false;
      parse_types_mode = TypesAllowed;
      parse_use_strict = true;
      parse_prevent_munge = false;
      parse_module_ref_prefix = None;
      parse_facebook_fbt = None;
      (* following options unused in classic mode *)
      parse_type_asserts = false;
      parse_suppress_types = SSet.empty;
      parse_max_literal_len = 0;
      parse_exact_by_default = false;
      parse_enable_enums = false;
      parse_enable_relay_integration = false;
      parse_relay_integration_excludes = [];
      parse_relay_integration_module_prefix = None;
      parse_node_main_fields = [];
    }
  in
  let result = do_parse ~parse_options ~info content file in
  let ast =
    match result with
    | Parse_ok { ast; _ } -> ast
    | Parse_fail _ -> failwith "Parse unexpectedly failed"
    | Parse_skip _ -> failwith "Parse unexpectedly skipped"
  in
  let result = PropertyAccessSearcher.search name ast in
  assert_equal ~ctxt expected result

let tests =
  "SymbolKind"
  >::: [
         ("property_access_positive" >:: fun ctxt -> run ctxt true "bar" "foo.bar");
         ("property_access_negative" >:: fun ctxt -> run ctxt false "bar" "foo.baz");
         ("destructuring_shorthand_positive" >:: fun ctxt -> run ctxt true "bar" "const {bar} = baz");
         ( "destructuring_shorthand_negative" >:: fun ctxt ->
           run ctxt false "baz" "const {bar} = baz"
         );
         ("destructuring_positive" >:: fun ctxt -> run ctxt true "foo" "const {foo: bar} = baz");
         ("destructuring_negative" >:: fun ctxt -> run ctxt false "bar" "const {foo: bar} = baz");
         ("destructuring_negative" >:: fun ctxt -> run ctxt false "bar" "const {foo: bar} = baz");
         ("export_default_positive" >:: fun ctxt -> run ctxt true "default" "export default 5");
         ("export_default_negative" >:: fun ctxt -> run ctxt false "bar" "export default bar");
         ("import_default_positive" >:: fun ctxt -> run ctxt true "default" "import bar from 'baz'");
         ("import_default_negative" >:: fun ctxt -> run ctxt false "bar" "import bar from 'baz'");
         ("class_method" >:: fun ctxt -> run ctxt true "bar" "class Foo { bar(): void {} }");
         ("class_property" >:: fun ctxt -> run ctxt true "bar" "class Foo { bar: number }");
         ("optional_chain_new" >:: fun ctxt -> run ctxt true "bar" "foo?.bar");
         ("optional_chain_continued" >:: fun ctxt -> run ctxt true "baz" "foo?.bar.baz");
       ]
