Bug 1289315 - Tests for Iterable<> Union Types in WebIDL Interfaces; r=bz
authorKyle Machulis <kyle@nonpolynomial.com>
Wed, 27 Jul 2016 09:46:02 -0700
changeset 346961 44d0ef641fa71923e29f50b130fd604144951d58
parent 346960 ae6fac030deb0b8d2823cb59f87378056320eafb
child 346962 b807e09863ff0d989aa95f1d5176cb983b1d7789
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1289315
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1289315 - Tests for Iterable<> Union Types in WebIDL Interfaces; r=bz MozReview-Commit-ID: 1co6k6YOPUI
dom/bindings/moz.build
dom/bindings/test/TestInterfaceIterableDoubleUnion.cpp
dom/bindings/test/TestInterfaceIterableDoubleUnion.h
dom/bindings/test/test_iterable.html
dom/webidl/TestInterfaceJSMaplikeSetlikeIterable.webidl
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -104,25 +104,27 @@ SOURCES += [
 # must be included in libxul. This breaks the "no test classes are exported"
 # rule stated in the test/ directory, but it's the only way this will work.
 # Test classes are only built in debug mode, and all tests requiring use of
 # them are only run in debug mode.
 if CONFIG['MOZ_DEBUG']:
     EXPORTS.mozilla.dom += [
         "test/TestFunctions.h",
         "test/TestInterfaceIterableDouble.h",
+        "test/TestInterfaceIterableDoubleUnion.h",
         "test/TestInterfaceIterableSingle.h",
         "test/TestInterfaceMaplike.h",
         "test/TestInterfaceMaplikeObject.h",
         "test/TestInterfaceSetlike.h",
         "test/TestInterfaceSetlikeNode.h"
         ]
     UNIFIED_SOURCES += [
         "test/TestFunctions.cpp",
         "test/TestInterfaceIterableDouble.cpp",
+        "test/TestInterfaceIterableDoubleUnion.cpp",
         "test/TestInterfaceIterableSingle.cpp",
         "test/TestInterfaceMaplike.cpp",
         "test/TestInterfaceMaplikeObject.cpp",
         "test/TestInterfaceSetlike.cpp",
         "test/TestInterfaceSetlikeNode.cpp",
         ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
new file mode 100644
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceIterableDoubleUnion.cpp
@@ -0,0 +1,83 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/TestInterfaceIterableDoubleUnion.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceIterableDoubleUnion, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceIterableDoubleUnion)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceIterableDoubleUnion)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceIterableDoubleUnion)
+NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceIterableDoubleUnion::TestInterfaceIterableDoubleUnion(nsPIDOMWindowInner* aParent)
+  : mParent(aParent)
+{
+  OwningStringOrLong a;
+  a.SetAsLong() = 1;
+  mValues.AppendElement(std::pair<nsString, OwningStringOrLong>(NS_LITERAL_STRING("long"),
+                                                                a));
+  a.SetAsString() = NS_LITERAL_STRING("a");
+  mValues.AppendElement(std::pair<nsString, OwningStringOrLong>(NS_LITERAL_STRING("string"),
+                                                                a));
+}
+
+//static
+already_AddRefed<TestInterfaceIterableDoubleUnion>
+TestInterfaceIterableDoubleUnion::Constructor(const GlobalObject& aGlobal,
+                                              ErrorResult& aRv)
+{
+  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
+  if (!window) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  RefPtr<TestInterfaceIterableDoubleUnion> r = new TestInterfaceIterableDoubleUnion(window);
+  return r.forget();
+}
+
+JSObject*
+TestInterfaceIterableDoubleUnion::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return TestInterfaceIterableDoubleUnionBinding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner*
+TestInterfaceIterableDoubleUnion::GetParentObject() const
+{
+  return mParent;
+}
+
+size_t
+TestInterfaceIterableDoubleUnion::GetIterableLength()
+{
+  return mValues.Length();
+}
+
+nsAString&
+TestInterfaceIterableDoubleUnion::GetKeyAtIndex(uint32_t aIndex)
+{
+  MOZ_ASSERT(aIndex < mValues.Length());
+  return mValues.ElementAt(aIndex).first;
+}
+
+OwningStringOrLong&
+TestInterfaceIterableDoubleUnion::GetValueAtIndex(uint32_t aIndex)
+{
+  MOZ_ASSERT(aIndex < mValues.Length());
+  return mValues.ElementAt(aIndex).second;
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceIterableDoubleUnion.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_TestInterfaceIterableDoubleUnion_h
+#define mozilla_dom_TestInterfaceIterableDoubleUnion_h
+
+#include "nsWrapperCache.h"
+#include "nsCOMPtr.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl iterable interfaces, using
+// primitives for value type
+class TestInterfaceIterableDoubleUnion final : public nsISupports,
+                                               public nsWrapperCache
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TestInterfaceIterableDoubleUnion)
+
+  explicit TestInterfaceIterableDoubleUnion(nsPIDOMWindowInner* aParent);
+  nsPIDOMWindowInner* GetParentObject() const;
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+  static already_AddRefed<TestInterfaceIterableDoubleUnion>
+    Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
+
+  size_t GetIterableLength();
+  nsAString& GetKeyAtIndex(uint32_t aIndex);
+  OwningStringOrLong& GetValueAtIndex(uint32_t aIndex);
+private:
+  virtual ~TestInterfaceIterableDoubleUnion() {}
+  nsCOMPtr<nsPIDOMWindowInner> mParent;
+  nsTArray<std::pair<nsString, OwningStringOrLong>> mValues;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceIterableDoubleUnion_h
--- a/dom/bindings/test/test_iterable.html
+++ b/dom/bindings/test/test_iterable.html
@@ -169,13 +169,73 @@
        is(value.value, undefined, "IterableDouble: Value iterator value should be undefined");
        is(value.done, true, "IterableDouble: Value iterator done should be true");
        is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
        is(entry.done, true, "IterableDouble: Entry iterator done should be true");
        is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
           "[object TestInterfaceIterableDoubleIteratorPrototype]",
           "iterator prototype should have the right brand");
 
+       // Simple dual type iterable creation and functionality test
+       info("IterableDoubleUnion: Testing simple iterable creation and functionality");
+       itr = new TestInterfaceIterableDoubleUnion();
+       testExistence("IterableDoubleUnion: ", itr, base_properties);
+       is(itr.entries, itr[Symbol.iterator],
+          "IterableDoubleUnion: Should be using @@iterator for 'entries'");
+       var elements = [["long", 1], ["string", "a"]]
+       var keys = [...itr.keys()];
+       var values = [...itr.values()];
+       var entries = [...itr.entries()];
+       var key_itr = itr.keys();
+       var value_itr = itr.values();
+       var entries_itr = itr.entries();
+       for (var i = 0; i < elements.length; ++i) {
+         var key = key_itr.next();
+         var value = value_itr.next();
+         var entry = entries_itr.next();
+         is(key.value, elements[i][0], "IterableDoubleUnion: Key iterator value should be " + elements[i][0]);
+         is(key.value, keys[i],
+            "IterableDoubleUnion: Key iterator value should match destructuring " + i);
+         is(value.value, elements[i][1], "IterableDoubleUnion: Value iterator value should be " + elements[i][1]);
+         is(value.value, values[i],
+            "IterableDoubleUnion: Value iterator value should match destructuring " + i);
+         is(entry.value[0], elements[i][0], "IterableDoubleUnion: Entry iterator value 0 should be " + elements[i][0]);
+         is(entry.value[1], elements[i][1], "IterableDoubleUnion: Entry iterator value 1 should be " + elements[i][1]);
+         is(entry.value[0], entries[i][0],
+            "IterableDoubleUnion: Entry iterator value 0 should match destructuring " + i);
+         is(entry.value[1], entries[i][1],
+            "IterableDoubleUnion: Entry iterator value 1 should match destructuring " + i);
+       }
+
+       callsToForEachCallback = 0;
+       thisArg = {};
+       itr.forEach(function(value, key, obj) {
+         is(key, keys[callsToForEachCallback],
+            `IterableDoubleUnion: Should have the right key at ${callsToForEachCallback} calls to forEach callback`);
+         is(value, values[callsToForEachCallback],
+            `IterableDoubleUnion: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
+         is(this, thisArg,
+            "IterableDoubleUnion: Should have the right this value for forEach callback");
+         is(obj, itr,
+            "IterableSingle: Should have the right third arg for forEach callback");
+         ++callsToForEachCallback;
+       }, thisArg);
+       is(callsToForEachCallback, 2,
+          "IterableDoubleUnion: Should have right total number of calls to forEach callback");
+
+       var key = key_itr.next();
+       var value = value_itr.next();
+       var entry = entries_itr.next()
+       is(key.value, undefined, "IterableDoubleUnion: Key iterator value should be undefined");
+       is(key.done, true, "IterableDoubleUnion: Key iterator done should be true");
+       is(value.value, undefined, "IterableDoubleUnion: Value iterator value should be undefined");
+       is(value.done, true, "IterableDoubleUnion: Value iterator done should be true");
+       is(entry.value, undefined, "IterableDoubleUnion: Entry iterator value should be undefined");
+       is(entry.done, true, "IterableDoubleUnion: Entry iterator done should be true");
+       is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
+          "[object TestInterfaceIterableDoubleUnionIteratorPrototype]",
+          "iterator prototype should have the right brand");
+
        SimpleTest.finish();
      });
     </script>
   </body>
 </html>
--- a/dom/webidl/TestInterfaceJSMaplikeSetlikeIterable.webidl
+++ b/dom/webidl/TestInterfaceJSMaplikeSetlikeIterable.webidl
@@ -55,8 +55,14 @@ interface TestInterfaceIterableSingle {
 };
 
 [Constructor(),
  Pref="dom.expose_test_interfaces"]
 interface TestInterfaceIterableDouble {
   iterable<DOMString, DOMString>;
 };
 
+[Constructor(),
+ Pref="dom.expose_test_interfaces"]
+interface TestInterfaceIterableDoubleUnion {
+  iterable<DOMString, (DOMString or long)>;
+};
+