blob: 14f310c471f7b067bac6bfb1c948ce13a76b5a2a [file] [log] [blame]
// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
#include "omaha/plugins/update/npapi/dispatch_host.h"
#include <atlbase.h>
#include <atlcom.h>
#include <string.h>
#include <vector>
#include "omaha/plugins/update/npapi/testing/dispatch_host_test_interface.h"
#include "omaha/plugins/update/npapi/testing/stubs.h"
#include "omaha/testing/unit_test.h"
namespace omaha {
class DispatchHostTest : public testing::Test {
protected:
virtual void SetUp() {
CComPtr<IDispatch> dispatch;
ASSERT_SUCCEEDED(
CComCoClass<DispatchHostTestInterface>::CreateInstance(&dispatch));
dispatch_host_ = NPN_CreateObject(NULL, &DispatchHost::kNPClass_);
static_cast<DispatchHost*>(dispatch_host_)->dispatch_ = dispatch.Detach();
VOID_TO_NPVARIANT(result_);
}
virtual void TearDown() {
NPN_ReleaseObject(dispatch_host_);
for (std::vector<NPVariant>::iterator it = args_.begin();
it != args_.end(); ++it) {
NPN_ReleaseVariantValue(&*it);
}
NPN_ReleaseVariantValue(&result_);
}
void UseTestInterface2() {
NPN_ReleaseObject(dispatch_host_);
CComPtr<IDispatch> dispatch;
ASSERT_SUCCEEDED(
CComCoClass<DispatchHostTestInterface2>::CreateInstance(&dispatch));
dispatch_host_ = NPN_CreateObject(NULL, &DispatchHost::kNPClass_);
static_cast<DispatchHost*>(dispatch_host_)->dispatch_ = dispatch.Detach();
}
void PushArg(bool value) {
args_.push_back(NPVariant());
BOOLEAN_TO_NPVARIANT(value, args_.back());
}
void PushArg(int32 value) {
args_.push_back(NPVariant());
INT32_TO_NPVARIANT(value, args_.back());
}
void PushArg(double value) {
args_.push_back(NPVariant());
DOUBLE_TO_NPVARIANT(value, args_.back());
}
void PushArg(const char* value) {
args_.push_back(NPVariant());
// TODO(omaha): _strdup is an implementation detail of the stubs.
STRINGZ_TO_NPVARIANT(_strdup(value), args_.back());
}
NPObject* dispatch_host_;
NPIdentifierFactory id_factory_;
std::vector<NPVariant> args_;
NPVariant result_;
};
TEST_F(DispatchHostTest, HasMethod) {
EXPECT_TRUE(NPN_HasMethod(NULL, dispatch_host_,
id_factory_.Create("Random")));
EXPECT_TRUE(NPN_HasMethod(NULL, dispatch_host_,
id_factory_.Create("AddAsMethod")));
// Property getters with input arguments should be treated as methods.
EXPECT_TRUE(NPN_HasMethod(NULL, dispatch_host_,
id_factory_.Create("AddAsProperty")));
// Properties and non-existent members are not methods.
EXPECT_FALSE(NPN_HasMethod(NULL, dispatch_host_,
id_factory_.Create("Property")));
EXPECT_FALSE(NPN_HasMethod(NULL, dispatch_host_,
id_factory_.Create("ReadOnlyProperty")));
EXPECT_FALSE(NPN_HasMethod(NULL, dispatch_host_,
id_factory_.Create("WriteOnlyProperty")));
EXPECT_FALSE(NPN_HasMethod(NULL, dispatch_host_,
id_factory_.Create("DoesNotExist")));
}
TEST_F(DispatchHostTest, InvokeNoArgs) {
EXPECT_TRUE(NPN_Invoke(NULL, dispatch_host_, id_factory_.Create("Random"),
NULL, 0, &result_));
EXPECT_TRUE(NPVARIANT_IS_INT32(result_));
EXPECT_EQ(42, result_.value.intValue);
}
TEST_F(DispatchHostTest, InvokeWithArgs) {
PushArg(7);
PushArg(27);
EXPECT_TRUE(NPN_Invoke(NULL, dispatch_host_,
id_factory_.Create("AddAsMethod"), &args_.front(),
args_.size(), &result_));
EXPECT_TRUE(NPVARIANT_IS_INT32(result_));
EXPECT_EQ(34, result_.value.intValue);
}
TEST_F(DispatchHostTest, InvokePropertyWithArgs) {
// Property getters that have input args should be handle by Invoke
PushArg(8);
PushArg(15);
EXPECT_TRUE(NPN_Invoke(NULL, dispatch_host_,
id_factory_.Create("AddAsProperty"), &args_.front(),
args_.size(), &result_));
EXPECT_TRUE(NPVARIANT_IS_INT32(result_));
EXPECT_EQ(23, result_.value.intValue);
}
TEST_F(DispatchHostTest, InvokeNonexistentMethod) {
// Non-existent method, should fail.
INT32_TO_NPVARIANT(0x19821982, result_);
EXPECT_FALSE(NPN_Invoke(NULL, dispatch_host_,
id_factory_.Create("NonExistent"), NULL, 0,
&result_));
EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
}
TEST_F(DispatchHostTest, InvokeWithIncompatibleArgs) {
PushArg("Hello World!");
PushArg(0x19851985);
INT32_TO_NPVARIANT(0x19881988, result_);
EXPECT_FALSE(NPN_Invoke(NULL, dispatch_host_,
id_factory_.Create("AddAsMethod"), &args_.front(),
args_.size(), &result_));
EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
}
TEST_F(DispatchHostTest, InvokeWithIncorrectNumberOfArgs) {
PushArg("Don't panic.");
INT32_TO_NPVARIANT(0x77777777, result_);
EXPECT_FALSE(NPN_Invoke(NULL, dispatch_host_, id_factory_.Create("Random"),
&args_.front(), args_.size(), &result_));
EXPECT_TRUE(NPVARIANT_IS_VOID(result_));
}
TEST_F(DispatchHostTest, InvokeDefault) {
EXPECT_TRUE(NPN_InvokeDefault(NULL, dispatch_host_, NULL, 0, &result_));
EXPECT_TRUE(NPVARIANT_IS_OBJECT(result_));
}
TEST_F(DispatchHostTest, InvokeDefaultPropertyWithArgs) {
UseTestInterface2();
PushArg(1048576);
EXPECT_TRUE(NPN_InvokeDefault(NULL, dispatch_host_, &args_.front(),
args_.size(), &result_));
EXPECT_TRUE(NPVARIANT_IS_INT32(result_));
EXPECT_EQ(1048576 * 2, result_.value.intValue);
}
// TODO(omaha): implement negative test
TEST_F(DispatchHostTest, HasProperty) {
EXPECT_TRUE(NPN_HasProperty(NULL, dispatch_host_,
id_factory_.Create("Property")));
EXPECT_TRUE(NPN_HasProperty(NULL, dispatch_host_,
id_factory_.Create("ReadOnlyProperty")));
EXPECT_TRUE(NPN_HasProperty(NULL, dispatch_host_,
id_factory_.Create("WriteOnlyProperty")));
// Property getters with input arguments should not be treated as properties.
EXPECT_FALSE(NPN_HasProperty(NULL, dispatch_host_,
id_factory_.Create("AddAsProperty")));
// Methods and non-existent members are not properties.
EXPECT_FALSE(NPN_HasProperty(NULL, dispatch_host_,
id_factory_.Create("Random")));
EXPECT_FALSE(NPN_HasProperty(NULL, dispatch_host_,
id_factory_.Create("DoesNotExist")));
}
TEST_F(DispatchHostTest, GetProperty) {
EXPECT_TRUE(NPN_GetProperty(NULL, dispatch_host_,
id_factory_.Create("Property"), &result_));
EXPECT_TRUE(NPVARIANT_IS_INT32(result_));
EXPECT_EQ(0xdeadbeef, result_.value.intValue);
}
TEST_F(DispatchHostTest, GetPropertyReadOnly) {
EXPECT_TRUE(NPN_GetProperty(NULL, dispatch_host_,
id_factory_.Create("ReadOnlyProperty"),
&result_));
EXPECT_TRUE(NPVARIANT_IS_INT32(result_));
EXPECT_EQ(19700101, result_.value.intValue);
}
TEST_F(DispatchHostTest, SetProperty) {
PushArg(20002000);
EXPECT_TRUE(NPN_SetProperty(NULL, dispatch_host_,
id_factory_.Create("Property"), &args_.front()));
}
TEST_F(DispatchHostTest, SetPropertyWriteOnly) {
PushArg(20612061);
EXPECT_TRUE(NPN_SetProperty(NULL, dispatch_host_,
id_factory_.Create("WriteOnlyProperty"),
&args_.front()));
}
TEST_F(DispatchHostTest, Unsupported) {
EXPECT_FALSE(NPN_RemoveProperty(NULL, dispatch_host_, NULL));
EXPECT_FALSE(NPN_Enumerate(NULL, dispatch_host_, NULL, NULL));
EXPECT_FALSE(NPN_Construct(NULL, dispatch_host_, NULL, 0, NULL));
}
} // namespace omaha