Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/tests/gtest/TestAtoms.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "mozilla/ArrayUtils.h"
8
9
#include "nsAtom.h"
10
#include "nsString.h"
11
#include "UTFStrings.h"
12
#include "nsIServiceManager.h"
13
#include "nsThreadUtils.h"
14
15
#include "gtest/gtest.h"
16
17
using namespace mozilla;
18
19
int32_t NS_GetUnusedAtomCount(void);
20
21
namespace TestAtoms {
22
23
TEST(Atoms, Basic)
24
0
{
25
0
  for (unsigned int i = 0; i < ArrayLength(ValidStrings); ++i) {
26
0
    nsDependentString str16(ValidStrings[i].m16);
27
0
    nsDependentCString str8(ValidStrings[i].m8);
28
0
29
0
    RefPtr<nsAtom> atom = NS_Atomize(str16);
30
0
31
0
    EXPECT_TRUE(atom->Equals(str16));
32
0
33
0
    nsString tmp16;
34
0
    nsCString tmp8;
35
0
    atom->ToString(tmp16);
36
0
    atom->ToUTF8String(tmp8);
37
0
    EXPECT_TRUE(str16.Equals(tmp16));
38
0
    EXPECT_TRUE(str8.Equals(tmp8));
39
0
40
0
    EXPECT_TRUE(nsDependentString(atom->GetUTF16String()).Equals(str16));
41
0
42
0
    EXPECT_TRUE(nsAtomString(atom).Equals(str16));
43
0
    EXPECT_TRUE(nsDependentAtomString(atom).Equals(str16));
44
0
    EXPECT_TRUE(nsAtomCString(atom).Equals(str8));
45
0
  }
46
0
}
47
48
TEST(Atoms, 16vs8)
49
0
{
50
0
  for (unsigned int i = 0; i < ArrayLength(ValidStrings); ++i) {
51
0
    RefPtr<nsAtom> atom16 = NS_Atomize(ValidStrings[i].m16);
52
0
    RefPtr<nsAtom> atom8 = NS_Atomize(ValidStrings[i].m8);
53
0
    EXPECT_EQ(atom16, atom8);
54
0
  }
55
0
}
56
57
TEST(Atoms, Null)
58
0
{
59
0
  nsAutoString str(NS_LITERAL_STRING("string with a \0 char"));
60
0
  nsDependentString strCut(str.get());
61
0
62
0
  EXPECT_FALSE(str.Equals(strCut));
63
0
64
0
  RefPtr<nsAtom> atomCut = NS_Atomize(strCut);
65
0
  RefPtr<nsAtom> atom = NS_Atomize(str);
66
0
67
0
  EXPECT_EQ(atom->GetLength(), str.Length());
68
0
  EXPECT_TRUE(atom->Equals(str));
69
0
  EXPECT_NE(atom, atomCut);
70
0
  EXPECT_TRUE(atomCut->Equals(strCut));
71
0
}
72
73
TEST(Atoms, Invalid)
74
0
{
75
0
  for (unsigned int i = 0; i < ArrayLength(Invalid16Strings); ++i) {
76
0
    nsrefcnt count = NS_GetNumberOfAtoms();
77
0
78
0
    {
79
0
      RefPtr<nsAtom> atom16 = NS_Atomize(Invalid16Strings[i].m16);
80
0
      EXPECT_TRUE(atom16->Equals(nsDependentString(Invalid16Strings[i].m16)));
81
0
    }
82
0
83
0
    EXPECT_EQ(count, NS_GetNumberOfAtoms());
84
0
  }
85
0
#ifndef DEBUG
86
0
// Don't run this test in debug builds as that intentionally asserts.
87
0
  for (unsigned int i = 0; i < ArrayLength(Invalid8Strings); ++i) {
88
0
    nsrefcnt count = NS_GetNumberOfAtoms();
89
0
90
0
    {
91
0
      RefPtr<nsAtom> atom8 = NS_Atomize(Invalid8Strings[i].m8);
92
0
      RefPtr<nsAtom> atom16 = NS_Atomize(Invalid8Strings[i].m16);
93
0
      EXPECT_EQ(atom16, atom8);
94
0
      EXPECT_TRUE(atom16->Equals(nsDependentString(Invalid8Strings[i].m16)));
95
0
    }
96
0
97
0
    EXPECT_EQ(count, NS_GetNumberOfAtoms());
98
0
  }
99
0
100
0
  for (unsigned int i = 0; i < ArrayLength(Malformed8Strings); ++i) {
101
0
    nsrefcnt count = NS_GetNumberOfAtoms();
102
0
103
0
    {
104
0
      RefPtr<nsAtom> atom8 = NS_Atomize(Malformed8Strings[i].m8);
105
0
      RefPtr<nsAtom> atom16 = NS_Atomize(Malformed8Strings[i].m16);
106
0
      EXPECT_EQ(atom8, atom16);
107
0
    }
108
0
109
0
    EXPECT_EQ(count, NS_GetNumberOfAtoms());
110
0
  }
111
0
#endif
112
0
}
113
114
#define FIRST_ATOM_STR "first static atom. Hello!"
115
#define SECOND_ATOM_STR "second static atom. @World!"
116
0
#define THIRD_ATOM_STR "third static atom?!"
117
118
bool
119
isStaticAtom(nsAtom* atom)
120
0
{
121
0
  // Don't use logic && in order to ensure that all addrefs/releases are always
122
0
  // run, even if one of the tests fail. This allows us to run this code on a
123
0
  // non-static atom without affecting its refcount.
124
0
  bool rv = (atom->AddRef() == 2);
125
0
  rv &= (atom->AddRef() == 2);
126
0
  rv &= (atom->AddRef() == 2);
127
0
128
0
  rv &= (atom->Release() == 1);
129
0
  rv &= (atom->Release() == 1);
130
0
  rv &= (atom->Release() == 1);
131
0
  return rv;
132
0
}
133
134
TEST(Atoms, Table)
135
0
{
136
0
  nsrefcnt count = NS_GetNumberOfAtoms();
137
0
138
0
  RefPtr<nsAtom> thirdDynamic = NS_Atomize(THIRD_ATOM_STR);
139
0
140
0
  EXPECT_FALSE(isStaticAtom(thirdDynamic));
141
0
142
0
  EXPECT_TRUE(thirdDynamic);
143
0
  EXPECT_EQ(NS_GetNumberOfAtoms(), count + 1);
144
0
}
145
146
class nsAtomRunner final : public nsIRunnable
147
{
148
public:
149
  NS_DECL_THREADSAFE_ISUPPORTS
150
151
  NS_IMETHOD Run() final
152
0
  {
153
0
    for (int i = 0; i < 10000; i++) {
154
0
      RefPtr<nsAtom> atom = NS_Atomize(u"A Testing Atom");
155
0
    }
156
0
    return NS_OK;
157
0
  }
158
159
private:
160
0
  ~nsAtomRunner() {}
161
};
162
163
NS_IMPL_ISUPPORTS(nsAtomRunner, nsIRunnable)
164
165
TEST(Atoms, ConcurrentAccessing)
166
0
{
167
0
  static const size_t kThreadCount = 4;
168
0
  // Force a GC before so that we don't have any unused atom.
169
0
  NS_GetNumberOfAtoms();
170
0
  EXPECT_EQ(NS_GetUnusedAtomCount(), int32_t(0));
171
0
  nsCOMPtr<nsIThread> threads[kThreadCount];
172
0
  for (size_t i = 0; i < kThreadCount; i++) {
173
0
    nsresult rv = NS_NewThread(getter_AddRefs(threads[i]), new nsAtomRunner);
174
0
    EXPECT_TRUE(NS_SUCCEEDED(rv));
175
0
  }
176
0
  for (size_t i = 0; i < kThreadCount; i++) {
177
0
    threads[i]->Shutdown();
178
0
  }
179
0
  // We should have one unused atom from this test.
180
0
  EXPECT_EQ(NS_GetUnusedAtomCount(), int32_t(1));
181
0
}
182
183
}