1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/strings/stringprintf.h"
6 #include "chrome/test/base/module_system_test.h"
7 #include "grit/renderer_resources.h"
8
9 namespace extensions {
10 namespace {
11
12 class MessagingUtilsUnittest : public ModuleSystemTest {
13 protected:
RegisterTestModule(const char * code)14 void RegisterTestModule(const char* code) {
15 RegisterModule("test", base::StringPrintf(
16 "var assert = requireNative('assert');\n"
17 "var AssertTrue = assert.AssertTrue;\n"
18 "var AssertFalse = assert.AssertFalse;\n"
19 "var messagingUtils = require('messaging_utils');\n"
20 "%s", code));
21 }
22
23 private:
SetUp()24 virtual void SetUp() OVERRIDE {
25 ModuleSystemTest::SetUp();
26
27 RegisterModule("messaging_utils", IDR_MESSAGING_UTILS_JS);
28 }
29
30 };
31
TEST_F(MessagingUtilsUnittest,TestNothing)32 TEST_F(MessagingUtilsUnittest, TestNothing) {
33 ExpectNoAssertionsMade();
34 }
35
TEST_F(MessagingUtilsUnittest,NoArguments)36 TEST_F(MessagingUtilsUnittest, NoArguments) {
37 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
38 RegisterTestModule(
39 "var args = messagingUtils.alignSendMessageArguments();\n"
40 "AssertTrue(args === null);");
41 module_system_->Require("test");
42 }
43
TEST_F(MessagingUtilsUnittest,ZeroArguments)44 TEST_F(MessagingUtilsUnittest, ZeroArguments) {
45 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
46 RegisterTestModule(
47 "var args = messagingUtils.alignSendMessageArguments([]);"
48 "AssertTrue(args === null);");
49 module_system_->Require("test");
50 }
51
TEST_F(MessagingUtilsUnittest,TooManyArgumentsNoOptions)52 TEST_F(MessagingUtilsUnittest, TooManyArgumentsNoOptions) {
53 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
54 RegisterTestModule(
55 "var args = messagingUtils.alignSendMessageArguments(\n"
56 " ['a', 'b', 'c', 'd']);\n"
57 "AssertTrue(args === null);");
58 module_system_->Require("test");
59 }
60
TEST_F(MessagingUtilsUnittest,TooManyArgumentsWithOptions)61 TEST_F(MessagingUtilsUnittest, TooManyArgumentsWithOptions) {
62 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
63 RegisterTestModule(
64 "var args = messagingUtils.alignSendMessageArguments(\n"
65 " ['a', 'b', 'c', 'd', 'e'], true);\n"
66 "AssertTrue(args === null);");
67 module_system_->Require("test");
68 }
69
TEST_F(MessagingUtilsUnittest,FinalArgumentIsNotAFunctionNoOptions)70 TEST_F(MessagingUtilsUnittest, FinalArgumentIsNotAFunctionNoOptions) {
71 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
72 RegisterTestModule(
73 "var args = messagingUtils.alignSendMessageArguments(\n"
74 " ['a', 'b', 'c']);\n"
75 "AssertTrue(args === null);");
76 module_system_->Require("test");
77 }
78
TEST_F(MessagingUtilsUnittest,FinalArgumentIsNotAFunctionWithOptions)79 TEST_F(MessagingUtilsUnittest, FinalArgumentIsNotAFunctionWithOptions) {
80 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
81 RegisterTestModule(
82 "var args = messagingUtils.alignSendMessageArguments(\n"
83 " ['a', 'b', 'c', 'd'], true);\n"
84 "AssertTrue(args === null);");
85 module_system_->Require("test");
86 }
87
TEST_F(MessagingUtilsUnittest,OneStringArgument)88 TEST_F(MessagingUtilsUnittest, OneStringArgument) {
89 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
90 // Because the request argument is required, a single argument must get
91 // mapped to it rather than to the optional targetId argument.
92 RegisterTestModule(
93 "var args = messagingUtils.alignSendMessageArguments(['a']);\n"
94 "AssertTrue(args.length == 3);\n"
95 "AssertTrue(args[0] === null);\n"
96 "AssertTrue(args[1] == 'a');\n"
97 "AssertTrue(args[2] === null);");
98 module_system_->Require("test");
99 }
100
TEST_F(MessagingUtilsUnittest,OneStringAndOneNullArgument)101 TEST_F(MessagingUtilsUnittest, OneStringAndOneNullArgument) {
102 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
103 // Explicitly specifying null as the request is allowed.
104 RegisterTestModule(
105 "var args = messagingUtils.alignSendMessageArguments(['a', null]);\n"
106 "AssertTrue(args.length == 3);\n"
107 "AssertTrue(args[0] == 'a');\n"
108 "AssertTrue(args[1] === null);\n"
109 "AssertTrue(args[2] === null);");
110 module_system_->Require("test");
111 }
112
TEST_F(MessagingUtilsUnittest,OneNullAndOneStringArgument)113 TEST_F(MessagingUtilsUnittest, OneNullAndOneStringArgument) {
114 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
115 RegisterTestModule(
116 "var args = messagingUtils.alignSendMessageArguments([null, 'a']);\n"
117 "AssertTrue(args.length == 3);\n"
118 "AssertTrue(args[0] === null);\n"
119 "AssertTrue(args[1] == 'a');\n"
120 "AssertTrue(args[2] === null);");
121 module_system_->Require("test");
122 }
123
TEST_F(MessagingUtilsUnittest,OneStringAndOneFunctionArgument)124 TEST_F(MessagingUtilsUnittest, OneStringAndOneFunctionArgument) {
125 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
126 // When the arguments are a string and a function, the function is
127 // unambiguously the responseCallback. Because the request argument is
128 // required, the remaining argument must get mapped to it rather than to the
129 // optional targetId argument.
130 RegisterTestModule(
131 "var cb = function() {};\n"
132 "var args = messagingUtils.alignSendMessageArguments(['a', cb]);\n"
133 "AssertTrue(args.length == 3);\n"
134 "AssertTrue(args[0] === null);\n"
135 "AssertTrue(args[1] == 'a');\n"
136 "AssertTrue(args[2] == cb);");
137 module_system_->Require("test");
138 }
139
TEST_F(MessagingUtilsUnittest,OneStringAndOneObjectArgument)140 TEST_F(MessagingUtilsUnittest, OneStringAndOneObjectArgument) {
141 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
142 // This tests an ambiguous set of arguments when options are present:
143 // chrome.runtime.sendMessage('target', {'msg': 'this is a message'});
144 // vs.
145 // chrome.runtime.sendMessage('request', {'includeTlsChannelId': true});
146 //
147 // The question is whether the string should map to the target and the
148 // dictionary to the message, or whether the string should map to the message
149 // and the dictionary to the options. Because the target and message arguments
150 // predate the options argument, we bind the string in this case to the
151 // targetId.
152 RegisterTestModule(
153 "var obj = {'b': true};\n"
154 "var args = messagingUtils.alignSendMessageArguments(['a', obj], true);\n"
155 "AssertTrue(args.length == 4);\n"
156 "AssertTrue(args[0] == 'a');\n"
157 "AssertTrue(args[1] == obj);\n"
158 "AssertTrue(args[2] === null);\n"
159 "AssertTrue(args[3] === null);");
160 module_system_->Require("test");
161 }
162
TEST_F(MessagingUtilsUnittest,TwoObjectArguments)163 TEST_F(MessagingUtilsUnittest, TwoObjectArguments) {
164 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
165 // When two non-string arguments are provided and options are present, the
166 // two arguments must match request and options, respectively, because
167 // targetId must be a string.
168 RegisterTestModule(
169 "var obj1 = {'a': 'foo'};\n"
170 "var obj2 = {'b': 'bar'};\n"
171 "var args = messagingUtils.alignSendMessageArguments(\n"
172 " [obj1, obj2], true);\n"
173 "AssertTrue(args.length == 4);\n"
174 "AssertTrue(args[0] === null);\n"
175 "AssertTrue(args[1] == obj1);\n"
176 "AssertTrue(args[2] == obj2);\n"
177 "AssertTrue(args[3] === null);");
178 module_system_->Require("test");
179 }
180
181 } // namespace
182 } // namespace extensions
183