Skip to content

Commit 4e4a5bc

Browse files
authored
#1756 generate 3-letter airport codes (#1763)
A.k.a. IATA code (passenger-friendly 3-letter code). This commit adds 1. enum `AirportCodeType (IATA | ICAO)` 2. method `aviation.airport(IATA)` -> 3-letter code 3. method `aviation.airport(ICAO)` -> 4-letter code
1 parent 6543aa4 commit 4e4a5bc

4 files changed

Lines changed: 215 additions & 22 deletions

File tree

src/main/java/net/datafaker/providers/base/Aviation.java

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import java.util.List;
44

5+
import static net.datafaker.providers.base.AviationCodeType.IATA;
6+
import static net.datafaker.providers.base.AviationCodeType.ICAO;
7+
58
/**
69
* Generates aviation related strings.
710
*
@@ -57,12 +60,27 @@ public String civilHelicopter() {
5760

5861
/**
5962
* Returns an airport ICAO code.
60-
* See also: <a href="https://en.wikipedia.org/wiki/List_of_airports_by_ICAO_code:_A">https://en.wikipedia.org/wiki/List_of_airports_by_ICAO_code:_A</a>
63+
* <p>
64+
* Seems that this method can return some local airport codes in addition to official ICAO code.
65+
* For example, it returns "CNT3" code for Ogoki Post Airport, but its official ICAO code is "CYKP".
66+
* </p>
67+
* @see <a href="https://en.wikipedia.org/wiki/List_of_airports_by_ICAO_code:_A">https://en.wikipedia.org/wiki/List_of_airports_by_ICAO_code:_A</a>
6168
*/
6269
public String airport() {
6370
return resolve("aviation.airport");
6471
}
6572

73+
/**
74+
* Returns either 3-letter IATA code or 4-letter ICAO code of a random airport
75+
* @see AviationCodeType
76+
*/
77+
public String airport(AviationCodeType codeType) {
78+
return switch (codeType) {
79+
case IATA -> resolve("aviation.airport_iata");
80+
case ICAO -> resolve("aviation.airport_icao");
81+
};
82+
}
83+
6684
/**
6785
* @return an airport name. Source: <a href="http://www.flugzeuginfo.net/table_airportcodes_country-location_en.php">http://www.flugzeuginfo.net/table_airportcodes_country-location_en.php</a>
6886
*/
@@ -104,17 +122,27 @@ public String engineType() {
104122
}
105123

106124
/**
107-
* Returns a flight number (IATA or ICAO format).
108-
*
109-
* @return A random flight number with IATA or ICAO format in a String.
125+
* @deprecated use {@link #flight(AviationCodeType)} instead
110126
*/
127+
@Deprecated
111128
public String flight(String type) {
112-
String airline;
113129
if ("ICAO".equalsIgnoreCase(type)) {
114-
airline = resolve("aviation.ICAO_airline");
130+
return flight(ICAO);
115131
} else {
116-
airline = resolve("aviation.IATA_airline");
132+
return flight(IATA);
117133
}
134+
}
135+
136+
/**
137+
* Returns a flight number (IATA or ICAO format).
138+
*
139+
* @return A random flight number with IATA or ICAO format in a String.
140+
*/
141+
public String flight(AviationCodeType type) {
142+
String airline = switch (type) {
143+
case ICAO -> resolve("aviation.ICAO_airline");
144+
case IATA -> resolve("aviation.IATA_airline");
145+
};
118146
int number = faker.number().numberBetween(0, 9999);
119147
return airline + number;
120148
}
@@ -125,7 +153,7 @@ public String flight(String type) {
125153
* @return A random flight number with IATA format in a String.
126154
*/
127155
public String flight() {
128-
return flight("IATA");
156+
return flight(IATA);
129157
}
130158

131159
/**
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.datafaker.providers.base;
2+
3+
public enum AviationCodeType {
4+
/**
5+
* 3-letter passenger-facing code, for example:
6+
* <ul>
7+
* <li>TLL - Lennart Meri Tallinn Airport</li>
8+
* <li>VNO - Vilnius Airport</li>
9+
* <li>JFK - John F. Kennedy International Airport (New York)</li>
10+
* </ul>
11+
*/
12+
IATA,
13+
14+
/**
15+
* 4-letter operational code, for example:
16+
* <ul>
17+
* <li>EETN - Lennart Meri Tallinn Airport</li>
18+
* <li>EYVI - Vilnius Airport</li>
19+
* <li>KJFK - John F. Kennedy International Airport (New York)</li>
20+
* </ul>
21+
*/
22+
ICAO
23+
}

src/main/resources/en/aviation.yml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6351,6 +6351,108 @@ en:
63516351
- "ZYTN"
63526352
- "ZYTX"
63536353
- "ZYYJ"
6354+
airport_iata:
6355+
- "ATL"
6356+
- "DXB"
6357+
- "HND"
6358+
- "DFW"
6359+
- "PVG"
6360+
- "LHR"
6361+
- "IST"
6362+
- "CAN"
6363+
- "DEN"
6364+
- "ORD"
6365+
- "DEL"
6366+
- "ICN"
6367+
- "LAX"
6368+
- "CDG"
6369+
- "PEK"
6370+
- "SIN"
6371+
- "AMS"
6372+
- "MAD"
6373+
- "SZX"
6374+
- "KUL"
6375+
- "FRA"
6376+
- "JFK"
6377+
- "BKK"
6378+
- "HKG"
6379+
- "MCO"
6380+
- "BCN"
6381+
- "TFU"
6382+
- "CGK"
6383+
- "BOM"
6384+
- "MIA"
6385+
- "SFO"
6386+
- "DOH"
6387+
- "LAS"
6388+
- "CLT"
6389+
- "PKX"
6390+
- "JED"
6391+
- "SEA"
6392+
- "MNL"
6393+
- "PHX"
6394+
- "FCO"
6395+
- "HGH"
6396+
- "SHA"
6397+
- "CKG"
6398+
- "KMG"
6399+
- "XIY"
6400+
- "SAW"
6401+
- "IAH"
6402+
- "TPE"
6403+
- "GRU"
6404+
- "EWR"
6405+
airport_icao:
6406+
- "KATL"
6407+
- "OMDB"
6408+
- "RJTT"
6409+
- "KDFW"
6410+
- "ZSPD"
6411+
- "EGLL"
6412+
- "LTFM"
6413+
- "ZGGG"
6414+
- "KDEN"
6415+
- "KORD"
6416+
- "VIDP"
6417+
- "RKSI"
6418+
- "KLAX"
6419+
- "LFPG"
6420+
- "ZBAA"
6421+
- "WSSS"
6422+
- "EHAM"
6423+
- "LEMD"
6424+
- "ZGSZ"
6425+
- "WMKK"
6426+
- "EDDF"
6427+
- "KJFK"
6428+
- "VTBS"
6429+
- "VHHH"
6430+
- "KMCO"
6431+
- "LEBL"
6432+
- "ZUTF"
6433+
- "WIII"
6434+
- "VABB"
6435+
- "KMIA"
6436+
- "KSFO"
6437+
- "OTHH"
6438+
- "KLAS"
6439+
- "KCLT"
6440+
- "ZBAD"
6441+
- "OEJN"
6442+
- "KSEA"
6443+
- "RPLL"
6444+
- "KPHX"
6445+
- "LIRF"
6446+
- "ZSHC"
6447+
- "ZSSS"
6448+
- "ZUCK"
6449+
- "ZPPP"
6450+
- "ZLXY"
6451+
- "LTFJ"
6452+
- "KIAH"
6453+
- "RCTP"
6454+
- "SBGR"
6455+
- "KEWR"
63546456
airport_name:
63556457
- "108 Mile"
63566458
- "A Coruna Airport"

src/test/java/net/datafaker/providers/base/AviationTest.java

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,54 @@
22

33
import org.junit.jupiter.api.Test;
44

5-
import static org.assertj.core.api.Assertions.assertThat;
6-
7-
import java.util.List;
85
import java.util.Collection;
6+
import java.util.List;
97
import java.util.regex.Pattern;
108

9+
import static net.datafaker.providers.base.AviationCodeType.IATA;
10+
import static net.datafaker.providers.base.AviationCodeType.ICAO;
11+
import static org.assertj.core.api.Assertions.assertThat;
12+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
13+
1114
class AviationTest extends BaseFakerTest {
15+
private static final Pattern FLIGHT_IATA_CODE = Pattern.compile("[A-Z0-9]{2}\\d{1,4}");
16+
private static final Pattern FLIGHT_ICAO_CODE = Pattern.compile("[A-Z]{3}[0-9]+");
17+
private static final String AIRPORT_IATA_CODE = "[A-Z]{3}";
18+
private static final String AIRPORT_ICAO_CODE = "[A-Z]{4}";
1219

1320
private final Aviation aviation = faker.aviation();
1421

1522
@Test
23+
@SuppressWarnings("deprecation")
1624
void flight_ICAO() {
17-
Pattern regex = Pattern.compile("[A-Z]{3}[0-9]+");
18-
assertThat(aviation.flight("ICAO")).matches(regex);
19-
assertThat(aviation.flight("icao")).matches(regex);
20-
assertThat(aviation.flight("Icao")).matches(regex);
21-
assertThat(aviation.flight("IcaO")).matches(regex);
25+
assertThat(aviation.flight(ICAO)).matches(FLIGHT_ICAO_CODE);
26+
assertThat(aviation.flight("ICAO")).matches(FLIGHT_ICAO_CODE);
27+
assertThat(aviation.flight("icao")).matches(FLIGHT_ICAO_CODE);
28+
assertThat(aviation.flight("Icao")).matches(FLIGHT_ICAO_CODE);
29+
assertThat(aviation.flight("IcaO")).matches(FLIGHT_ICAO_CODE);
2230
}
2331

2432
@Test
33+
@SuppressWarnings({"deprecation", "DataFlowIssue"})
2534
void flight_IATA() {
26-
Pattern regex = Pattern.compile("[A-Z0-9]{2}\\d{1,4}");
27-
assertThat(aviation.flight("IATA")).matches(regex);
28-
assertThat(aviation.flight("iata")).matches(regex);
29-
assertThat(aviation.flight("test")).matches(regex);
30-
assertThat(aviation.flight(null)).matches(regex);
35+
assertThat(aviation.flight(IATA)).matches(FLIGHT_IATA_CODE);
36+
assertThat(aviation.flight("IATA")).matches(FLIGHT_IATA_CODE);
37+
assertThat(aviation.flight("iata")).matches(FLIGHT_IATA_CODE);
38+
assertThat(aviation.flight("test")).matches(FLIGHT_IATA_CODE);
39+
assertThat(aviation.flight((String) null)).matches(FLIGHT_IATA_CODE);
40+
}
41+
42+
@Test
43+
@SuppressWarnings("DataFlowIssue")
44+
void flight_nullCodeNotAllowed() {
45+
assertThatThrownBy(() -> aviation.flight((AviationCodeType) null))
46+
.isInstanceOf(NullPointerException.class);
3147
}
3248

3349
@Test
3450
void flight_default() {
35-
assertThat(aviation.flight()).matches("[A-Z0-9]{2}\\d{1,4}");
51+
String flight = aviation.flight();
52+
assertThat(flight).matches(FLIGHT_IATA_CODE);
3653
}
3754

3855
@Test
@@ -45,9 +62,32 @@ void gate() {
4562
assertThat(aviation.gate()).isNotEmpty();
4663
}
4764

65+
@Test
66+
void airportCode() {
67+
assertThat(aviation.airport())
68+
.as("Looks like ICAO 4-letter code, but sometimes is non-official local code containing digits")
69+
.hasSize(4).matches("[A-Z0-9]{4}");
70+
}
71+
72+
@Test
73+
void airportICAOCode() {
74+
assertThat(aviation.airport(ICAO))
75+
.as("ICAO is 4-letter code consisting of Latin letters")
76+
.hasSize(4).matches(AIRPORT_ICAO_CODE);
77+
}
78+
79+
@Test
80+
void airportIATACode() {
81+
assertThat(aviation.airport(IATA))
82+
.as("IATA is 3-letter code consisting of Latin letters")
83+
.hasSize(3).matches(AIRPORT_IATA_CODE);
84+
}
85+
4886
@Override
4987
protected Collection<TestSpec> providerListTest() {
5088
return List.of(TestSpec.of(aviation::airport, "aviation.airport", "\\w{4}"),
89+
TestSpec.of(() -> aviation.airport(IATA), "aviation.airport_iata", AIRPORT_IATA_CODE),
90+
TestSpec.of(() -> aviation.airport(ICAO), "aviation.airport_icao", AIRPORT_ICAO_CODE),
5191
TestSpec.of(aviation::airportName, "aviation.airport_name"),
5292
TestSpec.of(aviation::airplane, "aviation.aircraft.airplane"),
5393
TestSpec.of(aviation::warplane, "aviation.aircraft.warplane"),

0 commit comments

Comments
 (0)