Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: base/observer_list_unittest.cc

Issue 2340583005: Base ObserverList: Add basic support for standard C++ iterators. (Closed)
Patch Set: Add a comment on MSVC. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« base/observer_list.h ('K') | « base/observer_list.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/observer_list.h" 5 #include "base/observer_list.h"
6 #include "base/observer_list_threadsafe.h" 6 #include "base/observer_list_threadsafe.h"
7 7
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/memory/weak_ptr.h" 12 #include "base/memory/weak_ptr.h"
13 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "base/single_thread_task_runner.h" 14 #include "base/single_thread_task_runner.h"
15 #include "base/threading/platform_thread.h" 15 #include "base/threading/platform_thread.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 17
18 namespace base { 18 namespace base {
19 namespace { 19 namespace {
20 20
21 class Foo { 21 class Foo {
22 public: 22 public:
23 virtual void Observe(int x) = 0; 23 virtual void Observe(int x) = 0;
24 virtual ~Foo() {} 24 virtual ~Foo() {}
25 virtual int GetValue() const { return 0; }
25 }; 26 };
26 27
27 class Adder : public Foo { 28 class Adder : public Foo {
28 public: 29 public:
29 explicit Adder(int scaler) : total(0), scaler_(scaler) {} 30 explicit Adder(int scaler) : total(0), scaler_(scaler) {}
31 ~Adder() override {}
32
30 void Observe(int x) override { total += x * scaler_; } 33 void Observe(int x) override { total += x * scaler_; }
31 ~Adder() override {} 34 int GetValue() const override { return total; }
35
32 int total; 36 int total;
33 37
34 private: 38 private:
35 int scaler_; 39 int scaler_;
36 }; 40 };
37 41
38 class Disrupter : public Foo { 42 class Disrupter : public Foo {
39 public: 43 public:
40 Disrupter(ObserverList<Foo>* list, Foo* doomed) 44 Disrupter(ObserverList<Foo>* list, Foo* doomed)
41 : list_(list), 45 : list_(list),
42 doomed_(doomed) { 46 doomed_(doomed) {
43 } 47 }
44 ~Disrupter() override {} 48 ~Disrupter() override {}
45 void Observe(int x) override { list_->RemoveObserver(doomed_); } 49 void Observe(int x) override { list_->RemoveObserver(doomed_); }
46 50
47 private: 51 private:
48 ObserverList<Foo>* list_; 52 ObserverList<Foo>* list_;
49 Foo* doomed_; 53 Foo* doomed_;
50 }; 54 };
51 55
56 class DisrupterSelf : public Foo {
57 public:
58 DisrupterSelf(ObserverList<Foo>* list) : list_(list) {}
59 ~DisrupterSelf() override {}
60 void Observe(int x) override { list_->RemoveObserver(this); }
61
62 private:
63 ObserverList<Foo>* list_;
64 };
65
52 class ThreadSafeDisrupter : public Foo { 66 class ThreadSafeDisrupter : public Foo {
53 public: 67 public:
54 ThreadSafeDisrupter(ObserverListThreadSafe<Foo>* list, Foo* doomed) 68 ThreadSafeDisrupter(ObserverListThreadSafe<Foo>* list, Foo* doomed)
55 : list_(list), 69 : list_(list),
56 doomed_(doomed) { 70 doomed_(doomed) {
57 } 71 }
58 ~ThreadSafeDisrupter() override {} 72 ~ThreadSafeDisrupter() override {}
59 void Observe(int x) override { list_->RemoveObserver(doomed_); } 73 void Observe(int x) override { list_->RemoveObserver(doomed_); }
60 74
61 private: 75 private:
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 212
199 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); 213 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10));
200 214
201 EXPECT_EQ(20, a.total); 215 EXPECT_EQ(20, a.total);
202 EXPECT_EQ(-20, b.total); 216 EXPECT_EQ(-20, b.total);
203 EXPECT_EQ(0, c.total); 217 EXPECT_EQ(0, c.total);
204 EXPECT_EQ(-10, d.total); 218 EXPECT_EQ(-10, d.total);
205 EXPECT_EQ(0, e.total); 219 EXPECT_EQ(0, e.total);
206 } 220 }
207 221
222 TEST(ObserverListTest, DesruptSelf) {
223 ObserverList<Foo> observer_list;
224 Adder a(1), b(-1), c(1), d(-1);
225 DisrupterSelf evil(&observer_list);
226
227 observer_list.AddObserver(&a);
228 observer_list.AddObserver(&b);
229
230 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10));
231
232 observer_list.AddObserver(&evil);
233 observer_list.AddObserver(&c);
234 observer_list.AddObserver(&d);
235
236 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10));
237
238 EXPECT_EQ(20, a.total);
239 EXPECT_EQ(-20, b.total);
240 EXPECT_EQ(10, c.total);
241 EXPECT_EQ(-10, d.total);
242 }
243
244 TEST(ObserverListTest, DesruptBefore) {
245 ObserverList<Foo> observer_list;
246 Adder a(1), b(-1), c(1), d(-1);
247 Disrupter evil(&observer_list, &b);
248
249 observer_list.AddObserver(&a);
250 observer_list.AddObserver(&b);
251 observer_list.AddObserver(&evil);
252 observer_list.AddObserver(&c);
253 observer_list.AddObserver(&d);
254
255 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10));
256 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10));
257
258 EXPECT_EQ(20, a.total);
259 EXPECT_EQ(-10, b.total);
260 EXPECT_EQ(20, c.total);
261 EXPECT_EQ(-20, d.total);
262 }
263
208 TEST(ObserverListThreadSafeTest, BasicTest) { 264 TEST(ObserverListThreadSafeTest, BasicTest) {
209 MessageLoop loop; 265 MessageLoop loop;
210 266
211 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( 267 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list(
212 new ObserverListThreadSafe<Foo>); 268 new ObserverListThreadSafe<Foo>);
213 Adder a(1); 269 Adder a(1);
214 Adder b(-1); 270 Adder b(-1);
215 Adder c(1); 271 Adder c(1);
216 Adder d(-1); 272 Adder d(-1);
217 ThreadSafeDisrupter evil(observer_list.get(), &c); 273 ThreadSafeDisrupter evil(observer_list.get(), &c);
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 TEST(ObserverListTest, IteratorOutlivesList) { 590 TEST(ObserverListTest, IteratorOutlivesList) {
535 ObserverList<Foo>* observer_list = new ObserverList<Foo>; 591 ObserverList<Foo>* observer_list = new ObserverList<Foo>;
536 ListDestructor a(observer_list); 592 ListDestructor a(observer_list);
537 observer_list->AddObserver(&a); 593 observer_list->AddObserver(&a);
538 594
539 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0)); 595 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0));
540 // If this test fails, there'll be Valgrind errors when this function goes out 596 // If this test fails, there'll be Valgrind errors when this function goes out
541 // of scope. 597 // of scope.
542 } 598 }
543 599
600 TEST(ObserverListTest, BasicStdIterator) {
601 using FooList = ObserverList<Foo>;
602 FooList observer_list;
603
604 // Iterate over empty list: no effect, no crash.
605 for (auto& i : observer_list)
606 i.Observe(10);
607
608 Adder a(1), b(-1), c(1), d(-1);
609
610 observer_list.AddObserver(&a);
611 observer_list.AddObserver(&b);
612 observer_list.AddObserver(&c);
613 observer_list.AddObserver(&d);
614
615 for (FooList::iterator i = observer_list.begin(), e = observer_list.end();
616 i != e; ++i)
617 i->Observe(1);
618
619 EXPECT_EQ(1, a.total);
620 EXPECT_EQ(-1, b.total);
621 EXPECT_EQ(1, c.total);
622 EXPECT_EQ(-1, d.total);
623
624 // Check an iteration over a 'const view' for a given container.
625 const FooList& const_list = observer_list;
626 for (FooList::const_iterator i = const_list.begin(), e = const_list.end();
627 i != e; ++i) {
628 EXPECT_EQ(1, std::abs(i->GetValue()));
629 }
630
631 for (const auto& o : const_list)
632 EXPECT_EQ(1, std::abs(o.GetValue()));
633 }
634
635 TEST(ObserverListTest, StdIteratorRemoveItself) {
636 ObserverList<Foo> observer_list;
637 Adder a(1), b(-1), c(1), d(-1);
638 DisrupterSelf disrupter(&observer_list);
639
640 observer_list.AddObserver(&a);
641 observer_list.AddObserver(&b);
642 observer_list.AddObserver(&disrupter);
643 observer_list.AddObserver(&c);
644 observer_list.AddObserver(&d);
645
646 for (auto& o : observer_list)
647 o.Observe(1);
648
649 for (auto& o : observer_list)
650 o.Observe(10);
651
652 EXPECT_EQ(11, a.total);
653 EXPECT_EQ(-11, b.total);
654 EXPECT_EQ(11, c.total);
655 EXPECT_EQ(-11, d.total);
656 }
657
658 TEST(ObserverListTest, StdIteratorRemoveBefore) {
659 ObserverList<Foo> observer_list;
660 Adder a(1), b(-1), c(1), d(-1);
661 Disrupter disrupter(&observer_list, &b);
662
663 observer_list.AddObserver(&a);
664 observer_list.AddObserver(&b);
665 observer_list.AddObserver(&disrupter);
666 observer_list.AddObserver(&c);
667 observer_list.AddObserver(&d);
668
669 for (auto& o : observer_list)
670 o.Observe(1);
671
672 for (auto& o : observer_list)
673 o.Observe(10);
674
675 EXPECT_EQ(11, a.total);
676 EXPECT_EQ(-1, b.total);
677 EXPECT_EQ(11, c.total);
678 EXPECT_EQ(-11, d.total);
679 }
680
681 TEST(ObserverListTest, StdIteratorRemoveAfter) {
682 ObserverList<Foo> observer_list;
683 Adder a(1), b(-1), c(1), d(-1);
684 Disrupter disrupter(&observer_list, &c);
685
686 observer_list.AddObserver(&a);
687 observer_list.AddObserver(&b);
688 observer_list.AddObserver(&disrupter);
689 observer_list.AddObserver(&c);
690 observer_list.AddObserver(&d);
691
692 for (auto& o : observer_list)
693 o.Observe(1);
694
695 for (auto& o : observer_list)
696 o.Observe(10);
697
698 EXPECT_EQ(11, a.total);
699 EXPECT_EQ(-11, b.total);
700 EXPECT_EQ(0, c.total);
701 EXPECT_EQ(-11, d.total);
702 }
703
704 TEST(ObserverListTest, StdIteratorRemoveAfterFront) {
705 ObserverList<Foo> observer_list;
706 Adder a(1), b(-1), c(1), d(-1);
707 Disrupter disrupter(&observer_list, &a);
708
709 observer_list.AddObserver(&a);
710 observer_list.AddObserver(&disrupter);
711 observer_list.AddObserver(&b);
712 observer_list.AddObserver(&c);
713 observer_list.AddObserver(&d);
714
715 for (auto& o : observer_list)
716 o.Observe(1);
717
718 for (auto& o : observer_list)
719 o.Observe(10);
720
721 EXPECT_EQ(1, a.total);
722 EXPECT_EQ(-11, b.total);
723 EXPECT_EQ(11, c.total);
724 EXPECT_EQ(-11, d.total);
725 }
726
727 TEST(ObserverListTest, StdIteratorRemoveBeforeBack) {
728 ObserverList<Foo> observer_list;
729 Adder a(1), b(-1), c(1), d(-1);
730 Disrupter disrupter(&observer_list, &d);
731
732 observer_list.AddObserver(&a);
733 observer_list.AddObserver(&b);
734 observer_list.AddObserver(&c);
735 observer_list.AddObserver(&disrupter);
736 observer_list.AddObserver(&d);
737
738 for (auto& o : observer_list)
739 o.Observe(1);
740
741 for (auto& o : observer_list)
742 o.Observe(10);
743
744 EXPECT_EQ(11, a.total);
745 EXPECT_EQ(-11, b.total);
746 EXPECT_EQ(11, c.total);
747 EXPECT_EQ(0, d.total);
748 }
749
750 TEST(ObserverListTest, StdIteratorRemoveFront) {
751 ObserverList<Foo> observer_list;
752 Adder a(1), b(-1), c(1), d(-1);
753 DisrupterSelf disrupter(&observer_list);
754
755 observer_list.AddObserver(&disrupter);
756 observer_list.AddObserver(&a);
757 observer_list.AddObserver(&b);
758 observer_list.AddObserver(&c);
759 observer_list.AddObserver(&d);
760
761 for (auto& o : observer_list)
762 o.Observe(1);
763
764 for (auto& o : observer_list)
765 o.Observe(10);
766
767 EXPECT_EQ(11, a.total);
768 EXPECT_EQ(-11, b.total);
769 EXPECT_EQ(11, c.total);
770 EXPECT_EQ(-11, d.total);
771 }
772
773 TEST(ObserverListTest, StdIteratorRemoveBack) {
774 ObserverList<Foo> observer_list;
775 Adder a(1), b(-1), c(1), d(-1);
776 DisrupterSelf disrupter(&observer_list);
777
778 observer_list.AddObserver(&a);
779 observer_list.AddObserver(&b);
780 observer_list.AddObserver(&c);
781 observer_list.AddObserver(&d);
782 observer_list.AddObserver(&disrupter);
783
784 for (auto& o : observer_list)
785 o.Observe(1);
786
787 for (auto& o : observer_list)
788 o.Observe(10);
789
790 EXPECT_EQ(11, a.total);
791 EXPECT_EQ(-11, b.total);
792 EXPECT_EQ(11, c.total);
793 EXPECT_EQ(-11, d.total);
794 }
795
544 } // namespace 796 } // namespace
545 } // namespace base 797 } // namespace base
OLDNEW
« base/observer_list.h ('K') | « base/observer_list.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698