From 8fc69142c6c40906516e12d3bd94cd49add5bff6 Mon Sep 17 00:00:00 2001 From: Hank Grabowski Date: Fri, 17 Mar 2023 15:03:39 -0400 Subject: [PATCH] Add Friendica version processing --- lib/models/friendica_version.dart | 186 +++++++++++++++++++++++++ test/friendica_version_test.dart | 224 ++++++++++++++++++++++++++++++ 2 files changed, 410 insertions(+) create mode 100644 lib/models/friendica_version.dart create mode 100644 test/friendica_version_test.dart diff --git a/lib/models/friendica_version.dart b/lib/models/friendica_version.dart new file mode 100644 index 0000000..53ca1d5 --- /dev/null +++ b/lib/models/friendica_version.dart @@ -0,0 +1,186 @@ +//Unknown +final FriendicaVersion unknown = FriendicaVersion(DateTime(1970, 01)); + +class FriendicaVersion implements Comparable { + final DateTime releaseDate; + final String extra; + + FriendicaVersion(this.releaseDate, {this.extra = ''}); + + factory FriendicaVersion.fromMastodonVersionString(String? text) { + if (text == null) { + return unknown; + } + + final elements = text.split(RegExp('\\s+')); + final versionString = elements.last.substring(0, elements.last.length - 1); + return FriendicaVersion.fromVersionString(versionString); + } + + factory FriendicaVersion.fromVersionString(String? text) { + if (text == null) { + return unknown; + } + + final elements = text.trim().split('.'); + if (elements.length < 2) { + return unknown; + } + + final year = int.tryParse(elements[0]); + if (year == null) { + return unknown; + } + + if (year < 2018) { + return unknown; + } + + int? month = int.tryParse(elements[1]); + String extra = ''; + if (month == null) { + final secondaryFields = elements[1].split(RegExp('\\D+')); + month = int.tryParse(secondaryFields.first) ?? 1; + extra = secondaryFields.sublist(1).join('-'); + } + + return FriendicaVersion(DateTime(year, month), extra: extra); + } + + bool operator >(FriendicaVersion other) { + return compareTo(other) > 0; + } + + bool operator >=(FriendicaVersion other) { + return compareTo(other) >= 0; + } + + bool operator <(FriendicaVersion other) { + return compareTo(other) < 0; + } + + bool operator <=(FriendicaVersion other) { + return compareTo(other) <= 0; + } + + @override + int compareTo(FriendicaVersion other) { + if (releaseDate == other.releaseDate) { + final subVersion = int.tryParse(extra); + final otherSubVersion = int.tryParse(other.extra); + if (subVersion == null && otherSubVersion == null) { + return extra.compareTo(other.extra); + } + + if (subVersion == null && otherSubVersion != null) { + return -1; + } + + if (subVersion != null && otherSubVersion == null) { + return 1; + } + + return subVersion!.compareTo(otherSubVersion!); + } + return releaseDate.compareTo(other.releaseDate); + } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is FriendicaVersion && + runtimeType == other.runtimeType && + releaseDate == other.releaseDate && + extra == other.extra; + + @override + int get hashCode => releaseDate.hashCode ^ extra.hashCode; + + @override + String toString() { + return 'FriendicaVersion{releaseDate: $releaseDate, extra: $extra}'; + } +} + +// Known Versions +// 2018 Versions +final FriendicaVersion v2018_05 = FriendicaVersion(DateTime(2018, 05)); +final FriendicaVersion v2018_09 = FriendicaVersion(DateTime(2018, 09)); + +// 2019 Versions +final FriendicaVersion v2019_01 = FriendicaVersion(DateTime(2019, 01)); +final FriendicaVersion v2019_03 = FriendicaVersion(DateTime(2019, 03)); +final FriendicaVersion v2019_04 = FriendicaVersion(DateTime(2019, 04)); +final FriendicaVersion v2019_06 = FriendicaVersion(DateTime(2019, 06)); +final FriendicaVersion v2019_09 = FriendicaVersion(DateTime(2019, 09)); +final FriendicaVersion v2019_12 = FriendicaVersion(DateTime(2019, 12)); + +// 2020 Versions +final FriendicaVersion v2020_03 = FriendicaVersion(DateTime(2020, 03)); +final FriendicaVersion v2020_07 = FriendicaVersion(DateTime(2020, 07)); +final FriendicaVersion v2020_07_01 = FriendicaVersion( + DateTime(2020, 07), + extra: '1', +); +final FriendicaVersion v2020_09 = FriendicaVersion(DateTime(2020, 09)); +final FriendicaVersion v2020_09_01 = FriendicaVersion( + DateTime(2020, 09), + extra: '1', +); + +// 2021 Versions +final FriendicaVersion v2021_01 = FriendicaVersion(DateTime(2021, 01)); +final FriendicaVersion v2021_04 = FriendicaVersion(DateTime(2021, 04)); +final FriendicaVersion v2021_07 = FriendicaVersion(DateTime(2021, 07)); +final FriendicaVersion v2021_09 = FriendicaVersion(DateTime(2021, 09)); + +// 2022 Versions +final FriendicaVersion v2022_02 = FriendicaVersion(DateTime(2022, 02)); +final FriendicaVersion v2022_03 = FriendicaVersion(DateTime(2022, 03)); +final FriendicaVersion v2022_06 = FriendicaVersion(DateTime(2022, 06)); +final FriendicaVersion v2022_10 = FriendicaVersion(DateTime(2022, 10)); +final FriendicaVersion v2022_12 = FriendicaVersion(DateTime(2022, 12)); + +// 2023 Versions +final FriendicaVersion v2023_01 = FriendicaVersion(DateTime(2023, 01)); +final FriendicaVersion v2023_03 = FriendicaVersion(DateTime(2023, 03)); + +final knownFriendicaVersions = [ +// 2018 Versions + v2018_05, + v2018_05, + v2018_09, + +// 2019 Versions + v2019_01, + v2019_03, + v2019_04, + v2019_06, + v2019_09, + v2019_12, + +// 2020 Versions + v2020_03, + v2020_07_01, + v2020_09, + v2020_09_01, + +// 2021 Versions + v2021_01, + v2021_04, + v2021_07, + v2021_09, + +// 2022 Versions + v2022_02, + v2022_03, + v2022_06, + v2022_10, + v2022_12, + +// 2023 Versions + v2023_01, + v2023_03, +]; + +FriendicaVersion latestVersion() => knownFriendicaVersions.last; diff --git a/test/friendica_version_test.dart b/test/friendica_version_test.dart new file mode 100644 index 0000000..89e1c2e --- /dev/null +++ b/test/friendica_version_test.dart @@ -0,0 +1,224 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:relatica/models/friendica_version.dart'; + +void main() { + group('Comparison tests', () { + test('Unknown less than all', () { + for (final v in knownFriendicaVersions) { + expect(v, greaterThan(unknown)); + } + }); + + test('Newer correct', () { + expect(v2022_02, greaterThan(v2021_01)); + }); + + test('Older correct', () { + expect(v2022_02, lessThan(v2023_01)); + }); + + test('Older or equals', () { + expect(v2022_02, lessThanOrEqualTo(v2022_02)); + }); + + test('Newer or equals', () { + expect(v2022_02, greaterThanOrEqualTo(v2022_02)); + }); + + test('Equals with sub-version', () { + expect(v2020_07_01, greaterThanOrEqualTo(v2020_07_01)); + }); + + test('Newer sub-version', () { + expect(v2020_07_01, greaterThan(v2020_07)); + }); + + test('Older non sub-version', () { + expect(v2020_07, lessThan(v2020_07_01)); + }); + + test('Newer sub-version for both', () { + expect( + FriendicaVersion(DateTime(2020, 01), extra: '2'), + greaterThan(FriendicaVersion(DateTime(2020, 01), extra: '1')), + ); + }); + + test('Newer sub-version alpha for both', () { + expect( + FriendicaVersion(DateTime(2020, 01), extra: 'b'), + greaterThan(FriendicaVersion(DateTime(2020, 01), extra: 'a')), + ); + }); + }); + + group('Parsing tests', () { + test('Garbled text and null return "unknown"', () { + expect( + FriendicaVersion.fromVersionString(null), + unknown, + ); + + expect( + FriendicaVersion.fromVersionString('some version string'), + unknown, + ); + + expect( + FriendicaVersion.fromVersionString('3.5.1'), + unknown, + ); + }); + + test('Mastodon version from Mastodon Server', () { + final version = FriendicaVersion.fromMastodonVersionString('4.1.0'); + expect(version, equals(unknown)); + }); + + test('Mastodon version from Friendica Server', () { + final version = FriendicaVersion.fromMastodonVersionString( + '2.8.0 (compatible; Friendica 2023.01)'); + expect(version, equals(FriendicaVersion(DateTime(2023, 01)))); + }); + + test('Standard year/month form', () { + final version = FriendicaVersion.fromVersionString('2018.09'); + expect(version, equals(FriendicaVersion(DateTime(2018, 09)))); + }); + + test('Standard year/month form with additional version', () { + final version = FriendicaVersion.fromVersionString('2020.07-1'); + expect(version, equals(FriendicaVersion(DateTime(2020, 07), extra: '1'))); + }); + }); + + test('Test known version strings', () { + final versionStrings = [ + "2.1", + "2.2", + "2.21", + "2.3", + "2.32", + "2.33", + "2.34", + "2.35", + "2.36", + "2.37", + "2.38", + "2.39", + "2.3beta1", + "2.3beta2", + "3.0", + "3.01", + "3.1", + "3.2", + "3.3", + "3.3-RC", + "3.3.1", + "3.3.2", + "3.3.3", + "3.4", + "3.4.1", + "3.4.2", + "3.4.3", + "3.4.3-2", + "3.5", + "3.5.1", + "3.5.2", + "3.5.3", + "3.5.4", + "3.6", + "2018.05", + "2018.09", + "2019.01", + "2019.03", + "2019.04", + "2019.06", + "2019.09", + "2019.12", + "2020.03", + "2020.07", + "2020.07-1", + "2020.09", + "2020.09-1", + "2021.01", + "2021.04", + "2021.07", + "2021.09", + "2022.02", + "2022.03", + "2022.06", + "2022.10", + "2022.12", + "2023.01", + "2023.03", + ]; + + final versions = [ + unknown, // 2.1 + unknown, // 2.2 + unknown, // 2.21 + unknown, // 2.3 + unknown, // 2.32 + unknown, // 2.33 + unknown, // 2.34 + unknown, // 2.35 + unknown, // 2.36 + unknown, // 2.37 + unknown, // 2.38 + unknown, // 2.39 + unknown, // 2.3beta1 + unknown, // 2.3beta2 + unknown, // 3.0 + unknown, // 3.01 + unknown, // 3.1 + unknown, // 3.2 + unknown, // 3.3 + unknown, // 3.3-RC + unknown, // 3.3.1 + unknown, // 3.3.2 + unknown, // 3.3.3 + unknown, // 3.4 + unknown, // 3.4.1 + unknown, // 3.4.2 + unknown, // 3.4.3 + unknown, // 3.4.3-2 + unknown, // 3.5 + unknown, // 3.5.1 + unknown, // 3.5.2 + unknown, // 3.5.3 + unknown, // 3.5.4 + unknown, // 3.6 + v2018_05, // 2018.05 + v2018_09, // 2018.09 + v2019_01, // 2019.01 + v2019_03, // 2019.03 + v2019_04, // 2019.04 + v2019_06, // 2019.06 + v2019_09, // 2019.09 + v2019_12, // 2019.12 + v2020_03, // 2020.03 + v2020_07, // 2020.07 + v2020_07_01, // 2020.07-1 + v2020_09, // 2020.09 + v2020_09_01, // 2020.09-1 + v2021_01, // 2021.01 + v2021_04, // 2021.04 + v2021_07, // 2021.07 + v2021_09, // 2021.09 + v2022_02, // 2022.02 + v2022_03, // 2022.03 + v2022_06, // 2022.06 + v2022_10, // 2022.10 + v2022_12, // 2022.12 + v2023_01, // 2023.01 + v2023_03, // 2023.03 + ]; + + expect(versionStrings.length, equals(versions.length)); + for (var i = 0; i < versions.length; i++) { + final version = FriendicaVersion.fromVersionString(versionStrings[i]); + expect(version, equals(versions[i])); + } + }); +}