Skip to content

Commit

Permalink
Add unit test for XKCD 3038 alt-text (#377)
Browse files Browse the repository at this point in the history
See for context: <https://xkcd.com/3038/>.  Presumably, the joke only
works if the speed limit in question corresponds to a realistic speed
limit for American roads, so we take the range to be from 25 MPH (many
residential streets) to 75 MPH (some roads in places I have seen such as
parts of MI or TX).

To make this work, it was convenient to add unit definitions for
`Arcminutes` and `Arcseconds`.  These have various choices for unit
symbol, but I decided to go with `am` and `as` because this will be the
most consistent with users who form symbols for `mas` and `uas`.

For the labels, in any case, I went with `'` and `"`.  I could be
persuaded to go with `''` for arcseconds, but I think `"` is likely to
be better overall.

We also now group all of our XKCD test cases into an `Xkcd` test family,
because of course we do.
  • Loading branch information
chiphogg authored Jan 15, 2025
1 parent 6d0f7c0 commit 598de94
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 1 deletion.
6 changes: 6 additions & 0 deletions au/code/au/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ header_only_library(
stdx/utility.hh
units/amperes.hh
units/amperes_fwd.hh
units/arcminutes.hh
units/arcminutes_fwd.hh
units/arcseconds.hh
units/arcseconds_fwd.hh
units/bars.hh
units/bars_fwd.hh
units/becquerel.hh
Expand Down Expand Up @@ -306,6 +310,8 @@ gtest_based_test(
NAME units_test
SRCS
units/test/amperes_test.cc
units/test/arcminutes_test.cc
units/test/arcseconds_test.cc
units/test/bars_test.cc
units/test/becquerel_test.cc
units/test/bits_test.cc
Expand Down
22 changes: 21 additions & 1 deletion au/code/au/au_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@

#include "au/au.hh"

#include "au/constants/speed_of_light.hh"
#include "au/prefix.hh"
#include "au/testing.hh"
#include "au/units/arcminutes.hh"
#include "au/units/celsius.hh"
#include "au/units/fahrenheit.hh"
#include "au/units/fathoms.hh"
Expand All @@ -26,12 +28,19 @@
#include "au/units/knots.hh"
#include "au/units/meters.hh"
#include "au/units/miles.hh"
#include "au/units/steradians.hh"
#include "au/units/yards.hh"
#include "gtest/gtest.h"

using ::testing::StaticAssertTypeEq;

namespace au {
namespace {
template <typename T, typename U>
auto IsBetween(T lower, U upper) {
return ::testing::AllOf(::testing::Ge(lower), ::testing::Le(upper));
}
} // namespace

TEST(Conversions, SupportIntMHzToU32Hz) {
constexpr QuantityU32<Hertz> freq = mega(hertz)(40);
Expand All @@ -54,7 +63,7 @@ constexpr auto round_sequentially(Quantity<U, R> q, FirstUnit first_unit, NextUn
return round_sequentially(round_as(first_unit, q), next_units...);
}

TEST(RoundAs, ReproducesXkcd2585) {
TEST(Xkcd, RoundAsReproducesXkcd2585) {
constexpr auto true_speed = (miles / hour)(17);

const auto rounded_speed = round_sequentially(true_speed,
Expand Down Expand Up @@ -86,6 +95,17 @@ TEST(RoundAs, ReproducesXkcd2585) {
EXPECT_EQ((miles / hour)(45), rounded_speed);
}

TEST(Xkcd, Xkcd3038GivesReasonableSpeedLimit) {
using symbols::h;
using symbols::mi;

constexpr auto c = SPEED_OF_LIGHT;
constexpr auto SPEED_LIMIT = make_constant(c * squared(arcminutes) / steradian);

EXPECT_THAT(SPEED_LIMIT, IsBetween(25.0 * mi / h, 75.0 * mi / h))
<< SPEED_LIMIT.as<double>(mi / h);
}

TEST(QuantityPoint, DocumentationExampleIsCorrect) {
EXPECT_LT(fahrenheit_pt(-40) + celsius_qty(60), kelvins_pt(300));
}
Expand Down
44 changes: 44 additions & 0 deletions au/code/au/units/arcminutes.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2025 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/units/arcminutes_fwd.hh"
// Keep corresponding `_fwd.hh` file on top.

#include "au/quantity.hh"
#include "au/unit_symbol.hh"
#include "au/units/degrees.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/).
template <typename T>
struct ArcminutesLabel {
static constexpr const char label[] = "'";
};
template <typename T>
constexpr const char ArcminutesLabel<T>::label[];
struct Arcminutes : decltype(Degrees{} / mag<60>()), ArcminutesLabel<void> {
using ArcminutesLabel<void>::label;
};
constexpr auto arcminute = SingularNameFor<Arcminutes>{};
constexpr auto arcminutes = QuantityMaker<Arcminutes>{};

namespace symbols {
constexpr auto am = SymbolFor<Arcminutes>{};
}

} // namespace au
21 changes: 21 additions & 0 deletions au/code/au/units/arcminutes_fwd.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2025 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

namespace au {

struct Arcminutes;

} // namespace au
44 changes: 44 additions & 0 deletions au/code/au/units/arcseconds.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2025 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "au/units/arcseconds_fwd.hh"
// Keep corresponding `_fwd.hh` file on top.

#include "au/quantity.hh"
#include "au/unit_symbol.hh"
#include "au/units/degrees.hh"

namespace au {

// DO NOT follow this pattern to define your own units. This is for library-defined units.
// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/).
template <typename T>
struct ArcsecondsLabel {
static constexpr const char label[] = "\"";
};
template <typename T>
constexpr const char ArcsecondsLabel<T>::label[];
struct Arcseconds : decltype(Degrees{} / mag<3600>()), ArcsecondsLabel<void> {
using ArcsecondsLabel<void>::label;
};
constexpr auto arcsecond = SingularNameFor<Arcseconds>{};
constexpr auto arcseconds = QuantityMaker<Arcseconds>{};

namespace symbols {
constexpr auto as = SymbolFor<Arcseconds>{};
}

} // namespace au
21 changes: 21 additions & 0 deletions au/code/au/units/arcseconds_fwd.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2025 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

namespace au {

struct Arcseconds;

} // namespace au
34 changes: 34 additions & 0 deletions au/code/au/units/test/arcminutes_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2025 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "au/units/arcminutes.hh"

#include "au/testing.hh"
#include "au/units/degrees.hh"
#include "gtest/gtest.h"

namespace au {

using ::testing::Eq;

TEST(Arcminutes, HasExpectedLabel) { expect_label<Arcminutes>("'"); }

TEST(Arcminutes, RelatesCorrectlyToDegrees) { EXPECT_THAT(arcminutes(120.0), Eq(degrees(2.0))); }

TEST(Arcminutes, HasExpectedSymbol) {
using symbols::am;
EXPECT_THAT(5.f * am, SameTypeAndValue(arcminutes(5.f)));
}

} // namespace au
34 changes: 34 additions & 0 deletions au/code/au/units/test/arcseconds_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2025 Aurora Operations, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "au/units/arcseconds.hh"

#include "au/testing.hh"
#include "au/units/degrees.hh"
#include "gtest/gtest.h"

namespace au {

using ::testing::Eq;

TEST(Arcseconds, HasExpectedLabel) { expect_label<Arcseconds>("\""); }

TEST(Arcseconds, RelatesCorrectlyToDegrees) { EXPECT_THAT(arcseconds(7200.0), Eq(degrees(2.0))); }

TEST(Arcseconds, HasExpectedSymbol) {
using symbols::as;
EXPECT_THAT(5.f * as, SameTypeAndValue(arcseconds(5.f)));
}

} // namespace au

0 comments on commit 598de94

Please sign in to comment.