1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-11-04 17:16:24 +00:00

Merge pull request #5358 from XiangRongLin/testable_prettytime

Make Localization.relativeTime testable
This commit is contained in:
Robin 2021-01-13 22:44:11 +01:00 committed by GitHub
commit 0264383ad2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 74 additions and 46 deletions

View File

@ -6,16 +6,26 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.multidex.MultiDexApplication; import androidx.multidex.MultiDexApplication;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache; import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.exceptions.CompositeException;
import io.reactivex.rxjava3.exceptions.MissingBackpressureException;
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
import io.reactivex.rxjava3.exceptions.UndeliverableException;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.acra.ACRA; import org.acra.ACRA;
import org.acra.config.ACRAConfigurationException; import org.acra.config.ACRAConfigurationException;
import org.acra.config.CoreConfiguration; import org.acra.config.CoreConfiguration;
@ -31,21 +41,6 @@ import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver; import org.schabi.newpipe.util.StateSaver;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.exceptions.CompositeException;
import io.reactivex.rxjava3.exceptions.MissingBackpressureException;
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
import io.reactivex.rxjava3.exceptions.UndeliverableException;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
/* /*
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org> * Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
* App.java is part of NewPipe. * App.java is part of NewPipe.
@ -95,7 +90,7 @@ public class App extends MultiDexApplication {
NewPipe.init(getDownloader(), NewPipe.init(getDownloader(),
Localization.getPreferredLocalization(this), Localization.getPreferredLocalization(this),
Localization.getPreferredContentCountry(this)); Localization.getPreferredContentCountry(this));
Localization.init(getApplicationContext()); Localization.initPrettyTime(Localization.resolvePrettyTime(getApplicationContext()));
StateSaver.init(this); StateSaver.init(this);
initNotificationChannels(); initNotificationChannels();

View File

@ -20,6 +20,8 @@
package org.schabi.newpipe; package org.schabi.newpipe;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -41,7 +43,6 @@ import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.Spinner; import android.widget.Spinner;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
@ -52,9 +53,10 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetBehavior;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.schabi.newpipe.databinding.ActivityMainBinding; import org.schabi.newpipe.databinding.ActivityMainBinding;
import org.schabi.newpipe.databinding.DrawerHeaderBinding; import org.schabi.newpipe.databinding.DrawerHeaderBinding;
import org.schabi.newpipe.databinding.DrawerLayoutBinding; import org.schabi.newpipe.databinding.DrawerLayoutBinding;
@ -87,12 +89,6 @@ import org.schabi.newpipe.util.TLSSocketFactoryCompat;
import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.views.FocusOverlayView; import org.schabi.newpipe.views.FocusOverlayView;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity"; private static final String TAG = "MainActivity";
public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release"); public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release");
@ -468,7 +464,7 @@ public class MainActivity extends AppCompatActivity {
protected void onResume() { protected void onResume() {
assureCorrectAppLanguage(this); assureCorrectAppLanguage(this);
// Change the date format to match the selected language on resume // Change the date format to match the selected language on resume
Localization.init(getApplicationContext()); Localization.initPrettyTime(Localization.resolvePrettyTime(getApplicationContext()));
super.onResume(); super.onResume();
// Close drawer on return, and don't show animation, // Close drawer on return, and don't show animation,

View File

@ -9,19 +9,10 @@ import android.icu.text.CompactDecimalFormat;
import android.os.Build; import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.PluralsRes; import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import org.ocpsoft.prettytime.PrettyTime;
import org.ocpsoft.prettytime.units.Decade;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.ktx.OffsetDateTimeKt;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.text.NumberFormat; import java.text.NumberFormat;
@ -33,6 +24,12 @@ import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.ocpsoft.prettytime.PrettyTime;
import org.ocpsoft.prettytime.units.Decade;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.ktx.OffsetDateTimeKt;
/* /*
@ -62,10 +59,6 @@ public final class Localization {
private Localization() { } private Localization() { }
public static void init(final Context context) {
initPrettyTime(context);
}
@NonNull @NonNull
public static String concatenateStrings(final String... strings) { public static String concatenateStrings(final String... strings) {
return concatenateStrings(Arrays.asList(strings)); return concatenateStrings(Arrays.asList(strings));
@ -307,12 +300,16 @@ public final class Localization {
// Pretty Time // Pretty Time
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
private static void initPrettyTime(final Context context) { public static void initPrettyTime(final PrettyTime time) {
prettyTime = new PrettyTime(getAppLocale(context)); prettyTime = time;
// Do not use decades as YouTube doesn't either. // Do not use decades as YouTube doesn't either.
prettyTime.removeUnit(Decade.class); prettyTime.removeUnit(Decade.class);
} }
public static PrettyTime resolvePrettyTime(final Context context) {
return new PrettyTime(getAppLocale(context));
}
public static String relativeTime(final OffsetDateTime offsetDateTime) { public static String relativeTime(final OffsetDateTime offsetDateTime) {
return relativeTime(OffsetDateTimeKt.toCalendar(offsetDateTime)); return relativeTime(OffsetDateTimeKt.toCalendar(offsetDateTime));
} }

View File

@ -0,0 +1,40 @@
package org.schabi.newpipe.util
import org.junit.Assert.assertEquals
import org.junit.Test
import org.ocpsoft.prettytime.PrettyTime
import java.text.SimpleDateFormat
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.util.GregorianCalendar
import java.util.Locale
class LocalizationTest {
@Test
fun `After initializing pretty time relativeTime() with a Calendar must work`() {
val reference = SimpleDateFormat("yyyy/MM/dd").parse("2021/1/1")
Localization.initPrettyTime(PrettyTime(reference, Locale.ENGLISH))
val actual = Localization.relativeTime(GregorianCalendar(2021, 1, 6))
// yes this assertion is true, even if it should be 5 days, it works as it is. Future research required.
assertEquals("1 month from now", actual)
}
@Test(expected = NullPointerException::class)
fun `relativeTime() must fail without initializing pretty time`() {
Localization.relativeTime(GregorianCalendar(2021, 1, 6))
}
@Test
fun `relativeTime() with a OffsetDateTime must work`() {
val reference = SimpleDateFormat("yyyy/MM/dd").parse("2021/1/1")
Localization.initPrettyTime(PrettyTime(reference, Locale.ENGLISH))
val offset = OffsetDateTime.of(2021, 1, 6, 0, 0, 0, 0, ZoneOffset.UTC)
val actual = Localization.relativeTime(offset)
assertEquals("5 days from now", actual)
}
}