// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Tests the functionality of object properties with the js_util library. For
// js_util tests with HTML objects see tests/lib/html/js_util_test.dart.

@JS()
library js_util_properties_test;

import 'package:js/js.dart';
import 'package:js/js_util.dart' as js_util;
import 'package:expect/minitest.dart';

@JS()
external String jsFunction();

@JS()
external void eval(String code);

@JS('JSON.stringify')
external String stringify(o);

@JS('ArrayBuffer')
external get JSArrayBufferType;

@JS()
class Foo {
  external Foo(num a);

  external num get a;
  external num bar();
  external Object get objectProperty;
  external List get list;
}

@JS('Foo')
external get JSFooType;

String dartFunction() {
  return 'Dart Function';
}

@JS()
@anonymous
class ExampleTypedLiteral {
  external factory ExampleTypedLiteral({a, b});

  external get a;
  external get b;
}

class ExampleTearoff {
  int x = 3;
  foo() => x;
}

String _getBarWithSideEffect() {
  var x = 5;
  expect(x, equals(5));
  return 'bar';
}

main() {
  eval(r"""
    function Foo(a) {
      this.a = a;
    }

    Foo.b = 38;

    Foo.prototype.list = [2, 4, 6];

    Foo.prototype.bar = function() {
      return this.a;
    }

    Foo.prototype.toString = function() {
      return "I'm a Foo a=" + this.a;
    }

    Foo.prototype.fnList = [Foo.prototype.bar, Foo.prototype.toString];

    Foo.prototype.objectProperty = {
      'c': 1,
      'list': [10, 20, 30],
      'functionProperty': function() { return 'Function Property'; }
    }

    function jsFunction() {
      return "JS Function";
    }

    Foo.prototype.nestedFunction = function() {
      return function() {
        return 'Nested Function';
      };
    }

    Foo.prototype.getFirstEl = function(list) {
      return list[0];
    }

    Foo.prototype.sumFn = function(a, b) {
      return a + b;
    }

    Foo.prototype.getA = function(obj) {
      return obj.a;
    }

    Foo.prototype.callFn = function(fn) {
      return fn();
    }
    """);

  group('newObject', () {
    test('create', () {
      expect(identical(js_util.newObject(), js_util.newObject()), isFalse);
    });

    test('callMethod', () {
      var o = js_util.newObject();
      expect(js_util.callMethod(o, 'toString', []), equals('[object Object]'));
      expect(stringify(o), equals('{}'));
    });

    test('properties', () {
      var o = js_util.newObject();
      expect(js_util.hasProperty(o, 'foo bar'), isFalse);
      expect(js_util.hasProperty(o, 'toString'), isTrue);
      expect(js_util.callMethod(o, 'hasOwnProperty', ['toString']), isFalse);
      expect(js_util.callMethod(o, 'hasOwnProperty', ['foo bar']), isFalse);
      js_util.setProperty(o, 'foo bar', 42);
      expect(js_util.callMethod(o, 'hasOwnProperty', ['foo bar']), isTrue);
      expect(js_util.getProperty(o, 'foo bar'), equals(42));
      expect(js_util.hasProperty(o, 'foo bar'), isTrue);
      expect(stringify(o), equals('{"foo bar":42}'));
    });

    test('nested properties calls', () {
      var o = js_util.newObject();
      var f = new Foo(42);
      js_util.setProperty(o, 'foo', f);
      var foo = js_util.getProperty(o, 'foo');
      expect(foo, equals(f));
      expect(js_util.hasProperty(foo, 'a'), isTrue);
      expect(js_util.getProperty(foo, 'a'), equals(42));
      js_util.setProperty(foo, 'a', 24);
      expect(js_util.getProperty(foo, 'a'), equals(24));
    });
  });

  group('hasProperty', () {
    test('typed object', () {
      var f = new Foo(42);
      expect(js_util.hasProperty(f, 'a'), isTrue);
      expect(js_util.hasProperty(f, 'bar'), isTrue);
      expect(js_util.hasProperty(f, 'b'), isFalse);
      expect(js_util.hasProperty(f, 'toString'), isTrue);
      js_util.setProperty(f, '__proto__', null);
      expect(js_util.hasProperty(f, 'toString'), isFalse);
    });

    test('typed literal', () {
      var literal = new ExampleTypedLiteral(a: 'x', b: 42);
      expect(js_util.hasProperty(literal, 'a'), isTrue);
      expect(js_util.hasProperty(literal, 'b'), isTrue);
      expect(js_util.hasProperty(literal, 'anything'), isFalse);

      literal = new ExampleTypedLiteral(a: null);
      expect(js_util.hasProperty(literal, 'a'), isTrue);
      expect(js_util.hasProperty(literal, 'b'), isFalse);
      expect(js_util.hasProperty(literal, 'anything'), isFalse);
    });

    test('complex hasProperty calls', () {
      var f = new Foo(42);
      expect(js_util.hasProperty(f.objectProperty, 'c'), isTrue);
      expect(js_util.hasProperty(f.objectProperty, 'nonexistent'), isFalse);

      // Using a variable for the property name.
      String propertyName = 'bar';
      expect(js_util.hasProperty(f, propertyName), isTrue);
    });
  });

  group('getProperty', () {
    test('typed object', () {
      var f = new Foo(42);
      expect(js_util.getProperty(f, 'a'), equals(42));
      expect(js_util.getProperty(f, 'b'), isNull);
      expect(js_util.getProperty(f, 'bar') is Function, isTrue);
      expect(js_util.getProperty(f, 'list') is List, isTrue);
      expect(js_util.getProperty(f, 'objectProperty') is Object, isTrue);
      expect(js_util.getProperty(f, 'toString') is Function, isTrue);
      js_util.setProperty(f, '__proto__', null);
      expect(js_util.getProperty(f, 'toString'), isNull);
    });

    test('typed literal', () {
      var literal = new ExampleTypedLiteral(a: 'x', b: 42);
      expect(js_util.getProperty(literal, 'a'), equals('x'));
      expect(js_util.getProperty(literal, 'b'), equals(42));
      expect(js_util.getProperty(literal, 'anything'), isNull);
    });

    test('complex getProperty calls', () {
      var f = new Foo(42);

      // Accessing a method property.
      expect(js_util.getProperty(f, 'bar') is Function, isTrue);
      expect(js_util.callMethod(f, 'bar', []), equals(42));

      // Accessing list properties.
      expect(js_util.getProperty(f, 'list')[0], equals(2));
      expect(js_util.getProperty(f, 'fnList')[0] is Function, isTrue);
      expect(
          js_util.callMethod(
              js_util.getProperty(f, 'fnList')[0], 'apply', [f, []]),
          equals(42));
      expect(js_util.getProperty(f.list, "0"), equals(2));
      var index = 0;
      expect(js_util.getProperty(f.list, index++), equals(2));
      expect(index, equals(1));
      expect(js_util.getProperty(f.list, index), equals(4));

      // Accessing nested object properites.
      var objectProperty = js_util.getProperty(f, 'objectProperty');
      expect(js_util.getProperty(objectProperty, 'c'), equals(1));
      expect(js_util.getProperty(objectProperty, 'list') is List, isTrue);
      expect(js_util.getProperty(objectProperty, 'list')[1], equals(20));
      expect(
          js_util.getProperty(objectProperty, 'functionProperty') is Function,
          isTrue);
      // Using nested getProperty calls.
      expect(
          js_util.getProperty(
              js_util.getProperty(
                  js_util.getProperty(f, 'objectProperty'), 'list'),
              1),
          equals(20));

      // Using a variable for the property name.
      String propertyName = 'a';
      expect(js_util.getProperty(f, propertyName), equals(42));
      String bar = _getBarWithSideEffect();
      expect(js_util.getProperty(f, bar) is Function, isTrue);
      expect(js_util.callMethod(f, bar, []), equals(42));
    });
  });

  group('setProperty', () {
    test('typed object', () {
      var f = new Foo(42);
      expect(js_util.getProperty(f, 'a'), equals(42));
      js_util.setProperty(f, 'a', 100);
      expect(f.a, equals(100));
      expect(js_util.getProperty(f, 'a'), equals(100));
      js_util.setProperty(f, 'a', null);
      expect(f.a, equals(null));

      expect(js_util.getProperty(f, 'list') is List, isTrue);
      js_util.setProperty(f, 'list', [8]);
      expect(js_util.getProperty(f, 'list') is List, isTrue);
      expect(js_util.getProperty(f, 'list')[0], equals(8));

      js_util.setProperty(f, 'newProperty', 'new');
      expect(js_util.getProperty(f, 'newProperty'), equals('new'));

      // Using a variable for the property value.
      var num = 4;
      js_util.setProperty(f, 'a', num);
      expect(f.a, equals(num));
      var str = 'bar';
      js_util.setProperty(f, 'a', str);
      expect(f.a, equals(str));
      var b = false;
      js_util.setProperty(f, 'a', b);
      expect(f.a, equals(b));
      var list = [2, 4, 6];
      js_util.setProperty(f, 'a', list);
      expect(f.a, equals(list));
      var fn = allowInterop(dartFunction);
      js_util.setProperty(f, 'a', fn);
      expect(f.a, equals(fn));
    });

    test('typed literal', () {
      var literal = new ExampleTypedLiteral();
      js_util.setProperty(literal, 'a', 'foo');
      expect(js_util.getProperty(literal, 'a'), equals('foo'));
      expect(literal.a, equals('foo'));
      js_util.setProperty(literal, 'a', literal);
      expect(identical(literal.a, literal), isTrue);
      var list = ['arr'];
      js_util.setProperty(literal, 'a', list);
      expect(identical(literal.a, list), isTrue);
    });

    test('complex setProperty calls', () {
      var f = new Foo(42);

      // Set function property to a num.
      expect(js_util.getProperty(f, 'bar') is Function, isTrue);
      js_util.setProperty(f, 'bar', 5);
      expect(js_util.getProperty(f, 'bar') is Function, isFalse);
      expect(js_util.getProperty(f, 'bar'), equals(5));

      // Set property to a Dart function.
      js_util.setProperty(f, 'bar', allowInterop(dartFunction));
      expect(js_util.getProperty(f, 'bar') is Function, isTrue);
      expect(js_util.callMethod(f, 'bar', []), equals('Dart Function'));
      js_util.setProperty(f, 'bar', allowInterop(() {
        return 'Inline';
      }));
      expect(js_util.callMethod(f, 'bar', []), equals('Inline'));

      // Set property to a JS function.
      js_util.setProperty(f, 'bar', allowInterop(jsFunction));
      expect(js_util.getProperty(f, 'bar') is Function, isTrue);
      expect(js_util.callMethod(f, 'bar', []), equals('JS Function'));

      // Set property with nested object properties.
      js_util.setProperty(f.objectProperty, 'c', 'new val');
      expect(js_util.getProperty(f.objectProperty, 'c'), equals('new val'));
      js_util.setProperty(f.objectProperty, 'list', [1, 2, 3]);
      expect(js_util.getProperty(f.objectProperty, 'list')[1], equals(2));
      // Using a nested getProperty call.
      js_util.setProperty(
          js_util.getProperty(f, 'objectProperty'), 'c', 'nested val');
      expect(js_util.getProperty(f.objectProperty, 'c'), equals('nested val'));

      // Using a variable for the property name.
      String propertyName = 'bar';
      js_util.setProperty(f, propertyName, 'foo');
      expect(js_util.getProperty(f, 'bar'), equals('foo'));
      String bar = _getBarWithSideEffect();
      js_util.setProperty(f, bar, 'baz');
      expect(js_util.getProperty(f, bar), equals('baz'));
      js_util.setProperty(f, _getBarWithSideEffect(), 'mumble');
      expect(js_util.getProperty(f, bar), equals('mumble'));

      // Set property to a function call.
      js_util.setProperty(f, 'a', dartFunction());
      String expected = dartFunction();
      expect(f.a, equals(expected));

      // Using a tearoff as the property value
      js_util.setProperty(f, 'tearoff', allowInterop(ExampleTearoff().foo));
      expect(js_util.callMethod(f, 'tearoff', []), equals(3));
    });
  });

  group('callMethod', () {
    test('typed object', () {
      var f = new Foo(42);
      expect(js_util.callMethod(f, 'bar', []), equals(42));
    });

    test('complex callMethod calls', () {
      var f = new Foo(42);

      // Call a method that returns an unbound function.
      expect(js_util.callMethod(f, 'nestedFunction', []) is Function, isTrue);
      expect(js_util.callMethod(f, 'nestedFunction', [])(),
          equals('Nested Function'));

      // Call method on a nested function property.
      expect(js_util.callMethod(f.objectProperty, 'functionProperty', []),
          equals('Function Property'));
      // Using a nested getProperty call.
      expect(
          js_util.callMethod(
              js_util.getProperty(f, 'objectProperty'), 'functionProperty', []),
          equals('Function Property'));

      // Call method with different args.
      expect(
          js_util.callMethod(f, 'getFirstEl', [
            [25, 50]
          ]),
          equals(25));
      expect(js_util.callMethod(f, 'sumFn', [2, 3]), equals(5));
      expect(js_util.callMethod(f, 'getA', [f]), equals(42));
      expect(js_util.callMethod(f, 'callFn', [allowInterop(jsFunction)]),
          equals("JS Function"));
      expect(js_util.callMethod(f, 'callFn', [allowInterop(dartFunction)]),
          equals("Dart Function"));
      expect(
          js_util.callMethod(f, 'callFn', [
            allowInterop(() {
              return "inline";
            })
          ]),
          equals("inline"));

      // Using a variable for the method name.
      String methodName = 'bar';
      expect(js_util.callMethod(f, methodName, []), equals(42));
      String bar = _getBarWithSideEffect();
      expect(js_util.callMethod(f, bar, []), equals(42));
    });
  });

  group('instanceof', () {
    test('typed object', () {
      var f = new Foo(42);
      expect(js_util.instanceof(f, JSFooType), isTrue);
      expect(js_util.instanceof(f, JSArrayBufferType), isFalse);
    });

    test('typed literal', () {
      var literal = new ExampleTypedLiteral();
      expect(js_util.instanceof(literal, JSFooType), isFalse);
    });
  });

  group('callConstructor', () {
    test('typed object', () {
      Foo f = js_util.callConstructor(JSFooType, [42]);
      expect(f.a, equals(42));
    });
  });
}
