Compare commits

..

6 commits

Author SHA1 Message Date
Khlopkova Olga
a3638306ef Changed default StopLocationType to StopOrPlatform 2021-02-05 17:56:27 +03:00
Olga Khlopkova
5bd1df553f
Merge pull request #8 from pranavpandey1998official/master
feat: made compatible with c++14
2021-02-04 16:17:15 +03:00
Khlopkova Olga
616c3c0107 Fixes for boost 1.65 2021-02-04 16:14:17 +03:00
Khlopkova Olga
dc130720b2 Fix for c++ 14 CI build 2021-02-04 15:55:04 +03:00
Pranav Pandey
ed604feba7 fix: ci cd 2021-02-01 21:29:28 +05:30
Pranav Pandey
dfc4f06f1a feat: made compatible with c++14 2021-01-30 16:41:52 +05:30
9 changed files with 153 additions and 269 deletions

View file

@ -2,9 +2,9 @@ name: C/C++ CI
on:
push:
branches: [ master, add-* ]
branches: [ cpp14, add-* ]
pull_request:
branches: [ master ]
branches: [ cpp14 ]
jobs:
build:
@ -13,6 +13,9 @@ jobs:
steps:
- uses: actions/checkout@v2
# install dependencies
- name: boost
run: sudo apt-get update && sudo apt-get install -yq libboost1.65-dev
- name: git_actions
run: git submodule update --init --recursive
- name: cmake

View file

@ -1,34 +0,0 @@
name: "CLA Assistant"
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened,closed,synchronize]
jobs:
CLAssistant:
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
# Alpha Release
uses: cla-assistant/github-action@v2.1.0-alpha
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }}
with:
path-to-signatures: 'signatures/version1/cla.json'
path-to-document: 'https://github.com/mapsme/just_gtfs/blob/master/MIT_CLA.md'
# branch should not be protected
branch: 'master'
allowlist: mesozoic-drones,tatiana-yan,bot*
#below are the optional inputs - If the optional inputs are not given, then default values will be taken
#remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
#remote-repository-name: enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository)
#create-file-commit-message: 'For example: Creating file for storing CLA Signatures'
#signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo'
#custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
#custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
#custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'

View file

@ -5,10 +5,13 @@ project(just_gtfs LANGUAGES CXX VERSION 0.1)
include_directories(include)
include_directories(doctest/doctest)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
find_package(Boost 1.65 COMPONENTS program_options)
include_directories( ${Boost_INCLUDE_DIR} )
enable_testing()
add_library(just_gtfs INTERFACE)

View file

@ -1,59 +0,0 @@
## Individual Contributor License Agreement (CLA)
**Thank you for submitting your contributions to this project.**
By signing this CLA, you agree that the following terms apply to all of your past, present and future contributions
to the project.
### License.
You hereby represent that all present, past and future contributions are governed by the
[MIT License](https://opensource.org/licenses/MIT)
copyright statement.
This entails that to the extent possible under law, you transfer all copyright and related or neighboring rights
of the code or documents you contribute to the project itself or its maintainers.
Furthermore you also represent that you have the authority to perform the above waiver
with respect to the entirety of you contributions.
### Moral Rights.
To the fullest extent permitted under applicable law, you hereby waive, and agree not to
assert, all of your “moral rights” in or relating to your contributions for the benefit of the project.
### Third Party Content.
If your Contribution includes or is based on any source code, object code, bug fixes, configuration changes, tools,
specifications, documentation, data, materials, feedback, information or other works of authorship that were not
authored by you (“Third Party Content”) or if you are aware of any third party intellectual property or proprietary
rights associated with your Contribution (“Third Party Rights”),
then you agree to include with the submission of your Contribution full details respecting such Third Party
Content and Third Party Rights, including, without limitation, identification of which aspects of your
Contribution contain Third Party Content or are associated with Third Party Rights, the owner/author of the
Third Party Content and Third Party Rights, where you obtained the Third Party Content, and any applicable
third party license terms or restrictions respecting the Third Party Content and Third Party Rights. For greater
certainty, the foregoing obligations respecting the identification of Third Party Content and Third Party Rights
do not apply to any portion of a Project that is incorporated into your Contribution to that same Project.
### Representations.
You represent that, other than the Third Party Content and Third Party Rights identified by
you in accordance with this Agreement, you are the sole author of your Contributions and are legally entitled
to grant the foregoing licenses and waivers in respect of your Contributions. If your Contributions were
created in the course of your employment with your past or present employer(s), you represent that such
employer(s) has authorized you to make your Contributions on behalf of such employer(s) or such employer
(s) has waived all of their right, title or interest in or to your Contributions.
### Disclaimer.
To the fullest extent permitted under applicable law, your Contributions are provided on an "as is"
basis, without any warranties or conditions, express or implied, including, without limitation, any implied
warranties or conditions of non-infringement, merchantability or fitness for a particular purpose. You are not
required to provide support for your Contributions, except to the extent you desire to provide support.
### No Obligation.
You acknowledge that the maintainers of this project are under no obligation to use or incorporate your contributions
into the project. The decision to use or incorporate your contributions into the project will be made at the
sole discretion of the maintainers or their authorized delegates.

View file

@ -21,29 +21,32 @@
#include <utility>
#include <vector>
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
namespace gtfs
{
// File names and other entities defined in GTFS----------------------------------------------------
inline const std::string file_agency = "agency.txt";
inline const std::string file_stops = "stops.txt";
inline const std::string file_routes = "routes.txt";
inline const std::string file_trips = "trips.txt";
inline const std::string file_stop_times = "stop_times.txt";
inline const std::string file_calendar = "calendar.txt";
inline const std::string file_calendar_dates = "calendar_dates.txt";
inline const std::string file_fare_attributes = "fare_attributes.txt";
inline const std::string file_fare_rules = "fare_rules.txt";
inline const std::string file_shapes = "shapes.txt";
inline const std::string file_frequencies = "frequencies.txt";
inline const std::string file_transfers = "transfers.txt";
inline const std::string file_pathways = "pathways.txt";
inline const std::string file_levels = "levels.txt";
inline const std::string file_feed_info = "feed_info.txt";
inline const std::string file_translations = "translations.txt";
inline const std::string file_attributions = "attributions.txt";
const std::string file_agency = "agency.txt";
const std::string file_stops = "stops.txt";
const std::string file_routes = "routes.txt";
const std::string file_trips = "trips.txt";
const std::string file_stop_times = "stop_times.txt";
const std::string file_calendar = "calendar.txt";
const std::string file_calendar_dates = "calendar_dates.txt";
const std::string file_fare_attributes = "fare_attributes.txt";
const std::string file_fare_rules = "fare_rules.txt";
const std::string file_shapes = "shapes.txt";
const std::string file_frequencies = "frequencies.txt";
const std::string file_transfers = "transfers.txt";
const std::string file_pathways = "pathways.txt";
const std::string file_levels = "levels.txt";
const std::string file_feed_info = "feed_info.txt";
const std::string file_translations = "translations.txt";
const std::string file_attributions = "attributions.txt";
inline constexpr char csv_separator = ',';
inline constexpr char quote = '"';
constexpr char csv_separator = ',';
constexpr char quote = '"';
// Helper classes and functions---------------------------------------------------------------------
struct InvalidFieldFormat : public std::exception
@ -455,7 +458,6 @@ public:
inline Time() = default;
inline explicit Time(const std::string & raw_time_str);
inline Time(uint16_t hours, uint16_t minutes, uint16_t seconds);
inline Time(size_t seconds);
inline bool is_provided() const;
inline size_t get_total_seconds() const;
inline std::tuple<uint16_t, uint16_t, uint16_t> get_hh_mm_ss() const;
@ -544,13 +546,6 @@ inline Time::Time(uint16_t hours, uint16_t minutes, uint16_t seconds)
time_is_provided = true;
}
inline Time::Time(size_t seconds)
: time_is_provided(true), total_seconds(seconds),
hh(seconds / 3600), mm((seconds % 3600) / 60), ss(seconds % 3600)
{
set_raw_time();
}
inline bool Time::is_provided() const { return time_is_provided; }
inline size_t Time::get_total_seconds() const { return total_seconds; }
@ -652,7 +647,7 @@ using CurrencyCode = std::string;
using LanguageCode = std::string;
// Helper enums for some GTFS fields ---------------------------------------------------------------
enum class StopLocationType : int8_t
enum class StopLocationType
{
StopOrPlatform = 0,
Station = 1,
@ -662,7 +657,7 @@ enum class StopLocationType : int8_t
};
// The type of transportation used on a route.
enum class RouteType : int16_t
enum class RouteType
{
// GTFS route types
Tram = 0, // Tram, Streetcar, Light rail
@ -760,20 +755,20 @@ enum class RouteType : int16_t
HorseDrawnCarriage = 1702
};
enum class TripDirectionId : bool
enum class TripDirectionId
{
DefaultDirection = 0, // e.g. outbound
OppositeDirection = 1 // e.g. inbound
};
enum class TripAccess : int8_t
enum class TripAccess
{
NoInfo = 0,
Yes = 1,
No = 2
};
enum class StopTimeBoarding : int8_t
enum class StopTimeBoarding
{
RegularlyScheduled = 0,
No = 1, // Not available
@ -781,31 +776,31 @@ enum class StopTimeBoarding : int8_t
CoordinateWithDriver = 3 // Must coordinate with driver to arrange
};
enum class StopTimePoint : bool
enum class StopTimePoint
{
Approximate = 0,
Exact = 1
};
enum class CalendarAvailability : bool
enum class CalendarAvailability
{
NotAvailable = 0,
Available = 1
};
enum class CalendarDateException : int8_t
enum class CalendarDateException
{
Added = 1, // Service has been added for the specified date
Removed = 2
};
enum class FarePayment : bool
enum class FarePayment
{
OnBoard = 0,
BeforeBoarding = 1 // Fare must be paid before boarding
};
enum class FareTransfers : int8_t
enum class FareTransfers
{
No = 0, // No transfers permitted on this fare
Once = 1,
@ -813,13 +808,13 @@ enum class FareTransfers : int8_t
Unlimited = 3
};
enum class FrequencyTripService : bool
enum class FrequencyTripService
{
FrequencyBased = 0, // Frequency-based trips
ScheduleBased = 1 // Schedule-based trips with the exact same headway throughout the day
};
enum class TransferType : int8_t
enum class TransferType
{
Recommended = 0,
Timed = 1,
@ -827,7 +822,7 @@ enum class TransferType : int8_t
NotPossible = 3
};
enum class PathwayMode : int8_t
enum class PathwayMode
{
Walkway = 1,
Stairs = 2,
@ -838,13 +833,13 @@ enum class PathwayMode : int8_t
ExitGate = 7
};
enum class PathwayDirection : bool
enum class PathwayDirection
{
Unidirectional = 0,
Bidirectional = 1
};
enum class AttributionRole : bool
enum class AttributionRole
{
No = 0, // Organization doesnt have this role
Yes = 1 // Organization does have this role
@ -1007,14 +1002,6 @@ struct FareAttributesItem
size_t transfer_duration = 0; // Length of time in seconds before a transfer expires
};
inline bool operator==(const FareAttributesItem & lhs, const FareAttributesItem & rhs)
{
return std::tie(lhs.fare_id, lhs.price, lhs.currency_type, lhs.payment_method, lhs.transfers,
lhs.agency_id, lhs.transfer_duration) ==
std::tie(rhs.fare_id, rhs.price, rhs.currency_type, rhs.payment_method, rhs.transfers,
rhs.agency_id, rhs.transfer_duration);
}
// Optional dataset file
struct FareRule
{
@ -1197,28 +1184,28 @@ public:
inline Result write_agencies(const std::string & gtfs_path) const;
inline const Agencies & get_agencies() const;
inline std::optional<Agency> get_agency(const Id & agency_id) const;
inline boost::optional<Agency> get_agency(const Id & agency_id) const;
inline void add_agency(const Agency & agency);
inline Result read_stops();
inline Result write_stops(const std::string & gtfs_path) const;
inline const Stops & get_stops() const;
inline std::optional<Stop> get_stop(const Id & stop_id) const;
inline boost::optional<Stop> get_stop(const Id & stop_id) const;
inline void add_stop(const Stop & stop);
inline Result read_routes();
inline Result write_routes(const std::string & gtfs_path) const;
inline const Routes & get_routes() const;
inline std::optional<Route> get_route(const Id & route_id) const;
inline boost::optional<Route> get_route(const Id & route_id) const;
inline void add_route(const Route & route);
inline Result read_trips();
inline Result write_trips(const std::string & gtfs_path) const;
inline const Trips & get_trips() const;
inline std::optional<Trip> get_trip(const Id & trip_id) const;
inline boost::optional<Trip> get_trip(const Id & trip_id) const;
inline void add_trip(const Trip & trip);
inline Result read_stop_times();
@ -1233,7 +1220,7 @@ public:
inline Result write_calendar(const std::string & gtfs_path) const;
inline const Calendar & get_calendar() const;
inline std::optional<CalendarItem> get_calendar(const Id & service_id) const;
inline boost::optional<CalendarItem> get_calendar(const Id & service_id) const;
inline void add_calendar_item(const CalendarItem & calendar_item);
inline Result read_calendar_dates();
@ -1275,7 +1262,7 @@ public:
inline Result write_transfers(const std::string & gtfs_path) const;
inline const Transfers & get_transfers() const;
inline std::optional<Transfer> get_transfer(const Id & from_stop_id, const Id & to_stop_id) const;
inline boost::optional<Transfer> get_transfer(const Id & from_stop_id, const Id & to_stop_id) const;
inline void add_transfer(const Transfer & transfer);
inline Result read_pathways();
@ -1290,7 +1277,7 @@ public:
inline Result write_levels(const std::string & gtfs_path) const;
inline const Levels & get_levels() const;
inline std::optional<Level> get_level(const Id & level_id) const;
inline boost::optional<Level> get_level(const Id & level_id) const;
inline void add_level(const Level & level);
inline Result read_feed_info();
@ -1356,7 +1343,6 @@ private:
inline void write_translations(std::ofstream & out) const;
inline void write_attributions(std::ofstream & out) const;
protected:
std::string gtfs_directory;
Agencies agencies;
@ -1389,57 +1375,74 @@ inline bool ErrorParsingOptionalFile(const Result & res)
inline Result Feed::read_feed()
{
// Read required files:
if (auto res = read_agencies(); res != ResultCode::OK)
auto res = read_agencies();
if (res != ResultCode::OK)
return res;
res = read_stops();
if (res != ResultCode::OK)
return res;
if (auto res = read_stops(); res != ResultCode::OK)
res = read_routes();
if (res != ResultCode::OK)
return res;
if (auto res = read_routes(); res != ResultCode::OK)
res = read_trips();
if (res != ResultCode::OK)
return res;
if (auto res = read_trips(); res != ResultCode::OK)
return res;
if (auto res = read_stop_times(); res != ResultCode::OK)
res = read_stop_times();
if (res != ResultCode::OK)
return res;
// Read conditionally required files:
if (auto res = read_calendar(); ErrorParsingOptionalFile(res))
res = read_calendar();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_calendar_dates(); ErrorParsingOptionalFile(res))
res = read_calendar_dates();
if (ErrorParsingOptionalFile(res))
return res;
// Read optional files:
if (auto res = read_shapes(); ErrorParsingOptionalFile(res))
res = read_shapes();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_transfers(); ErrorParsingOptionalFile(res))
res = read_transfers();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_frequencies(); ErrorParsingOptionalFile(res))
res = read_frequencies();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_fare_attributes(); ErrorParsingOptionalFile(res))
res = read_fare_attributes();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_fare_rules(); ErrorParsingOptionalFile(res))
res = read_fare_rules();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_pathways(); ErrorParsingOptionalFile(res))
res = read_pathways();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_levels(); ErrorParsingOptionalFile(res))
res = read_levels();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_attributions(); ErrorParsingOptionalFile(res))
res = read_attributions();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_feed_info(); ErrorParsingOptionalFile(res))
res = read_feed_info();
if (ErrorParsingOptionalFile(res))
return res;
if (auto res = read_translations(); ErrorParsingOptionalFile(res))
res = read_translations();
if (ErrorParsingOptionalFile(res))
return res;
return ResultCode::OK;
@ -1857,7 +1860,7 @@ inline Result Feed::add_fare_attributes(const ParsedCsvRow & row)
item.currency_type = row.at("currency_type");
set_field(item.payment_method, row, "payment_method", false);
set_field(item.transfers, row, "transfers");
set_field(item.transfers, row, "transfers", false);
// Conditionally optional:
item.agency_id = get_value_or_default(row, "agency_id");
@ -2159,7 +2162,7 @@ inline Result Feed::write_agencies(const std::string & gtfs_path) const
inline const Agencies & Feed::get_agencies() const { return agencies; }
inline std::optional<Agency> Feed::get_agency(const Id & agency_id) const
inline boost::optional<Agency> Feed::get_agency(const Id & agency_id) const
{
// agency id is required when the dataset contains data for multiple agencies,
// otherwise it is optional:
@ -2171,7 +2174,7 @@ inline std::optional<Agency> Feed::get_agency(const Id & agency_id) const
[&agency_id](const Agency & agency) { return agency.agency_id == agency_id; });
if (it == agencies.end())
return std::nullopt;
return boost::none;
return *it;
}
@ -2192,13 +2195,13 @@ inline Result Feed::write_stops(const std::string & gtfs_path) const
inline const Stops & Feed::get_stops() const { return stops; }
inline std::optional<Stop> Feed::get_stop(const Id & stop_id) const
inline boost::optional<Stop> Feed::get_stop(const Id & stop_id) const
{
const auto it = std::find_if(stops.begin(), stops.end(),
[&stop_id](const Stop & stop) { return stop.stop_id == stop_id; });
if (it == stops.end())
return std::nullopt;
return boost::none;
return *it;
}
@ -2219,14 +2222,14 @@ inline Result Feed::write_routes(const std::string & gtfs_path) const
inline const Routes & Feed::get_routes() const { return routes; }
inline std::optional<Route> Feed::get_route(const Id & route_id) const
inline boost::optional<Route> Feed::get_route(const Id & route_id) const
{
const auto it = std::find_if(routes.begin(), routes.end(), [&route_id](const Route & route) {
return route.route_id == route_id;
});
if (it == routes.end())
return std::nullopt;
return boost::none;
return *it;
}
@ -2247,13 +2250,13 @@ inline Result Feed::write_trips(const std::string & gtfs_path) const
inline const Trips & Feed::get_trips() const { return trips; }
inline std::optional<Trip> Feed::get_trip(const Id & trip_id) const
inline boost::optional<Trip> Feed::get_trip(const Id & trip_id) const
{
const auto it = std::find_if(trips.begin(), trips.end(),
[&trip_id](const Trip & trip) { return trip.trip_id == trip_id; });
if (it == trips.end())
return std::nullopt;
return boost::none;
return *it;
}
@ -2318,7 +2321,7 @@ inline Result Feed::write_calendar(const std::string & gtfs_path) const
inline const Calendar & Feed::get_calendar() const { return calendar; }
inline std::optional<CalendarItem> Feed::get_calendar(const Id & service_id) const
inline boost::optional<CalendarItem> Feed::get_calendar(const Id & service_id) const
{
const auto it = std::find_if(calendar.begin(), calendar.end(),
[&service_id](const CalendarItem & calendar_item) {
@ -2326,7 +2329,7 @@ inline std::optional<CalendarItem> Feed::get_calendar(const Id & service_id) con
});
if (it == calendar.end())
return std::nullopt;
return boost::none;
return *it;
}
@ -2507,7 +2510,7 @@ inline Result Feed::write_transfers(const std::string & gtfs_path) const
inline const Transfers & Feed::get_transfers() const { return transfers; }
inline std::optional<Transfer> Feed::get_transfer(const Id & from_stop_id,
inline boost::optional<Transfer> Feed::get_transfer(const Id & from_stop_id,
const Id & to_stop_id) const
{
const auto it = std::find_if(
@ -2516,7 +2519,7 @@ inline std::optional<Transfer> Feed::get_transfer(const Id & from_stop_id,
});
if (it == transfers.end())
return std::nullopt;
return boost::none;
return *it;
}
@ -2575,14 +2578,14 @@ inline Result Feed::write_levels(const std::string & gtfs_path) const
inline const Levels & Feed::get_levels() const { return levels; }
inline std::optional<Level> Feed::get_level(const Id & level_id) const
inline boost::optional<Level> Feed::get_level(const Id & level_id) const
{
const auto it = std::find_if(levels.begin(), levels.end(), [&level_id](const Level & level) {
return level.level_id == level_id;
});
if (it == levels.end())
return std::nullopt;
return boost::none;
return *it;
}
@ -2795,12 +2798,9 @@ inline void Feed::write_fare_attributes(std::ofstream & out) const
for (const auto & attribute : fare_attributes)
{
std::vector<std::string> fields{
wrap(attribute.fare_id), wrap(attribute.price), attribute.currency_type,
wrap(attribute.payment_method),
// Here we handle GTFS specification corner case: "The fact that this field can be left
// empty is an exception to the requirement that a Required field must not be empty.":
attribute.transfers == FareTransfers::Unlimited ? "" : wrap(attribute.transfers),
wrap(attribute.agency_id), wrap(attribute.transfer_duration)};
wrap(attribute.fare_id), wrap(attribute.price), attribute.currency_type,
wrap(attribute.payment_method), wrap(attribute.transfers), wrap(attribute.agency_id),
wrap(attribute.transfer_duration)};
write_joined(out, std::move(fields));
}
}

View file

@ -1,20 +0,0 @@
{
"signedContributors": [
{
"name": "nilsnolde",
"id": 25637358,
"comment_id": 1441674396,
"created_at": "2023-02-23T12:23:33Z",
"repoId": 250751634,
"pullRequestNo": 18
},
{
"name": "Osyotr",
"id": 8740768,
"comment_id": 2089322842,
"created_at": "2024-05-02T00:13:58Z",
"repoId": 250751634,
"pullRequestNo": 21
}
]
}

View file

@ -5,6 +5,6 @@ message(STATUS "CMAKE_CURRENT_BINARY_DIR=" ${CMAKE_CURRENT_BINARY_DIR})
foreach(TEST_SOURCE ${TESTS})
string(REPLACE ".cpp" "" TEST_TARGET "${TEST_SOURCE}")
add_executable(${TEST_TARGET} ${TEST_SOURCE})
target_compile_features(${TEST_TARGET} PRIVATE cxx_std_17)
target_compile_features(${TEST_TARGET} PRIVATE cxx_std_14)
add_test("${TEST_TARGET}" "${TEST_TARGET}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} --verbose)
endforeach()

View file

@ -1,4 +1,3 @@
fare_id,price,currency_type,payment_method,transfers,transfer_duration
p,1.25,USD,0,0,
a,5.25,USD,1,1,
x,20,USD,0,,60
a,5.25,USD,0,0,

View file

@ -230,10 +230,11 @@ TEST_CASE("Empty container before parsing")
Feed feed("data/non_existing_dir");
REQUIRE(feed.get_agencies().empty());
auto agency = feed.get_agency("agency_10");
CHECK(!agency);
const bool no_agency = agency == boost::none;
CHECK_EQ(no_agency, true);
}
TEST_CASE("Non existend directory")
TEST_CASE("Non existing directory")
{
Feed feed("data/non_existing_dir");
REQUIRE_EQ(feed.read_transfers(), ResultCode::ERROR_FILE_ABSENT);
@ -243,7 +244,8 @@ TEST_CASE("Non existend directory")
TEST_CASE("Transfers")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_transfers(), ResultCode::OK);
REQUIRE_EQ(feed.read_transfers().code, ResultCode::OK);
const auto & transfers = feed.get_transfers();
CHECK_EQ(transfers.size(), 4);
@ -253,7 +255,8 @@ TEST_CASE("Transfers")
CHECK_EQ(transfers[0].min_transfer_time, 70);
const auto & transfer = feed.get_transfer("314", "11");
REQUIRE(transfer);
const bool transfer_exists = transfer != boost::none;
REQUIRE_EQ(transfer_exists, true);
CHECK_EQ(transfer.value().transfer_type, TransferType::Timed);
CHECK_EQ(transfer.value().min_transfer_time, 0);
}
@ -261,12 +264,14 @@ TEST_CASE("Transfers")
TEST_CASE("Calendar")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_calendar(), ResultCode::OK);
REQUIRE_EQ(feed.read_calendar().code, ResultCode::OK);
const auto & calendar = feed.get_calendar();
REQUIRE_EQ(calendar.size(), 2);
const auto & calendar_record = feed.get_calendar("WE");
REQUIRE(calendar_record);
const bool calendar_exists = calendar_record != boost::none;
REQUIRE_EQ(calendar_exists, true);
CHECK_EQ(calendar_record->start_date, Date(2007, 01, 01));
CHECK_EQ(calendar_record->end_date, Date(2010, 12, 31));
@ -283,7 +288,7 @@ TEST_CASE("Calendar")
TEST_CASE("Calendar dates")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_calendar_dates(), ResultCode::OK);
REQUIRE_EQ(feed.read_calendar_dates().code, ResultCode::OK);
const auto & calendar_dates = feed.get_calendar_dates();
REQUIRE_EQ(calendar_dates.size(), 1);
@ -297,7 +302,7 @@ TEST_CASE("Calendar dates")
TEST_CASE("Read GTFS feed")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_feed(), ResultCode::OK);
REQUIRE_EQ(feed.read_feed().code, ResultCode::OK);
CHECK_EQ(feed.get_agencies().size(), 1);
CHECK_EQ(feed.get_routes().size(), 5);
@ -310,7 +315,7 @@ TEST_CASE("Read GTFS feed")
CHECK_EQ(feed.get_attributions().size(), 1);
CHECK_EQ(feed.get_calendar().size(), 2);
CHECK_EQ(feed.get_calendar_dates().size(), 1);
CHECK_EQ(feed.get_fare_attributes().size(), 3);
CHECK_EQ(feed.get_fare_attributes().size(), 2);
CHECK_EQ(feed.get_fare_rules().size(), 4);
CHECK(!feed.get_feed_info().feed_publisher_name.empty());
CHECK_EQ(feed.get_levels().size(), 3);
@ -321,7 +326,7 @@ TEST_CASE("Read GTFS feed")
TEST_CASE("Agency")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_agencies(), ResultCode::OK);
REQUIRE_EQ(feed.read_agencies().code, ResultCode::OK);
const auto & agencies = feed.get_agencies();
REQUIRE_EQ(agencies.size(), 1);
@ -332,7 +337,8 @@ TEST_CASE("Agency")
CHECK_EQ(agencies[0].agency_timezone, "America/Los_Angeles");
const auto agency = feed.get_agency("DTA");
CHECK(agency);
const bool agency_exists = agency != boost::none;
CHECK_EQ(agency_exists, true);
REQUIRE_EQ(feed.write_agencies("data/output_feed"), ResultCode::OK);
Feed feed_copy("data/output_feed");
@ -343,7 +349,7 @@ TEST_CASE("Agency")
TEST_CASE("Routes")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_routes(), ResultCode::OK);
REQUIRE_EQ(feed.read_routes().code, ResultCode::OK);
const auto & routes = feed.get_routes();
REQUIRE_EQ(routes.size(), 5);
@ -357,13 +363,14 @@ TEST_CASE("Routes")
CHECK(routes[0].route_desc.empty());
const auto & route = feed.get_route("AB");
CHECK(route);
const bool route_exists = route != boost::none;
CHECK_EQ(route_exists, true);
}
TEST_CASE("Trips")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_trips(), ResultCode::OK);
REQUIRE_EQ(feed.read_trips().code, ResultCode::OK);
const auto & trips = feed.get_trips();
REQUIRE_EQ(trips.size(), 11);
@ -377,14 +384,15 @@ TEST_CASE("Trips")
CHECK_EQ(trips[0].trip_id, "AB1");
const auto & trip = feed.get_trip("AB1");
REQUIRE(trip);
const bool trip_exists = trip != boost::none;
REQUIRE_EQ(trip_exists, true);
CHECK(trip.value().trip_short_name.empty());
}
TEST_CASE("Stops")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_stops(), ResultCode::OK);
REQUIRE_EQ(feed.read_stops().code, ResultCode::OK);
const auto & stops = feed.get_stops();
REQUIRE_EQ(stops.size(), 9);
@ -399,13 +407,14 @@ TEST_CASE("Stops")
CHECK(stops[0].zone_id.empty());
auto const & stop = feed.get_stop("FUR_CREEK_RES");
REQUIRE(stop);
const bool stop_exists = stop != boost::none;
REQUIRE_EQ(stop_exists, true);
}
TEST_CASE("StopTimes")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_stop_times(), ResultCode::OK);
REQUIRE_EQ(feed.read_stop_times().code, ResultCode::OK);
const auto & stop_times = feed.get_stop_times();
REQUIRE_EQ(stop_times.size(), 28);
@ -426,7 +435,7 @@ TEST_CASE("StopTimes")
TEST_CASE("Shapes")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_shapes(), ResultCode::OK);
REQUIRE_EQ(feed.read_shapes().code, ResultCode::OK);
const auto & shapes = feed.get_shapes();
REQUIRE_EQ(shapes.size(), 8);
@ -443,7 +452,7 @@ TEST_CASE("Shapes")
TEST_CASE("Calendar")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_calendar(), ResultCode::OK);
REQUIRE_EQ(feed.read_calendar().code, ResultCode::OK);
const auto & calendar = feed.get_calendar();
REQUIRE_EQ(calendar.size(), 2);
@ -454,13 +463,14 @@ TEST_CASE("Calendar")
CHECK_EQ(calendar[0].sunday, CalendarAvailability::Available);
const auto & calendar_for_service = feed.get_calendar("FULLW");
CHECK(calendar_for_service);
const bool calendar_exists = calendar_for_service != boost::none;
CHECK_EQ(calendar_exists, true);
}
TEST_CASE("Calendar dates")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_calendar_dates(), ResultCode::OK);
REQUIRE_EQ(feed.read_calendar_dates().code, ResultCode::OK);
const auto & calendar_dates = feed.get_calendar_dates();
REQUIRE_EQ(calendar_dates.size(), 1);
@ -475,7 +485,7 @@ TEST_CASE("Calendar dates")
TEST_CASE("Frequencies")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_frequencies(), ResultCode::OK);
REQUIRE_EQ(feed.read_frequencies().code, ResultCode::OK);
const auto & frequencies = feed.get_frequencies();
REQUIRE_EQ(frequencies.size(), 11);
@ -491,10 +501,10 @@ TEST_CASE("Frequencies")
TEST_CASE("Fare attributes")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_fare_attributes(), ResultCode::OK);
REQUIRE_EQ(feed.read_fare_attributes().code, ResultCode::OK);
const auto & attributes = feed.get_fare_attributes();
REQUIRE_EQ(attributes.size(), 3);
REQUIRE_EQ(attributes.size(), 2);
CHECK_EQ(attributes[0].fare_id, "p");
CHECK_EQ(attributes[0].price, 1.25);
CHECK_EQ(attributes[0].currency_type, "USD");
@ -502,34 +512,15 @@ TEST_CASE("Fare attributes")
CHECK_EQ(attributes[0].transfers, FareTransfers::No);
CHECK_EQ(attributes[0].transfer_duration, 0);
CHECK_EQ(attributes[1].fare_id, "a");
CHECK_EQ(attributes[1].price, 5.25);
CHECK_EQ(attributes[1].currency_type, "USD");
CHECK_EQ(attributes[1].payment_method, FarePayment::BeforeBoarding);
CHECK_EQ(attributes[1].transfers, FareTransfers::Once);
CHECK_EQ(attributes[1].transfer_duration, 0);
CHECK_EQ(attributes[2].fare_id, "x");
CHECK_EQ(attributes[2].price, 20);
CHECK_EQ(attributes[2].currency_type, "USD");
CHECK_EQ(attributes[2].payment_method, FarePayment::OnBoard);
CHECK_EQ(attributes[2].transfers, FareTransfers::Unlimited);
CHECK_EQ(attributes[2].transfer_duration, 60);
const auto & attributes_for_id = feed.get_fare_attributes("a");
REQUIRE_EQ(attributes_for_id.size(), 1);
CHECK_EQ(attributes_for_id[0].price, 5.25);
REQUIRE_EQ(feed.write_fare_attributes("data/output_feed"), ResultCode::OK);
Feed feed_copy("data/output_feed");
REQUIRE_EQ(feed_copy.read_fare_attributes(), ResultCode::OK);
CHECK_EQ(attributes, feed_copy.get_fare_attributes());
}
TEST_CASE("Fare rules")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_fare_rules(), ResultCode::OK);
REQUIRE_EQ(feed.read_fare_rules().code, ResultCode::OK);
const auto & fare_rules = feed.get_fare_rules();
REQUIRE_EQ(fare_rules.size(), 4);
@ -544,7 +535,7 @@ TEST_CASE("Fare rules")
TEST_CASE("Levels")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_levels(), ResultCode::OK);
REQUIRE_EQ(feed.read_levels().code, ResultCode::OK);
const auto & levels = feed.get_levels();
REQUIRE_EQ(levels.size(), 3);
@ -552,7 +543,8 @@ TEST_CASE("Levels")
CHECK_EQ(levels[0].level_index, -1.5);
const auto & level = feed.get_level("U321L2");
REQUIRE(level);
const bool level_exists = level != boost::none;
REQUIRE_EQ(level_exists, true);
CHECK_EQ(level.value().level_index, -2);
CHECK_EQ(level.value().level_name, "Vestibul2");
@ -561,7 +553,7 @@ TEST_CASE("Levels")
TEST_CASE("Pathways")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_pathways(), ResultCode::OK);
REQUIRE_EQ(feed.read_pathways().code, ResultCode::OK);
const auto & pathways = feed.get_pathways();
REQUIRE_EQ(pathways.size(), 3);
@ -582,7 +574,7 @@ TEST_CASE("Pathways")
TEST_CASE("Translations")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_translations(), ResultCode::OK);
REQUIRE_EQ(feed.read_translations().code, ResultCode::OK);
const auto & translations = feed.get_translations();
REQUIRE_EQ(translations.size(), 1);
@ -600,7 +592,7 @@ TEST_CASE("Translations")
TEST_CASE("Attributions")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_attributions(), ResultCode::OK);
REQUIRE_EQ(feed.read_attributions().code, ResultCode::OK);
const auto & attributions = feed.get_attributions();
REQUIRE_EQ(attributions.size(), 1);
@ -617,7 +609,7 @@ TEST_CASE("Attributions")
TEST_CASE("Feed info")
{
Feed feed("data/sample_feed");
REQUIRE_EQ(feed.read_feed_info(), ResultCode::OK);
REQUIRE_EQ(feed.read_feed_info().code, ResultCode::OK);
const auto & info = feed.get_feed_info();
@ -651,7 +643,7 @@ TEST_CASE("Agencies create & save")
feed_for_writing.add_agency(agency1);
feed_for_writing.add_agency(agency2);
REQUIRE_EQ(feed_for_writing.write_agencies("data/output_feed"), ResultCode::OK);
REQUIRE_EQ(feed_for_writing.write_agencies("data/output_feed").code, ResultCode::OK);
Feed feed_for_testing("data/output_feed");
REQUIRE_EQ(feed_for_testing.read_agencies(), ResultCode::OK);