1 // Copyright 2015 The Weave 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 "src/states/state_change_queue.h"
6
7 #include <gtest/gtest.h>
8 #include <weave/test/unittest_utils.h>
9
10 #include "src/bind_lambda.h"
11
12 namespace weave {
13
14 using test::CreateDictionaryValue;
15
16 class StateChangeQueueTest : public ::testing::Test {
17 public:
SetUp()18 void SetUp() override { queue_.reset(new StateChangeQueue(100)); }
19
TearDown()20 void TearDown() override { queue_.reset(); }
21
22 std::unique_ptr<StateChangeQueue> queue_;
23 };
24
TEST_F(StateChangeQueueTest,Empty)25 TEST_F(StateChangeQueueTest, Empty) {
26 EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
27 }
28
TEST_F(StateChangeQueueTest,UpdateOne)29 TEST_F(StateChangeQueueTest, UpdateOne) {
30 auto timestamp = base::Time::Now();
31 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
32 timestamp, *CreateDictionaryValue("{'prop': {'name': 23}}")));
33 auto changes = queue_->GetAndClearRecordedStateChanges();
34 ASSERT_EQ(1u, changes.size());
35 EXPECT_EQ(timestamp, changes.front().timestamp);
36 EXPECT_JSON_EQ("{'prop':{'name': 23}}", *changes.front().changed_properties);
37 EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
38 }
39
TEST_F(StateChangeQueueTest,UpdateMany)40 TEST_F(StateChangeQueueTest, UpdateMany) {
41 auto timestamp1 = base::Time::Now();
42 const std::string state1 = "{'prop': {'name1': 23}}";
43 auto timestamp2 = timestamp1 + base::TimeDelta::FromSeconds(1);
44 const std::string state2 =
45 "{'prop': {'name1': 17, 'name2': 1.0, 'name3': false}}";
46 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(timestamp1,
47 *CreateDictionaryValue(state1)));
48 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(timestamp2,
49 *CreateDictionaryValue(state2)));
50
51 auto changes = queue_->GetAndClearRecordedStateChanges();
52 ASSERT_EQ(2u, changes.size());
53 EXPECT_EQ(timestamp1, changes[0].timestamp);
54 EXPECT_JSON_EQ(state1, *changes[0].changed_properties);
55 EXPECT_EQ(timestamp2, changes[1].timestamp);
56 EXPECT_JSON_EQ(state2, *changes[1].changed_properties);
57 EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty());
58 }
59
TEST_F(StateChangeQueueTest,GroupByTimestamp)60 TEST_F(StateChangeQueueTest, GroupByTimestamp) {
61 base::Time timestamp = base::Time::Now();
62 base::TimeDelta time_delta = base::TimeDelta::FromMinutes(1);
63
64 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
65 timestamp, *CreateDictionaryValue("{'prop': {'name1': 1}}")));
66
67 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
68 timestamp, *CreateDictionaryValue("{'prop': {'name2': 2}}")));
69
70 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
71 timestamp, *CreateDictionaryValue("{'prop': {'name1': 3}}")));
72
73 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
74 timestamp + time_delta,
75 *CreateDictionaryValue("{'prop': {'name1': 4}}")));
76
77 auto changes = queue_->GetAndClearRecordedStateChanges();
78 ASSERT_EQ(2u, changes.size());
79
80 const std::string expected1 = "{'prop': {'name1': 3, 'name2': 2}}";
81 const std::string expected2 = "{'prop': {'name1': 4}}";
82 EXPECT_EQ(timestamp, changes[0].timestamp);
83 EXPECT_JSON_EQ(expected1, *changes[0].changed_properties);
84 EXPECT_EQ(timestamp + time_delta, changes[1].timestamp);
85 EXPECT_JSON_EQ(expected2, *changes[1].changed_properties);
86 }
87
TEST_F(StateChangeQueueTest,MaxQueueSize)88 TEST_F(StateChangeQueueTest, MaxQueueSize) {
89 queue_.reset(new StateChangeQueue(2));
90 base::Time start_time = base::Time::Now();
91 base::TimeDelta time_delta1 = base::TimeDelta::FromMinutes(1);
92 base::TimeDelta time_delta2 = base::TimeDelta::FromMinutes(3);
93
94 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
95 start_time,
96 *CreateDictionaryValue("{'prop': {'name1': 1, 'name2': 2}}")));
97
98 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
99 start_time + time_delta1,
100 *CreateDictionaryValue("{'prop': {'name1': 3, 'name3': 4}}")));
101
102 ASSERT_TRUE(queue_->NotifyPropertiesUpdated(
103 start_time + time_delta2,
104 *CreateDictionaryValue("{'prop': {'name10': 10, 'name11': 11}}")));
105
106 auto changes = queue_->GetAndClearRecordedStateChanges();
107 ASSERT_EQ(2u, changes.size());
108
109 const std::string expected1 =
110 "{'prop': {'name1': 3, 'name2': 2, 'name3': 4}}";
111 EXPECT_EQ(start_time + time_delta1, changes[0].timestamp);
112 EXPECT_JSON_EQ(expected1, *changes[0].changed_properties);
113
114 const std::string expected2 = "{'prop': {'name10': 10, 'name11': 11}}";
115 EXPECT_EQ(start_time + time_delta2, changes[1].timestamp);
116 EXPECT_JSON_EQ(expected2, *changes[1].changed_properties);
117 }
118
119 } // namespace weave
120