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 12namespace weave { 13 14using test::CreateDictionaryValue; 15 16class StateChangeQueueTest : public ::testing::Test { 17 public: 18 void SetUp() override { queue_.reset(new StateChangeQueue(100)); } 19 20 void TearDown() override { queue_.reset(); } 21 22 std::unique_ptr<StateChangeQueue> queue_; 23}; 24 25TEST_F(StateChangeQueueTest, Empty) { 26 EXPECT_TRUE(queue_->GetAndClearRecordedStateChanges().empty()); 27} 28 29TEST_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 40TEST_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 60TEST_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 88TEST_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