From 1c32f3e2831aefdf50fd226d3e1b314c804afc3b Mon Sep 17 00:00:00 2001 From: Chris Dyer Date: Wed, 2 May 2012 02:30:52 -0400 Subject: remove dependency on gtest, remove all-static --- utils/Makefile.am | 18 +++--- utils/crp_test.cc | 31 ++++------ utils/dict_test.cc | 37 ++++-------- utils/logval_test.cc | 60 ++++++++----------- utils/m_test.cc | 52 +++++++--------- utils/small_vector_test.cc | 145 +++++++++++++++++++++------------------------ utils/weights_test.cc | 22 ++----- 7 files changed, 148 insertions(+), 217 deletions(-) (limited to 'utils') diff --git a/utils/Makefile.am b/utils/Makefile.am index 2fc6ae21..46650c75 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -4,7 +4,6 @@ bin_PROGRAMS = reconstruct_weights atools noinst_PROGRAMS = ts phmt mfcr_test TESTS = ts phmt mfcr_test -if HAVE_GTEST noinst_PROGRAMS += \ crp_test \ dict_test \ @@ -14,7 +13,6 @@ noinst_PROGRAMS += \ small_vector_test TESTS += crp_test small_vector_test logval_test weights_test dict_test m_test -endif reconstruct_weights_SOURCES = reconstruct_weights.cc @@ -44,23 +42,23 @@ endif phmt_SOURCES = phmt.cc ts_SOURCES = ts.cc m_test_SOURCES = m_test.cc -m_test_LDADD = $(GTEST_LDFLAGS) $(GTEST_LIBS) +m_test_LDADD = $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) dict_test_SOURCES = dict_test.cc -dict_test_LDADD = $(GTEST_LDFLAGS) $(GTEST_LIBS) +dict_test_LDADD = $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) mfcr_test_SOURCES = mfcr_test.cc -mfcr_test_LDADD = $(GTEST_LDFLAGS) $(GTEST_LIBS) +mfcr_test_LDADD = $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) weights_test_SOURCES = weights_test.cc -weights_test_LDADD = $(GTEST_LDFLAGS) $(GTEST_LIBS) +weights_test_LDADD = $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) crp_test_SOURCES = crp_test.cc -crp_test_LDADD = $(GTEST_LDFLAGS) $(GTEST_LIBS) +crp_test_LDADD = $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) logval_test_SOURCES = logval_test.cc -logval_test_LDADD = $(GTEST_LDFLAGS) $(GTEST_LIBS) +logval_test_LDADD = $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) small_vector_test_SOURCES = small_vector_test.cc -small_vector_test_LDADD = $(GTEST_LDFLAGS) $(GTEST_LIBS) +small_vector_test_LDADD = $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) AM_LDFLAGS = libutils.a -lz ################################################################ # do NOT NOT NOT add any other -I includes NO NO NO NO NO ###### -AM_CPPFLAGS = -W -Wall -Wno-sign-compare $(GTEST_CPPFLAGS) -I. +AM_CPPFLAGS = -DBOOST_TEST_DYN_LINK -W -Wall -Wno-sign-compare -I. ################################################################ diff --git a/utils/crp_test.cc b/utils/crp_test.cc index 561cd4dd..0cdb7afd 100644 --- a/utils/crp_test.cc +++ b/utils/crp_test.cc @@ -2,25 +2,18 @@ #include #include -#include +#define BOOST_TEST_MODULE CrpTest +#include +#include #include "ccrp.h" #include "sampler.h" -const size_t MAX_DOC_LEN_CHARS = 10000000; - using namespace std; -class CRPTest : public testing::Test { - public: - CRPTest() {} - protected: - virtual void SetUp() { } - virtual void TearDown() { } - MT19937 rng; -}; +MT19937 rng; -TEST_F(CRPTest, Dist) { +BOOST_AUTO_TEST_CASE(Dist) { CCRP crp(0.1, 5); double un = 0.25; int tt = 0; @@ -41,7 +34,7 @@ TEST_F(CRPTest, Dist) { cout << " P(foo)=" << crp.prob("foo", un) << endl; double x = crp.prob("bar", un) + crp.prob("hi", un) + crp.prob("baz", un) + crp.prob("foo", un); cout << " tot=" << x << endl; - EXPECT_FLOAT_EQ(1.0, x); + BOOST_CHECK_CLOSE(1.0, x, 1e-6); tt += crp.decrement("hi", &rng); tt += crp.decrement("bar", &rng); cout << crp << endl; @@ -50,7 +43,7 @@ TEST_F(CRPTest, Dist) { cout << "tt=" << tt << endl; } -TEST_F(CRPTest, Exchangability) { +BOOST_AUTO_TEST_CASE(Exchangability) { double tot = 0; double xt = 0; CCRP crp(0.5, 1.0); @@ -79,24 +72,20 @@ TEST_F(CRPTest, Exchangability) { ++hist[c]; tot += c; } - EXPECT_EQ(cust, crp.num_customers()); + BOOST_CHECK_EQUAL(cust, crp.num_customers()); cerr << "P(a) = " << (xt / samples) << endl; cerr << "E[num tables] = " << (tot / samples) << endl; double error = fabs((tot / samples) - 5.4); cerr << " error = " << error << endl; - EXPECT_LT(error, 0.1); // it's possible for this to fail, but + BOOST_CHECK_MESSAGE(error < 0.1, "error is too big = " << error); // it's possible for this to fail, but // very, very unlikely for (int i = 1; i <= cust; ++i) cerr << i << ' ' << (hist[i]) << endl; } -TEST_F(CRPTest, LP) { +BOOST_AUTO_TEST_CASE(LP) { CCRP crp(1,1,1,1,0.1,50.0); crp.increment("foo", 1.0, &rng); cerr << crp.log_crp_prob() << endl; } -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/utils/dict_test.cc b/utils/dict_test.cc index 2049ec27..dac65de1 100644 --- a/utils/dict_test.cc +++ b/utils/dict_test.cc @@ -3,45 +3,34 @@ #include "fdict.h" #include -#include +#define BOOST_TEST_MODULE CrpTest +#include +#include #include using namespace std; -class DTest : public testing::Test { - public: - DTest() {} - protected: - virtual void SetUp() { } - virtual void TearDown() { } -}; - -TEST_F(DTest, Convert) { +BOOST_AUTO_TEST_CASE(Convert) { Dict d; WordID a = d.Convert("foo"); WordID b = d.Convert("bar"); std::string x = "foo"; WordID c = d.Convert(x); - EXPECT_NE(a, b); - EXPECT_EQ(a, c); - EXPECT_EQ(d.Convert(a), "foo"); - EXPECT_EQ(d.Convert(b), "bar"); + assert(a != b); + BOOST_CHECK_EQUAL(a, c); + BOOST_CHECK_EQUAL(d.Convert(a), "foo"); + BOOST_CHECK_EQUAL(d.Convert(b), "bar"); } -TEST_F(DTest, FDictTest) { +BOOST_AUTO_TEST_CASE(FDictTest) { int fid = FD::Convert("First"); - EXPECT_GT(fid, 0); - EXPECT_EQ(FD::Convert(fid), "First"); + assert(fid > 0); + BOOST_CHECK_EQUAL(FD::Convert(fid), "First"); string x = FD::Escape("="); cerr << x << endl; - EXPECT_NE(x, "="); + assert(x != "="); x = FD::Escape(";"); cerr << x << endl; - EXPECT_NE(x, ";"); -} - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + assert(x != ";"); } diff --git a/utils/logval_test.cc b/utils/logval_test.cc index 6133f5ce..119fa0e4 100644 --- a/utils/logval_test.cc +++ b/utils/logval_test.cc @@ -1,56 +1,51 @@ #include "logval.h" - -#include +#define BOOST_TEST_MODULE LogValTest +#include +#include #include -class LogValTest : public testing::Test { - protected: - virtual void SetUp() { } - virtual void TearDown() { } -}; - using namespace std; -TEST_F(LogValTest,Order) { +BOOST_AUTO_TEST_CASE(Order) { LogVal a(-0.3); LogVal b(0.3); LogVal c(2.4); - EXPECT_LT(a,b); - EXPECT_LT(b,c); - EXPECT_LT(a,c); - EXPECT_FALSE(b < a); - EXPECT_FALSE(c < a); - EXPECT_FALSE(c < b); - EXPECT_FALSE(c < c); - EXPECT_FALSE(b < b); - EXPECT_FALSE(a < a); + BOOST_CHECK_LT(a,b); + BOOST_CHECK_LT(b,c); + BOOST_CHECK_LT(a,c); + BOOST_CHECK(b >= a); + BOOST_CHECK(c >= a); + BOOST_CHECK(c >= b); + BOOST_CHECK(c >= c); + BOOST_CHECK(b >= b); + BOOST_CHECK(a >= a); } -TEST_F(LogValTest,Negate) { +BOOST_AUTO_TEST_CASE(Negate) { LogVal x(-2.4); LogVal y(2.4); y.negate(); - EXPECT_FLOAT_EQ(x.as_float(),y.as_float()); + BOOST_CHECK_CLOSE(x.as_float(),y.as_float(), 1e-6); } -TEST_F(LogValTest,Inverse) { +BOOST_AUTO_TEST_CASE(Inverse) { LogVal x(1/2.4); LogVal y(2.4); - EXPECT_FLOAT_EQ(x.as_float(),y.inverse().as_float()); + BOOST_CHECK_CLOSE(x.as_float(),y.inverse().as_float(), 1e-6); } -TEST_F(LogValTest,Minus) { +BOOST_AUTO_TEST_CASE(Minus) { LogVal x(12); LogVal y(2); LogVal z1 = x - y; LogVal z2 = x; z2 -= y; - EXPECT_FLOAT_EQ(z1.as_float(), z2.as_float()); - EXPECT_FLOAT_EQ(z1.as_float(), 10.0); - EXPECT_FLOAT_EQ((y - x).as_float(), -10.0); + BOOST_CHECK_CLOSE(z1.as_float(), z2.as_float(), 1e-6); + BOOST_CHECK_CLOSE(z1.as_float(), 10.0, 1e-6); + BOOST_CHECK_CLOSE((y - x).as_float(), -10.0, 1e-6); } -TEST_F(LogValTest,TestOps) { +BOOST_AUTO_TEST_CASE(TestOps) { LogVal x(-12.12); LogVal y(x); cerr << x << endl; @@ -62,18 +57,13 @@ TEST_F(LogValTest,TestOps) { LogVal bb(-0.3); cerr << (aa + bb) << endl; cerr << (bb + aa) << endl; - EXPECT_FLOAT_EQ((aa + bb).as_float(), (bb + aa).as_float()); - EXPECT_FLOAT_EQ((aa + bb).as_float(), -0.1); + BOOST_CHECK_CLOSE((aa + bb).as_float(), (bb + aa).as_float(), 1e-6); + BOOST_CHECK_CLOSE((aa + bb).as_float(), -0.1, 1e-6); } -TEST_F(LogValTest,TestSizes) { +BOOST_AUTO_TEST_CASE(TestSizes) { cerr << sizeof(LogVal) << endl; cerr << sizeof(LogVal) << endl; cerr << sizeof(void*) << endl; } -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - diff --git a/utils/m_test.cc b/utils/m_test.cc index c4d6a166..7851e4ac 100644 --- a/utils/m_test.cc +++ b/utils/m_test.cc @@ -1,20 +1,15 @@ #include "m.h" +#define BOOST_TEST_MODULE MTest +#include +#include + #include -#include #include using namespace std; -class MTest : public testing::Test { - public: - MTest() {} - protected: - virtual void SetUp() { } - virtual void TearDown() { } -}; - -TEST_F(MTest, Densities) { +BOOST_AUTO_TEST_CASE(Densities) { double px1 = Md::log_gaussian_density(1.0, 0.0, 1.0); double px2 = Md::log_gaussian_density(-1.0, 0.0, 1.0); double py1 = Md::log_laplace_density(1.0, 0.0, 1.0); @@ -22,70 +17,65 @@ TEST_F(MTest, Densities) { double pz1 = Md::log_triangle_density(1.0, -2.0, 2.0, 0.0); double pz2 = Md::log_triangle_density(1.0, -2.0, 2.0, 0.0); cerr << px1 << " " << py1 << " " << pz2 << endl; - EXPECT_FLOAT_EQ(px1, px2); - EXPECT_FLOAT_EQ(py1, py2); - EXPECT_FLOAT_EQ(pz1, pz2); + BOOST_CHECK_CLOSE(px1, px2, 1e-6); + BOOST_CHECK_CLOSE(py1, py2, 1e-6); + BOOST_CHECK_CLOSE(pz1, pz2, 1e-6); double b1 = Md::log_bivariate_gaussian_density(1.0, -1.0, 0.0, 0.0, 1.0, 1.0, -0.8); double b2 = Md::log_bivariate_gaussian_density(-1.0, 1.0, 0.0, 0.0, 1.0, 1.0, -0.8); cerr << b1 << " " << b2 << endl; } -TEST_F(MTest, Poisson) { +BOOST_AUTO_TEST_CASE(Poisson) { double prev = 1.0; double tot = 0; for (int i = 0; i < 10; ++i) { double p = Md::log_poisson(i, 0.99); cerr << "p(i=" << i << ") = " << exp(p) << endl; - EXPECT_LT(p, prev); + assert(p < prev); tot += exp(p); prev = p; } cerr << " tot=" << tot << endl; - EXPECT_LE(tot, 1.0); + assert(tot < 1.0); } -TEST_F(MTest, YuleSimon) { +BOOST_AUTO_TEST_CASE(YuleSimon) { double prev = 1.0; double tot = 0; for (int i = 0; i < 10; ++i) { double p = Md::log_yule_simon(i, 1.0); cerr << "p(i=" << i << ") = " << exp(p) << endl; - EXPECT_LT(p, prev); + assert(p < prev); tot += exp(p); prev = p; } cerr << " tot=" << tot << endl; - EXPECT_LE(tot, 1.0); + assert(tot < 1.0); } -TEST_F(MTest, LogGeometric) { +BOOST_AUTO_TEST_CASE(LogGeometric) { double prev = 1.0; double tot = 0; for (int i = 0; i < 10; ++i) { double p = Md::log_geometric(i, 0.5); cerr << "p(i=" << i << ") = " << exp(p) << endl; - EXPECT_LT(p, prev); + assert(p < prev); tot += exp(p); prev = p; } cerr << " tot=" << tot << endl; - EXPECT_LE(tot, 1.0); + assert(tot <= 1.0); } -TEST_F(MTest, GeneralizedFactorial) { +BOOST_AUTO_TEST_CASE(GeneralizedFactorial) { for (double i = 0.3; i < 10000; i += 0.4) { double a = Md::log_generalized_factorial(1.0, i); double b = lgamma(1.0 + i); - EXPECT_FLOAT_EQ(a,b); + BOOST_CHECK_CLOSE(a,b,1e-6); } double gf_3_6 = 3.0 * 4.0 * 5.0 * 6.0 * 7.0 * 8.0; - EXPECT_FLOAT_EQ(Md::log_generalized_factorial(3.0, 6.0), std::log(gf_3_6)); + BOOST_CHECK_CLOSE(Md::log_generalized_factorial(3.0, 6.0), std::log(gf_3_6), 1e-6); double gf_314_6 = 3.14 * 4.14 * 5.14 * 6.14 * 7.14 * 8.14; - EXPECT_FLOAT_EQ(Md::log_generalized_factorial(3.14, 6.0), std::log(gf_314_6)); -} - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + BOOST_CHECK_CLOSE(Md::log_generalized_factorial(3.14, 6.0), std::log(gf_314_6), 1e-6); } diff --git a/utils/small_vector_test.cc b/utils/small_vector_test.cc index d1d8dcab..cded4619 100644 --- a/utils/small_vector_test.cc +++ b/utils/small_vector_test.cc @@ -1,129 +1,118 @@ #include "small_vector.h" -#include +#define BOOST_TEST_MODULE svTest +#include +#include #include -#include #include using namespace std; -class SVTest : public testing::Test { - protected: - virtual void SetUp() { } - virtual void TearDown() { } -}; - -TEST_F(SVTest, LargerThan2) { +BOOST_AUTO_TEST_CASE(LargerThan2) { SmallVectorInt v; SmallVectorInt v2; v.push_back(0); v.push_back(1); v.push_back(2); - assert(v.size() == 3); - assert(v[2] == 2); - assert(v[1] == 1); - assert(v[0] == 0); + BOOST_CHECK(v.size() == 3); + BOOST_CHECK(v[2] == 2); + BOOST_CHECK(v[1] == 1); + BOOST_CHECK(v[0] == 0); v2 = v; SmallVectorInt copy(v); - assert(copy.size() == 3); - assert(copy[0] == 0); - assert(copy[1] == 1); - assert(copy[2] == 2); - assert(copy == v2); + BOOST_CHECK(copy.size() == 3); + BOOST_CHECK(copy[0] == 0); + BOOST_CHECK(copy[1] == 1); + BOOST_CHECK(copy[2] == 2); + BOOST_CHECK(copy == v2); copy[1] = 99; - assert(copy != v2); - assert(v2.size() == 3); - assert(v2[2] == 2); - assert(v2[1] == 1); - assert(v2[0] == 0); + BOOST_CHECK(copy != v2); + BOOST_CHECK(v2.size() == 3); + BOOST_CHECK(v2[2] == 2); + BOOST_CHECK(v2[1] == 1); + BOOST_CHECK(v2[0] == 0); v2[0] = -2; v2[1] = -1; v2[2] = 0; - assert(v2[2] == 0); - assert(v2[1] == -1); - assert(v2[0] == -2); + BOOST_CHECK(v2[2] == 0); + BOOST_CHECK(v2[1] == -1); + BOOST_CHECK(v2[0] == -2); SmallVectorInt v3(1,1); - assert(v3[0] == 1); + BOOST_CHECK(v3[0] == 1); v2 = v3; - assert(v2.size() == 1); - assert(v2[0] == 1); + BOOST_CHECK(v2.size() == 1); + BOOST_CHECK(v2[0] == 1); SmallVectorInt v4(10, 1); - assert(v4.size() == 10); - assert(v4[5] == 1); - assert(v4[9] == 1); + BOOST_CHECK(v4.size() == 10); + BOOST_CHECK(v4[5] == 1); + BOOST_CHECK(v4[9] == 1); v4 = v; - assert(v4.size() == 3); - assert(v4[2] == 2); - assert(v4[1] == 1); - assert(v4[0] == 0); + BOOST_CHECK(v4.size() == 3); + BOOST_CHECK(v4[2] == 2); + BOOST_CHECK(v4[1] == 1); + BOOST_CHECK(v4[0] == 0); SmallVectorInt v5(10, 2); - assert(v5.size() == 10); - assert(v5[7] == 2); - assert(v5[0] == 2); - assert(v.size() == 3); + BOOST_CHECK(v5.size() == 10); + BOOST_CHECK(v5[7] == 2); + BOOST_CHECK(v5[0] == 2); + BOOST_CHECK(v.size() == 3); v = v5; - assert(v.size() == 10); - assert(v[2] == 2); - assert(v[9] == 2); + BOOST_CHECK(v.size() == 10); + BOOST_CHECK(v[2] == 2); + BOOST_CHECK(v[9] == 2); SmallVectorInt cc; for (int i = 0; i < 33; ++i) cc.push_back(i); for (int i = 0; i < 33; ++i) - assert(cc[i] == i); + BOOST_CHECK(cc[i] == i); cc.resize(20); - assert(cc.size() == 20); + BOOST_CHECK(cc.size() == 20); for (int i = 0; i < 20; ++i) - assert(cc[i] == i); + BOOST_CHECK(cc[i] == i); cc[0]=-1; cc.resize(1, 999); - assert(cc.size() == 1); - assert(cc[0] == -1); + BOOST_CHECK(cc.size() == 1); + BOOST_CHECK(cc[0] == -1); cc.resize(99, 99); for (int i = 1; i < 99; ++i) { cerr << i << " " << cc[i] << endl; - assert(cc[i] == 99); + BOOST_CHECK(cc[i] == 99); } cc.clear(); - assert(cc.size() == 0); + BOOST_CHECK(cc.size() == 0); } -TEST_F(SVTest, Small) { +BOOST_AUTO_TEST_CASE(Small) { SmallVectorInt v; SmallVectorInt v1(1,0); SmallVectorInt v2(2,10); SmallVectorInt v1a(2,0); - EXPECT_TRUE(v1 != v1a); - EXPECT_TRUE(v1 == v1); - EXPECT_EQ(v1[0], 0); - EXPECT_EQ(v2[1], 10); - EXPECT_EQ(v2[0], 10); + BOOST_CHECK(v1 != v1a); + BOOST_CHECK(v1 == v1); + BOOST_CHECK_EQUAL(v1[0], 0); + BOOST_CHECK_EQUAL(v2[1], 10); + BOOST_CHECK_EQUAL(v2[0], 10); ++v2[1]; --v2[0]; - EXPECT_EQ(v2[0], 9); - EXPECT_EQ(v2[1], 11); + BOOST_CHECK_EQUAL(v2[0], 9); + BOOST_CHECK_EQUAL(v2[1], 11); SmallVectorInt v3(v2); - assert(v3[0] == 9); - assert(v3[1] == 11); - assert(!v3.empty()); - assert(v3.size() == 2); + BOOST_CHECK(v3[0] == 9); + BOOST_CHECK(v3[1] == 11); + BOOST_CHECK(!v3.empty()); + BOOST_CHECK(v3.size() == 2); v3.clear(); - assert(v3.empty()); - assert(v3.size() == 0); - assert(v3 != v2); - assert(v2 != v3); + BOOST_CHECK(v3.empty()); + BOOST_CHECK(v3.size() == 0); + BOOST_CHECK(v3 != v2); + BOOST_CHECK(v2 != v3); v3 = v2; - assert(v3 == v2); - assert(v2 == v3); - assert(v3[0] == 9); - assert(v3[1] == 11); - assert(!v3.empty()); - assert(v3.size() == 2); + BOOST_CHECK(v3 == v2); + BOOST_CHECK(v2 == v3); + BOOST_CHECK(v3[0] == 9); + BOOST_CHECK(v3[1] == 11); + BOOST_CHECK(!v3.empty()); + BOOST_CHECK(v3.size() == 2); cerr << sizeof(SmallVectorInt) << endl; cerr << sizeof(vector) << endl; } - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - diff --git a/utils/weights_test.cc b/utils/weights_test.cc index 938b311f..4be4c40f 100644 --- a/utils/weights_test.cc +++ b/utils/weights_test.cc @@ -1,26 +1,12 @@ -#include -#include -#include -#include -#include +#define BOOST_TEST_MODULE WeightsTest +#include +#include #include "weights.h" -#include "tdict.h" using namespace std; -class WeightsTest : public testing::Test { - protected: - virtual void SetUp() { } - virtual void TearDown() { } -}; - -TEST_F(WeightsTest,Load) { +BOOST_AUTO_TEST_CASE(Load) { vector v; Weights::InitFromFile("test_data/weights", &v); Weights::WriteToFile("-", v); } - -int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -- cgit v1.2.3