blob: ace0738672fb098ce1e2eaf90f920ef7904faee5 [file] [log] [blame]
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -07001// Copyright 2014 The Chromium OS 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 <gtest/gtest.h>
6
Alex Vakulenko8dc69af2014-08-07 10:29:42 -07007#include "buffet/commands/command_dictionary.h"
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -07008#include "buffet/commands/command_instance.h"
9#include "buffet/commands/prop_types.h"
Alex Vakulenko8dc69af2014-08-07 10:29:42 -070010#include "buffet/commands/unittest_utils.h"
11
12using buffet::unittests::CreateDictionaryValue;
13using buffet::unittests::CreateValue;
14
15namespace {
16
17class CommandInstanceTest : public ::testing::Test {
18 protected:
Alex Vakulenko5a9e7182014-08-11 15:59:58 -070019 void SetUp() override {
Alex Vakulenko8dc69af2014-08-07 10:29:42 -070020 auto json = CreateDictionaryValue(R"({
21 'base': {
22 'reboot': {
23 'parameters': {}
24 }
25 },
26 'robot': {
27 'jump': {
28 'parameters': {
29 'height': {
30 'type': 'integer',
31 'minimum': 0,
32 'maximum': 100
33 },
34 '_jumpType': {
35 'type': 'string',
36 'enum': ['_withAirFlip', '_withSpin', '_withKick']
37 }
38 }
39 },
40 'speak': {
41 'parameters': {
42 'phrase': {
43 'type': 'string',
44 'enum': ['beamMeUpScotty', 'iDontDigOnSwine',
45 'iPityDaFool', 'dangerWillRobinson']
46 },
47 'volume': {
48 'type': 'integer',
49 'minimum': 0,
50 'maximum': 10
51 }
52 }
53 }
54 }
55 })");
56 CHECK(dict_.LoadCommands(*json, "robotd", nullptr, nullptr))
57 << "Failed to parse test command dictionary";
58 }
59 buffet::CommandDictionary dict_;
60};
61
62} // anonymous namespace
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070063
64TEST(CommandInstance, Test) {
65 buffet::native_types::Object params;
66 buffet::IntPropType int_prop;
67 buffet::DoublePropType dbl_prop;
68 params.insert(std::make_pair("freq", dbl_prop.CreateValue(800.5)));
69 params.insert(std::make_pair("volume", int_prop.CreateValue(100)));
70 buffet::CommandInstance instance("robot._beep", "robotd", params);
71
72 EXPECT_EQ("robot._beep", instance.GetName());
73 EXPECT_EQ("robotd", instance.GetCategory());
74 EXPECT_EQ(params, instance.GetParameters());
75 EXPECT_DOUBLE_EQ(800.5,
76 instance.FindParameter("freq")->GetDouble()->GetValue());
77 EXPECT_EQ(100, instance.FindParameter("volume")->GetInt()->GetValue());
78 EXPECT_EQ(nullptr, instance.FindParameter("blah").get());
79}
Alex Vakulenko8dc69af2014-08-07 10:29:42 -070080
81TEST_F(CommandInstanceTest, FromJson) {
82 auto json = CreateDictionaryValue(R"({
83 'name': 'robot.jump',
84 'parameters': {
85 'height': 53,
86 '_jumpType': '_withKick'
87 }
88 })");
89 auto instance = buffet::CommandInstance::FromJson(json.get(), dict_, nullptr);
90 EXPECT_EQ("robot.jump", instance->GetName());
91 EXPECT_EQ("robotd", instance->GetCategory());
92 EXPECT_EQ(53, instance->FindParameter("height")->GetInt()->GetValue());
93 EXPECT_EQ("_withKick",
94 instance->FindParameter("_jumpType")->GetString()->GetValue());
95}
96
97TEST_F(CommandInstanceTest, FromJson_ParamsOmitted) {
98 auto json = CreateDictionaryValue("{'name': 'base.reboot'}");
99 auto instance = buffet::CommandInstance::FromJson(json.get(), dict_, nullptr);
100 EXPECT_EQ("base.reboot", instance->GetName());
101 EXPECT_EQ("robotd", instance->GetCategory());
102 EXPECT_TRUE(instance->GetParameters().empty());
103}
104
105TEST_F(CommandInstanceTest, FromJson_NotObject) {
106 auto json = CreateValue("'string'");
Alex Vakulenko5f472062014-08-14 17:54:04 -0700107 chromeos::ErrorPtr error;
Alex Vakulenko8dc69af2014-08-07 10:29:42 -0700108 auto instance = buffet::CommandInstance::FromJson(json.get(), dict_, &error);
109 EXPECT_EQ(nullptr, instance.get());
110 EXPECT_EQ("json_object_expected", error->GetCode());
111 EXPECT_EQ("Command instance is not a JSON object", error->GetMessage());
112}
113
114TEST_F(CommandInstanceTest, FromJson_NameMissing) {
115 auto json = CreateDictionaryValue("{'param': 'value'}");
Alex Vakulenko5f472062014-08-14 17:54:04 -0700116 chromeos::ErrorPtr error;
Alex Vakulenko8dc69af2014-08-07 10:29:42 -0700117 auto instance = buffet::CommandInstance::FromJson(json.get(), dict_, &error);
118 EXPECT_EQ(nullptr, instance.get());
119 EXPECT_EQ("parameter_missing", error->GetCode());
120 EXPECT_EQ("Command name is missing", error->GetMessage());
121}
122
123TEST_F(CommandInstanceTest, FromJson_UnknownCommand) {
124 auto json = CreateDictionaryValue("{'name': 'robot.scream'}");
Alex Vakulenko5f472062014-08-14 17:54:04 -0700125 chromeos::ErrorPtr error;
Alex Vakulenko8dc69af2014-08-07 10:29:42 -0700126 auto instance = buffet::CommandInstance::FromJson(json.get(), dict_, &error);
127 EXPECT_EQ(nullptr, instance.get());
128 EXPECT_EQ("invalid_command_name", error->GetCode());
129 EXPECT_EQ("Unknown command received: robot.scream", error->GetMessage());
130}
131
132TEST_F(CommandInstanceTest, FromJson_ParamsNotObject) {
133 auto json = CreateDictionaryValue(R"({
134 'name': 'robot.speak',
135 'parameters': 'hello'
136 })");
Alex Vakulenko5f472062014-08-14 17:54:04 -0700137 chromeos::ErrorPtr error;
Alex Vakulenko8dc69af2014-08-07 10:29:42 -0700138 auto instance = buffet::CommandInstance::FromJson(json.get(), dict_, &error);
139 EXPECT_EQ(nullptr, instance.get());
140 auto inner = error->GetInnerError();
141 EXPECT_EQ("json_object_expected", inner->GetCode());
142 EXPECT_EQ("Property 'parameters' must be a JSON object", inner->GetMessage());
143 EXPECT_EQ("command_failed", error->GetCode());
144 EXPECT_EQ("Failed to validate command 'robot.speak'", error->GetMessage());
145}
146
147TEST_F(CommandInstanceTest, FromJson_ParamError) {
148 auto json = CreateDictionaryValue(R"({
149 'name': 'robot.speak',
150 'parameters': {
151 'phrase': 'iPityDaFool',
152 'volume': 20
153 }
154 })");
Alex Vakulenko5f472062014-08-14 17:54:04 -0700155 chromeos::ErrorPtr error;
Alex Vakulenko8dc69af2014-08-07 10:29:42 -0700156 auto instance = buffet::CommandInstance::FromJson(json.get(), dict_, &error);
157 EXPECT_EQ(nullptr, instance.get());
158 auto first = error->GetFirstError();
159 EXPECT_EQ("out_of_range", first->GetCode());
160 EXPECT_EQ("Value 20 is out of range. It must not be greater than 10",
161 first->GetMessage());
162 auto inner = error->GetInnerError();
163 EXPECT_EQ("invalid_parameter_value", inner->GetCode());
164 EXPECT_EQ("Invalid parameter value for property 'volume'",
165 inner->GetMessage());
166 EXPECT_EQ("command_failed", error->GetCode());
167 EXPECT_EQ("Failed to validate command 'robot.speak'", error->GetMessage());
168}