blob: 663c136940383e45f9510599d3c669bdd3f89d76 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <limits>
#include <string>
#include <gtest/gtest.h>
#include "tools/fidl/fidlc/src/versioning_types.h"
namespace fidlc {
namespace {
using Legacy = Availability::Legacy;
using InheritResult = Availability::InheritResult;
using Status = InheritResult::Status;
using LegacyStatus = InheritResult::LegacyStatus;
Version v(uint64_t x) { return Version::From(x).value(); }
VersionRange range(uint64_t x, uint64_t y) { return VersionRange(v(x), v(y)); }
VersionSet set(uint64_t x, uint64_t y) { return VersionSet(range(x, y)); }
VersionSet set(std::pair<uint64_t, uint64_t> a, std::pair<uint64_t, uint64_t> b) {
return VersionSet(range(a.first, a.second), range(b.first, b.second));
}
TEST(VersioningTypesTests, GoodPlatformParse) {
EXPECT_EQ(Platform::Parse("foo123").value().name(), "foo123");
}
TEST(VersioningTypesTests, GoodPlatformUnversioned) {
EXPECT_TRUE(Platform::Unversioned().is_unversioned());
EXPECT_TRUE(Platform::Parse("unversioned").value().is_unversioned());
EXPECT_FALSE(Platform::Parse("foo123").value().is_unversioned());
}
TEST(VersioningTypesTests, BadPlatformParseEmpty) { EXPECT_FALSE(Platform::Parse("").has_value()); }
TEST(VersioningTypesTests, BadPlatformParseInvalidChar) {
EXPECT_FALSE(Platform::Parse("foo_bar").has_value());
}
TEST(VersioningTypesTests, GoodPlatformEquality) {
EXPECT_EQ(Platform::Parse("foo").value(), Platform::Parse("foo").value());
EXPECT_EQ(Platform::Unversioned(), Platform::Unversioned());
EXPECT_EQ(Platform::Parse("unversioned").value(), Platform::Unversioned());
EXPECT_NE(Platform::Parse("foo").value(), Platform::Parse("bar").value());
EXPECT_NE(Platform::Parse("foo").value(), Platform::Unversioned());
}
TEST(VersioningTypesTests, GoodVersionFromMinNumeric) {
auto maybe_version = Version::From(1);
ASSERT_TRUE(maybe_version.has_value());
EXPECT_EQ(maybe_version.value().ordinal(), 1u);
EXPECT_EQ(maybe_version.value().ToString(), "1");
}
TEST(VersioningTypesTests, GoodVersionFromMaxNumeric) {
uint64_t ordinal = (1ull << 63) - 1;
auto maybe_version = Version::From(ordinal);
ASSERT_TRUE(maybe_version.has_value());
EXPECT_EQ(maybe_version.value().ordinal(), ordinal);
EXPECT_EQ(maybe_version.value().ToString(), std::to_string(ordinal));
// Confirm this is in fact the last valid ordinal.
EXPECT_EQ(Version::From(ordinal + 1), std::nullopt);
}
TEST(VersioningTypesTests, GoodVersionFromHead) {
uint64_t ordinal = std::numeric_limits<uint64_t>::max() - 1;
auto maybe_version = Version::From(ordinal);
ASSERT_TRUE(maybe_version.has_value());
EXPECT_EQ(maybe_version.value().ordinal(), ordinal);
EXPECT_EQ(maybe_version.value().ToString(), "HEAD");
}
TEST(VersioningTypesTests, GoodVersionFromLegacy) {
uint64_t ordinal = std::numeric_limits<uint64_t>::max();
auto maybe_version = Version::From(ordinal);
ASSERT_TRUE(maybe_version.has_value());
EXPECT_EQ(maybe_version.value().ordinal(), ordinal);
EXPECT_EQ(maybe_version.value().ToString(), "LEGACY");
}
TEST(VersioningTypesTests, BadVersionFrom) {
ASSERT_EQ(Version::From(0), std::nullopt);
ASSERT_EQ(Version::From(1ull << 63), std::nullopt);
ASSERT_EQ(Version::From(std::numeric_limits<uint64_t>::max() - 2), std::nullopt);
}
TEST(VersioningTypesTests, GoodVersionParse) {
uint64_t max_numeric_ordinal = (1ull << 63) - 1;
uint64_t head_ordinal = std::numeric_limits<uint64_t>::max() - 1;
uint64_t legacy_ordinal = std::numeric_limits<uint64_t>::max();
EXPECT_EQ(Version::Parse("1"), v(1));
EXPECT_EQ(Version::Parse(std::to_string(max_numeric_ordinal)), v(max_numeric_ordinal));
EXPECT_EQ(Version::Parse(std::to_string(head_ordinal)), v(head_ordinal));
EXPECT_EQ(Version::Parse(std::to_string(legacy_ordinal)), v(legacy_ordinal));
EXPECT_EQ(Version::Parse("HEAD"), v(head_ordinal));
EXPECT_EQ(Version::Parse("LEGACY"), v(legacy_ordinal));
}
TEST(VersioningTypesTests, BadVersionParse) {
EXPECT_EQ(Version::Parse(""), std::nullopt);
EXPECT_EQ(Version::Parse("0"), std::nullopt);
EXPECT_EQ(Version::Parse("9223372036854775808"), std::nullopt); // 2^63
EXPECT_EQ(Version::Parse("18446744073709551616"), std::nullopt); // 2^64
EXPECT_EQ(Version::Parse("-1"), std::nullopt);
}
TEST(VersioningTypesTests, GoodVersionRangeComparisons) {
EXPECT_EQ(range(1, 2), range(1, 2));
EXPECT_EQ(range(2, 3), range(2, 3));
EXPECT_NE(range(1, 2), range(1, 3));
EXPECT_NE(range(1, 3), range(2, 3));
EXPECT_NE(range(2, 3), range(1, 2));
EXPECT_LT(range(1, 2), range(1, 3));
EXPECT_LT(range(1, 3), range(2, 3));
EXPECT_LT(range(1, 2), range(2, 3));
EXPECT_GT(range(1, 3), range(1, 2));
EXPECT_GT(range(2, 3), range(1, 3));
EXPECT_GT(range(2, 3), range(1, 2));
}
TEST(VersioningTypesTests, GoodVersionRangeIntersect) {
// Case #1: (empty) (empty)
EXPECT_EQ(VersionRange::Intersect(std::nullopt, std::nullopt), std::nullopt);
// Case #2: (empty) |---|
EXPECT_EQ(VersionRange::Intersect(std::nullopt, range(3, 6)), std::nullopt);
// Case #3: |---| (empty)
EXPECT_EQ(VersionRange::Intersect(range(3, 6), std::nullopt), std::nullopt);
// Case #4: |---|
// |--|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(7, 9))), std::nullopt);
// Case #5: |---|
// |--|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(6, 8))), std::nullopt);
// Case #6: |---|
// |--|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(5, 7))), range(5, 6));
// Case #7: |---|
// |--|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(4, 6))), range(4, 6));
// Case #8: |---|
// |--|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(3, 5))), range(3, 5));
// Case #9: |---|
// |-|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(4, 5))), range(4, 5));
// Case #10: |---|
// |---|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(3, 6))), range(3, 6));
// Case #11: |---|
// |--|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(2, 4))), range(3, 4));
// Case #12: |---|
// |--|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(1, 3))), std::nullopt);
// Case #13: |---|
// |--|
EXPECT_EQ(VersionRange::Intersect(range(3, 6), (range(1, 2))), std::nullopt);
}
TEST(VersioningTypesTests, GoodVersionSetContains) {
VersionSet two_three(range(2, 4));
EXPECT_FALSE(VersionSet(two_three).Contains(v(1)));
EXPECT_TRUE(VersionSet(two_three).Contains(v(2)));
EXPECT_TRUE(VersionSet(two_three).Contains(v(3)));
EXPECT_FALSE(VersionSet(two_three).Contains(v(4)));
EXPECT_FALSE(VersionSet(two_three).Contains(v(5)));
EXPECT_FALSE(VersionSet(two_three).Contains(v(6)));
VersionSet two_three_five(range(2, 4), range(5, 6));
EXPECT_FALSE(two_three_five.Contains(v(1)));
EXPECT_TRUE(two_three_five.Contains(v(2)));
EXPECT_TRUE(two_three_five.Contains(v(3)));
EXPECT_FALSE(two_three_five.Contains(v(4)));
EXPECT_TRUE(two_three_five.Contains(v(5)));
EXPECT_FALSE(two_three_five.Contains(v(6)));
}
TEST(VersioningTypesTests, GoodVersionSetIntersect) {
// Case #1: (empty) (empty)
EXPECT_EQ(VersionSet::Intersect(std::nullopt, std::nullopt), std::nullopt);
// Case #2: |---| (empty)
EXPECT_EQ(VersionSet::Intersect(set(1, 3), std::nullopt), std::nullopt);
// Case #3: (empty) |---|
EXPECT_EQ(VersionSet::Intersect(std::nullopt, set(1, 3)), std::nullopt);
// Case #4: |---|
// |---|
EXPECT_EQ(VersionSet::Intersect(set(1, 3), set(3, 5)), std::nullopt);
// Case #5: |---|
// |---|
EXPECT_EQ(VersionSet::Intersect(set(1, 3), set(1, 3)), set(1, 3));
// Case #6: |---| |---|
// |---|
EXPECT_EQ(VersionSet::Intersect(set({1, 3}, {4, 6}), set(6, 8)), std::nullopt);
// Case #7: |---| |---|
// |---|
EXPECT_EQ(VersionSet::Intersect(set({1, 3}, {4, 6}), set(4, 6)), set(4, 6));
// Case #8: |---| |---|
// |---|
EXPECT_EQ(VersionSet::Intersect(set({1, 3}, {4, 6}), set(2, 5)), set({2, 3}, {4, 5}));
// Case #9: |---| |---|
// |---|
EXPECT_EQ(VersionSet::Intersect(set({1, 3}, {4, 6}), set(1, 3)), set(1, 3));
// Case #10: |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set(6, 8), set({1, 3}, {4, 6})), std::nullopt);
// Case #11: |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set(4, 6), set({1, 3}, {4, 6})), set(4, 6));
// Case #12: |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set(2, 5), set({1, 3}, {4, 6})), set({2, 3}, {4, 5}));
// Case #13: |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set(1, 3), set({1, 3}, {4, 6})), set(1, 3));
// Case #14: |---| |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set({1, 3}, {4, 6}), set({6, 8}, {9, 11})), std::nullopt);
// Case #15: |---| |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set({1, 3}, {4, 6}), set({4, 6}, {7, 9})), set(4, 6));
// Case #16: |---| |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set({1, 3}, {4, 6}), set({2, 5}, {6, 8})), set({2, 3}, {4, 5}));
// Case #17: |---| |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set({1, 3}, {4, 6}), set({1, 3}, {4, 6})), set({1, 3}, {4, 6}));
// Case #18: |---| |---|
// |---| |---|
EXPECT_EQ(VersionSet::Intersect(set({2, 5}, {6, 8}), set({1, 3}, {4, 6})), set({2, 3}, {4, 5}));
}
TEST(VersioningTypesTests, GoodAvailabilityInitNone) {
Availability availability;
ASSERT_TRUE(availability.Init({}));
EXPECT_EQ(availability.Debug(), "_ _ _ _");
}
TEST(VersioningTypesTests, GoodAvailabilityInitAdded) {
Availability availability;
ASSERT_TRUE(availability.Init({.added = v(1)}));
EXPECT_EQ(availability.Debug(), "1 _ _ _");
}
TEST(VersioningTypesTests, GoodAvailabilityInitLegacy) {
Availability availability;
ASSERT_TRUE(availability.Init({.legacy = Legacy::kYes}));
EXPECT_EQ(availability.Debug(), "_ _ _ yes");
}
TEST(VersioningTypesTests, GoodAvailabilityInitAll) {
Availability availability;
ASSERT_TRUE(availability.Init(
{.added = v(1), .deprecated = v(2), .removed = v(3), .legacy = Legacy::kNo}));
EXPECT_EQ(availability.Debug(), "1 2 3 no");
}
TEST(VersioningTypesTests, BadAvailabilityInitWrongOrder) {
Availability availability;
EXPECT_FALSE(availability.Init({.added = v(1), .removed = v(1)}));
}
TEST(VersioningTypesTests, GoodAvailabilityInheritUnbounded) {
Availability availability;
ASSERT_TRUE(availability.Init({.added = v(1)}));
ASSERT_TRUE(availability.Inherit(Availability::Unbounded()).Ok());
EXPECT_EQ(availability.Debug(), "1 _ +inf n/a");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritUnset) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .deprecated = v(2), .removed = v(3)}));
ASSERT_TRUE(child.Init({}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 2 3 no");
EXPECT_EQ(child.Debug(), "1 2 3 no");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritUnchanged) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .deprecated = v(2), .removed = v(3)}));
ASSERT_TRUE(child.Init({.added = v(1), .deprecated = v(2), .removed = v(3)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 2 3 no");
EXPECT_EQ(child.Debug(), "1 2 3 no");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritPartial) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1)}));
ASSERT_TRUE(child.Init({.removed = v(2)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 _ +inf n/a");
EXPECT_EQ(child.Debug(), "1 _ 2 no");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritChangeDeprecation) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .deprecated = v(1)}));
ASSERT_TRUE(child.Init({.added = v(2)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 1 +inf n/a");
EXPECT_EQ(child.Debug(), "2 2 +inf n/a");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritEliminateDeprecation) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .deprecated = v(2)}));
ASSERT_TRUE(child.Init({.removed = v(2)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 2 +inf n/a");
EXPECT_EQ(child.Debug(), "1 _ 2 no");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritLegacyRemovedAtSameTime) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .removed = v(2), .legacy = Legacy::kYes}));
ASSERT_TRUE(child.Init({.removed = v(2)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 _ 2 yes");
EXPECT_EQ(child.Debug(), "1 _ 2 yes");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritLegacyRemovedEarlier) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .removed = v(3), .legacy = Legacy::kYes}));
ASSERT_TRUE(child.Init({.removed = v(2)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 _ 3 yes");
EXPECT_EQ(child.Debug(), "1 _ 2 no");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritLegacyOverride) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .removed = v(2), .legacy = Legacy::kYes}));
ASSERT_TRUE(child.Init({.legacy = Legacy::kNo}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 _ 2 yes");
EXPECT_EQ(child.Debug(), "1 _ 2 no");
}
TEST(VersioningTypesTests, GoodAvailabilityInheritLegacyExplicitNo) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .removed = v(2), .legacy = Legacy::kNo}));
ASSERT_TRUE(child.Init({.legacy = Legacy::kNo}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
ASSERT_TRUE(child.Inherit(parent).Ok());
EXPECT_EQ(parent.Debug(), "1 _ 2 no");
EXPECT_EQ(child.Debug(), "1 _ 2 no");
}
TEST(VersioningTypesTests, BadAvailabilityInheritBeforeParentCompletely) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(3)}));
ASSERT_TRUE(child.Init({.added = v(1), .deprecated = v(2), .removed = v(3)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
auto status = child.Inherit(parent);
EXPECT_EQ(status.added, Status::kBeforeParentAdded);
EXPECT_EQ(status.deprecated, Status::kBeforeParentAdded);
EXPECT_EQ(status.removed, Status::kBeforeParentAdded);
EXPECT_EQ(status.legacy, LegacyStatus::kOk);
}
TEST(VersioningTypesTests, BadAvailabilityInheritBeforeParentPartially) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(3)}));
ASSERT_TRUE(child.Init({.added = v(1), .deprecated = v(2), .removed = v(4)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
auto status = child.Inherit(parent);
EXPECT_EQ(status.added, Status::kBeforeParentAdded);
EXPECT_EQ(status.deprecated, Status::kBeforeParentAdded);
EXPECT_EQ(status.removed, Status::kOk);
EXPECT_EQ(status.legacy, LegacyStatus::kOk);
}
TEST(VersioningTypesTests, BadAvailabilityInheritAfterParentCompletely) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .removed = v(2)}));
ASSERT_TRUE(child.Init({.added = v(2), .deprecated = v(3), .removed = v(4)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
auto status = child.Inherit(parent);
EXPECT_EQ(status.added, Status::kAfterParentRemoved);
EXPECT_EQ(status.deprecated, Status::kAfterParentRemoved);
EXPECT_EQ(status.removed, Status::kAfterParentRemoved);
EXPECT_EQ(status.legacy, LegacyStatus::kOk);
}
TEST(VersioningTypesTests, BadAvailabilityInheritAfterParentPartially) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .removed = v(2)}));
ASSERT_TRUE(child.Init({.added = v(1), .deprecated = v(2), .removed = v(3)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
auto status = child.Inherit(parent);
EXPECT_EQ(status.added, Status::kOk);
EXPECT_EQ(status.deprecated, Status::kAfterParentRemoved);
EXPECT_EQ(status.removed, Status::kAfterParentRemoved);
EXPECT_EQ(status.legacy, LegacyStatus::kOk);
}
TEST(VersioningTypesTests, BadAvailabilityInheritAfterParentDeprecated) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .deprecated = v(2)}));
ASSERT_TRUE(child.Init({.added = v(1), .deprecated = v(3), .removed = v(4)}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
auto status = child.Inherit(parent);
EXPECT_EQ(status.added, Status::kOk);
EXPECT_EQ(status.deprecated, Status::kAfterParentDeprecated);
EXPECT_EQ(status.removed, Status::kOk);
EXPECT_EQ(status.legacy, LegacyStatus::kOk);
}
TEST(VersioningTypesTests, BadAvailabilityInheritLegacyNoNeverRemoved) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1)}));
ASSERT_TRUE(child.Init({.legacy = Legacy::kNo}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
auto status = child.Inherit(parent);
EXPECT_EQ(status.added, Status::kOk);
EXPECT_EQ(status.deprecated, Status::kOk);
EXPECT_EQ(status.removed, Status::kOk);
EXPECT_EQ(status.legacy, LegacyStatus::kNeverRemoved);
}
TEST(VersioningTypesTests, BadAvailabilityInheritLegacyYesNeverRemoved) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1)}));
ASSERT_TRUE(child.Init({.legacy = Legacy::kYes}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
auto status = child.Inherit(parent);
EXPECT_EQ(status.added, Status::kOk);
EXPECT_EQ(status.deprecated, Status::kOk);
EXPECT_EQ(status.removed, Status::kOk);
EXPECT_EQ(status.legacy, LegacyStatus::kNeverRemoved);
}
TEST(VersioningTypesTests, BadAvailabilityInheritLegacyWithoutParent) {
Availability parent, child;
ASSERT_TRUE(parent.Init({.added = v(1), .removed = v(2)}));
ASSERT_TRUE(child.Init({.legacy = Legacy::kYes}));
ASSERT_TRUE(parent.Inherit(Availability::Unbounded()).Ok());
auto status = child.Inherit(parent);
EXPECT_EQ(status.added, Status::kOk);
EXPECT_EQ(status.deprecated, Status::kOk);
EXPECT_EQ(status.removed, Status::kOk);
EXPECT_EQ(status.legacy, LegacyStatus::kWithoutParent);
}
TEST(VersioningTypesTests, GoodAvailabilityDecomposeWhole) {
Availability availability;
ASSERT_TRUE(availability.Init({.added = v(1), .removed = v(2)}));
ASSERT_TRUE(availability.Inherit(Availability::Unbounded()).Ok());
availability.Narrow(range(1, 2));
EXPECT_EQ(availability.Debug(), "1 _ 2 no");
}
} // namespace
} // namespace fidlc