uia 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. data/.rspec +1 -0
  2. data/ChangeLog +11 -0
  3. data/README.md +18 -1
  4. data/Rakefile +6 -1
  5. data/ext/UiaDll/UIA.Helper/Element.cs +52 -32
  6. data/ext/UiaDll/UiaDll.Test/AssemblyInfo.cpp +40 -0
  7. data/ext/UiaDll/UiaDll.Test/ElementInformationTest.cpp +89 -0
  8. data/ext/UiaDll/UiaDll.Test/ElementStub.h +59 -0
  9. data/ext/UiaDll/UiaDll.Test/ElementsTest.cpp +22 -0
  10. data/ext/UiaDll/UiaDll.Test/MemoryLeakDetector.h +47 -0
  11. data/ext/UiaDll/UiaDll.Test/ReadMe.txt +35 -0
  12. data/ext/UiaDll/UiaDll.Test/StringHelperTest.cpp +14 -0
  13. data/ext/UiaDll/UiaDll.Test/UiaDll.Test.cpp +16 -0
  14. data/ext/UiaDll/UiaDll.Test/UiaDll.Test.vcxproj +127 -0
  15. data/ext/UiaDll/UiaDll.Test/UiaDll.Test.vcxproj.filters +67 -0
  16. data/ext/UiaDll/UiaDll.Test/app.ico +0 -0
  17. data/ext/UiaDll/UiaDll.Test/app.rc +0 -0
  18. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-actions.h +1078 -0
  19. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-cardinalities.h +147 -0
  20. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-actions.h +2415 -0
  21. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-actions.h.pump +821 -0
  22. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-function-mockers.h +991 -0
  23. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-function-mockers.h.pump +265 -0
  24. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-matchers.h +2190 -0
  25. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-matchers.h.pump +674 -0
  26. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-nice-strict.h +397 -0
  27. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-nice-strict.h.pump +161 -0
  28. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-matchers.h +3986 -0
  29. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-more-actions.h +233 -0
  30. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-more-matchers.h +58 -0
  31. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-spec-builders.h +1791 -0
  32. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock.h +94 -0
  33. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/internal/gmock-generated-internal-utils.h +279 -0
  34. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/internal/gmock-generated-internal-utils.h.pump +136 -0
  35. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/internal/gmock-internal-utils.h +498 -0
  36. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/internal/gmock-port.h +78 -0
  37. data/ext/UiaDll/UiaDll.Test/gmock/lib/gmock.lib +0 -0
  38. data/ext/UiaDll/UiaDll.Test/gmock/lib/gmockd.lib +0 -0
  39. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-death-test.h +294 -0
  40. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-message.h +250 -0
  41. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-param-test.h +1421 -0
  42. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-param-test.h.pump +487 -0
  43. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-printers.h +855 -0
  44. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-spi.h +232 -0
  45. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-test-part.h +179 -0
  46. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-typed-test.h +259 -0
  47. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest.h +2291 -0
  48. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest_pred_impl.h +358 -0
  49. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest_prod.h +58 -0
  50. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-death-test-internal.h +319 -0
  51. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-filepath.h +206 -0
  52. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-internal.h +1158 -0
  53. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-linked_ptr.h +233 -0
  54. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-param-util-generated.h +5143 -0
  55. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump +301 -0
  56. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-param-util.h +619 -0
  57. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-port.h +1947 -0
  58. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-string.h +167 -0
  59. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-tuple.h +1012 -0
  60. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-tuple.h.pump +339 -0
  61. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-type-util.h +3331 -0
  62. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-type-util.h.pump +297 -0
  63. data/ext/UiaDll/UiaDll.Test/gtest/lib/gtest.lib +0 -0
  64. data/ext/UiaDll/UiaDll.Test/gtest/lib/gtestd.lib +0 -0
  65. data/ext/UiaDll/UiaDll.Test/resource.h +3 -0
  66. data/ext/UiaDll/UiaDll.Test/stdafx.cpp +7 -0
  67. data/ext/UiaDll/UiaDll.Test/stdafx.h +7 -0
  68. data/ext/UiaDll/UiaDll.sln +15 -0
  69. data/ext/UiaDll/UiaDll/ArrayHelper.h +20 -2
  70. data/ext/UiaDll/UiaDll/ElementMethods.cpp +18 -0
  71. data/ext/UiaDll/UiaDll/ElementStructures.h +36 -24
  72. data/ext/UiaDll/UiaDll/StringHelper.h +16 -2
  73. data/ext/UiaDll/UiaDll/UiaDll.vcxproj +0 -2
  74. data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +0 -6
  75. data/lib/uia.rb +23 -117
  76. data/lib/uia/element.rb +38 -0
  77. data/lib/uia/library.rb +60 -0
  78. data/lib/uia/library/constants.rb +85 -0
  79. data/lib/uia/library/structs.rb +85 -0
  80. data/lib/uia/version.rb +1 -1
  81. data/spec/app/FizzWare.NBuilder.dll +0 -0
  82. data/spec/app/UIA.Extensions.dll +0 -0
  83. data/spec/app/WindowsForms.exe +0 -0
  84. data/spec/spec_helper.rb +21 -0
  85. data/spec/uia/element_spec.rb +56 -0
  86. data/spec/uia_spec.rb +28 -0
  87. data/uia.gemspec +13 -10
  88. metadata +134 -8
  89. data/ext/UiaDll/UiaDll/ArrayHelper.cpp +0 -22
  90. data/ext/UiaDll/UiaDll/StringHelper.cpp +0 -17
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --format documentation --color
data/ChangeLog ADDED
@@ -0,0 +1,11 @@
1
+ === Verions 0.0.5 / 2012-10-16
2
+
3
+ * Enhancements
4
+ * Pushed #find_element into the Uia module
5
+ * Can locate elements by :id, :handle, :runtime_pid and :pid
6
+ * Element now knows about :id,:control_type, :patterns, :handle and :runtime_id
7
+ * Elements know about their :children and :descendants
8
+
9
+ === Version 0.0.4 / 2013-10-11
10
+ Initial release with very limited support for finding an element and
11
+ displaying various properties.
data/README.md CHANGED
@@ -18,7 +18,24 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
21
+ Getting started with `uia` is easy. Simply require `uia` and then include the `Uia` module wherever you would like to use it.
22
+
23
+ ```ruby
24
+ require 'uia'
25
+
26
+ include Uia
27
+
28
+ main_window = find_element id: 'MainFormWindow'
29
+ ```
30
+
31
+ ### Finding Elements
32
+
33
+ You can locate elements based on the following criteria:
34
+
35
+ * `:id` - find by their `AutomationId`
36
+ * `:pid` - find an element by their process id
37
+ * `:handle` - find an element by their native window handle
38
+ * `:runtime_id` - find an element by their `RuntimeId` (i.e. `[42, 12345]`)
22
39
 
23
40
  ## Contributing
24
41
 
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -8,41 +8,58 @@ namespace UIA.Helper
8
8
  {
9
9
  private readonly AutomationElement _element;
10
10
 
11
+ protected Element()
12
+ {
13
+ }
14
+
11
15
  private Element(AutomationElement element)
12
16
  {
13
17
  _element = element;
14
18
  }
15
19
 
16
- public int[] RuntimeId
20
+ public virtual int[] RuntimeId
17
21
  {
18
22
  get { return _element.GetRuntimeId(); }
19
23
  }
20
24
 
21
- public string Name
25
+ public virtual string Name
22
26
  {
23
27
  get { return _element.Current.Name; }
24
28
  }
25
29
 
26
- public int NativeWindowHandle
30
+ public virtual string Id
31
+ {
32
+ get { return _element.Current.AutomationId; }
33
+ }
34
+
35
+ public virtual int NativeWindowHandle
27
36
  {
28
37
  get { return _element.Current.NativeWindowHandle; }
29
38
  }
30
39
 
40
+ public virtual int ControlTypeId
41
+ {
42
+ get { return _element.Current.ControlType.Id; }
43
+ }
44
+
45
+ public virtual int[] SupportedPatternIds
46
+ {
47
+ get { return _element.GetSupportedPatterns().Select(x => x.Id).ToArray(); }
48
+ }
49
+
31
50
  public Element[] Children
32
51
  {
33
- get
34
- {
35
- return _element.FindAll(TreeScope.Children, Condition.TrueCondition).Cast<AutomationElement>()
36
- .Select(x => new Element(x))
37
- .ToArray();
38
- }
52
+ get { return Find(TreeScope.Children, Condition.TrueCondition); }
39
53
  }
40
54
 
41
55
  public Element[] ChildrenOf(AutomationProperty.Id id)
42
56
  {
43
- return _element.FindAll(TreeScope.Children, AutomationProperty.From(id)).Cast<AutomationElement>()
44
- .Select(x => new Element(x))
45
- .ToArray();
57
+ return Find(TreeScope.Children, AutomationProperty.From(id));
58
+ }
59
+
60
+ public Element[] Descendants
61
+ {
62
+ get { return Find(TreeScope.Descendants, Condition.TrueCondition); }
46
63
  }
47
64
 
48
65
  public void MouseClick()
@@ -52,36 +69,39 @@ namespace UIA.Helper
52
69
 
53
70
  public static Element ById(string automationId)
54
71
  {
55
- var foundElement = AutomationElement.RootElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, automationId));
56
- if (null == foundElement)
57
- {
58
- throw new ArgumentException(string.Format("An element with the id \"{0}\" was not found", automationId));
59
- }
72
+ return FindFirst(new PropertyCondition(AutomationElement.AutomationIdProperty, automationId));
73
+ }
60
74
 
61
- return new Element(foundElement);
75
+ public static Element ByProcessId(int processId)
76
+ {
77
+ return FindFirst(new PropertyCondition(AutomationElement.ProcessIdProperty, processId));
62
78
  }
63
79
 
64
80
  public static Element ByHandle(IntPtr windowHandle)
65
81
  {
66
- var foundElement = AutomationElement.FromHandle(windowHandle);
67
- if (null == foundElement)
68
- {
69
- throw new ArgumentException(string.Format("An element with the handle 0x{0:x} was not found", windowHandle.ToInt32()));
70
- }
71
-
72
- return new Element(foundElement);
82
+ return NullOr(AutomationElement.FromHandle(windowHandle));
73
83
  }
74
84
 
75
85
  public static Element ByRuntimeId(int[] runtimeId)
76
86
  {
77
- var foundElement = AutomationElement.RootElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.RuntimeIdProperty, runtimeId));
78
- if (null == foundElement)
79
- {
80
- throw new ArgumentException(string.Format("An element with the runtime id \"{0}\" was not found",
81
- string.Join(", ", runtimeId.Select(x => x.ToString()))));
82
- }
87
+ return FindFirst(new PropertyCondition(AutomationElement.RuntimeIdProperty, runtimeId));
88
+ }
83
89
 
84
- return new Element(foundElement);
90
+ private Element[] Find(TreeScope scope, Condition condition)
91
+ {
92
+ return _element.FindAll(scope, condition).Cast<AutomationElement>()
93
+ .Select(x => new Element(x))
94
+ .ToArray();
95
+ }
96
+
97
+ private static Element FindFirst(Condition condition)
98
+ {
99
+ return NullOr(AutomationElement.RootElement.FindFirst(TreeScope.Descendants, condition));
100
+ }
101
+
102
+ private static Element NullOr(AutomationElement automationElement)
103
+ {
104
+ return null == automationElement ? null : new Element(automationElement);
85
105
  }
86
106
  }
87
107
  }
@@ -0,0 +1,40 @@
1
+ #include "stdafx.h"
2
+
3
+ using namespace System;
4
+ using namespace System::Reflection;
5
+ using namespace System::Runtime::CompilerServices;
6
+ using namespace System::Runtime::InteropServices;
7
+ using namespace System::Security::Permissions;
8
+
9
+ //
10
+ // General Information about an assembly is controlled through the following
11
+ // set of attributes. Change these attribute values to modify the information
12
+ // associated with an assembly.
13
+ //
14
+ [assembly:AssemblyTitleAttribute("UiaDllTest")];
15
+ [assembly:AssemblyDescriptionAttribute("")];
16
+ [assembly:AssemblyConfigurationAttribute("")];
17
+ [assembly:AssemblyCompanyAttribute("")];
18
+ [assembly:AssemblyProductAttribute("UiaDllTest")];
19
+ [assembly:AssemblyCopyrightAttribute("Copyright (c) 2013")];
20
+ [assembly:AssemblyTrademarkAttribute("")];
21
+ [assembly:AssemblyCultureAttribute("")];
22
+
23
+ //
24
+ // Version information for an assembly consists of the following four values:
25
+ //
26
+ // Major Version
27
+ // Minor Version
28
+ // Build Number
29
+ // Revision
30
+ //
31
+ // You can specify all the value or you can default the Revision and Build Numbers
32
+ // by using the '*' as shown below:
33
+
34
+ [assembly:AssemblyVersionAttribute("1.0.*")];
35
+
36
+ [assembly:ComVisible(false)];
37
+
38
+ [assembly:CLSCompliantAttribute(true)];
39
+
40
+ [assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
@@ -0,0 +1,89 @@
1
+ #include "stdafx.h"
2
+ #include "ElementStub.h"
3
+ #include <ElementStructures.h>
4
+
5
+ class ElementInformationTest : public ::testing::Test {
6
+ public:
7
+ Element^ ElementWith(String^ name) {
8
+ return gcnew ElementStub(name);
9
+ }
10
+
11
+ Element^ ElementWith(...array<int>^ runtimeIds) {
12
+ return gcnew ElementStub("", runtimeIds);
13
+ }
14
+ };
15
+
16
+ TEST_F(ElementInformationTest, ItHasAnId)
17
+ {
18
+ auto element = gcnew ElementStub("");
19
+ element->Id = "Expected Id";
20
+ ASSERT_STREQ("Expected Id", ElementInformation(element).id);
21
+ }
22
+
23
+ TEST_F(ElementInformationTest, ItCleansUpTheName)
24
+ {
25
+ auto elementInformation = new ElementInformation(ElementWith("Some Name"));
26
+ delete elementInformation;
27
+ }
28
+
29
+ TEST_F(ElementInformationTest, ItCleansUpTheRuntimeId)
30
+ {
31
+ auto elementInformation = new ElementInformation(ElementWith(46, 2));
32
+ delete elementInformation;
33
+ }
34
+
35
+ TEST_F(ElementInformationTest, ItHasTheName)
36
+ {
37
+ ASSERT_STREQ("Expected Name", ElementInformation(gcnew ElementStub("Expected Name")).name);
38
+ }
39
+
40
+ TEST_F(ElementInformationTest, ItKnowsAboutTheRuntimeId)
41
+ {
42
+ auto elementInformation = ElementInformation(gcnew ElementStub("", 0, 1, 2));
43
+ for(auto expected = 0; expected < 3; expected++) {
44
+ ASSERT_EQ(expected, elementInformation.runtimeId[expected]);
45
+ }
46
+
47
+ ASSERT_EQ(3, elementInformation.runtimeIdLength);
48
+ }
49
+
50
+ TEST_F(ElementInformationTest, ItKnowsTheWindowHandle)
51
+ {
52
+ auto element = gcnew ElementStub("");
53
+ element->NativeWindowHandle = 12345;
54
+
55
+ ASSERT_EQ(ElementInformation(element).nativeWindowHandle, 12345);
56
+ }
57
+
58
+ TEST_F(ElementInformationTest, ItKnowsTheControlType)
59
+ {
60
+ auto element = gcnew ElementStub("");
61
+ element->ControlTypeId = 1234;
62
+
63
+ ASSERT_EQ(1234, ElementInformation(element).controlTypeId);
64
+ }
65
+
66
+ TEST_F(ElementInformationTest, ItKnowsTheSupportedPatterns)
67
+ {
68
+ auto element = gcnew ElementStub("");
69
+ element->SetPatterns(7, 5, 3);
70
+
71
+ auto elementInformation = ElementInformation(element);
72
+
73
+ const int expectedPatterns[] = {7, 5, 3};
74
+ ASSERT_THAT(expectedPatterns, ::testing::ElementsAreArray(elementInformation.patterns, elementInformation.patternsLength));
75
+ }
76
+
77
+ TEST_F(ElementInformationTest, ItCanBeUpdated)
78
+ {
79
+ auto elementInformation = ElementInformation(gcnew ElementStub("Initial", 0));
80
+
81
+ auto updatedElement = gcnew ElementStub("Updated", 46, 2);
82
+ updatedElement->NativeWindowHandle = 123;
83
+ elementInformation.Update(updatedElement);
84
+
85
+ const int expectedId[] = {46, 2};
86
+ ASSERT_THAT(expectedId, ::testing::ElementsAreArray(elementInformation.runtimeId, elementInformation.runtimeIdLength));
87
+ ASSERT_STREQ("Updated", elementInformation.name);
88
+ ASSERT_EQ(123, elementInformation.nativeWindowHandle);
89
+ }
@@ -0,0 +1,59 @@
1
+ #include "stdafx.h"
2
+
3
+ ref class ElementStub : Element
4
+ {
5
+ public:
6
+ ElementStub(String^ name, ...array<int>^ runtimeIds) : Element()
7
+ {
8
+ _name = name;
9
+ _runtimeIds = runtimeIds;
10
+ _patterns = gcnew array<int>(0);
11
+ }
12
+
13
+ virtual property String^ Name
14
+ {
15
+ String^ get() override { return _name; }
16
+ void set(String^ name) { _name = name; }
17
+ }
18
+
19
+ virtual property String^ Id
20
+ {
21
+ String^ get() override { return _id; }
22
+ void set(String^ value) override { _id = value; }
23
+ }
24
+
25
+ virtual property array<int>^ RuntimeId
26
+ {
27
+ array<int>^ get() override { return _runtimeIds; }
28
+ }
29
+
30
+ virtual property int NativeWindowHandle
31
+ {
32
+ int get() override { return _nativeWindowHandle; }
33
+ void set(int value) { _nativeWindowHandle = value; }
34
+ }
35
+
36
+ virtual property int ControlTypeId
37
+ {
38
+ int get() override { return _controlTypeId; }
39
+ void set(int value) override { _controlTypeId = value; }
40
+ }
41
+
42
+ virtual property array<int>^ SupportedPatternIds
43
+ {
44
+ array<int>^ get() override { return _patterns; }
45
+ }
46
+
47
+ void SetPatterns(... array<int>^ patterns)
48
+ {
49
+ _patterns = patterns;
50
+ }
51
+
52
+ private:
53
+ String^ _name;
54
+ String^ _id;
55
+ array<int>^ _runtimeIds;
56
+ array<int>^ _patterns;
57
+ int _nativeWindowHandle;
58
+ int _controlTypeId;
59
+ };
@@ -0,0 +1,22 @@
1
+ #include "stdafx.h"
2
+ #include "ElementStub.h"
3
+ #include <ElementStructures.h>
4
+
5
+ class ElementsTest : public ::testing::Test {
6
+ public:
7
+ array<Element^>^ ElementsWithNames(...array<String^>^ names) {
8
+ auto elements = gcnew array<Element^>(names->Length);
9
+ auto index = 0;
10
+ for each(auto name in names) {
11
+ elements[index++] = gcnew ElementStub(name);
12
+ }
13
+ return elements;
14
+ }
15
+ };
16
+
17
+ TEST_F(ElementsTest, ItCanBeInitialized)
18
+ {
19
+ auto elements = Elements(ElementsWithNames("First", "Second"));
20
+ ASSERT_STREQ("First", elements.elements[0].name);
21
+ ASSERT_STREQ("Second", elements.elements[1].name);
22
+ }
@@ -0,0 +1,47 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file
5
+ * @copyright (c) 2013 Stephan Brenner
6
+ * @license This project is released under the MIT License.
7
+ *
8
+ * This file implements a main() function for Google Test that runs all tests
9
+ * and detects memory leaks.
10
+ */
11
+
12
+ #include <iostream>
13
+ #include <crtdbg.h>
14
+ #include <gtest/gtest.h>
15
+
16
+ using namespace std;
17
+ using namespace testing;
18
+
19
+ namespace testing
20
+ {
21
+ class MemoryLeakDetector : public EmptyTestEventListener
22
+ {
23
+ #ifdef _DEBUG
24
+ public:
25
+ virtual void OnTestStart(const TestInfo&)
26
+ {
27
+ _CrtMemCheckpoint(&memState_);
28
+ }
29
+
30
+ virtual void OnTestEnd(const TestInfo& test_info){
31
+ if(test_info.result()->Passed())
32
+ {
33
+ _CrtMemState stateNow, stateDiff;
34
+ _CrtMemCheckpoint(&stateNow);
35
+ int diffResult = _CrtMemDifference(&stateDiff, &memState_, &stateNow);
36
+ if (diffResult)
37
+ {
38
+ FAIL() << "Memory leak of " << stateDiff.lSizes[1] << " byte(s) detected.";
39
+ }
40
+ }
41
+ }
42
+
43
+ private:
44
+ _CrtMemState memState_;
45
+ #endif // _DEBUG
46
+ };
47
+ }