Merge pull request #5358 from XiangRongLin/testable_prettytime
Make Localization.relativeTime testable
This commit is contained in:
commit
0264383ad2
|
@ -6,16 +6,26 @@ import android.content.Context;
|
|||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.multidex.MultiDexApplication;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
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.config.ACRAConfigurationException;
|
||||
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.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>
|
||||
* App.java is part of NewPipe.
|
||||
|
@ -93,9 +88,9 @@ public class App extends MultiDexApplication {
|
|||
SettingsActivity.initSettings(this);
|
||||
|
||||
NewPipe.init(getDownloader(),
|
||||
Localization.getPreferredLocalization(this),
|
||||
Localization.getPreferredContentCountry(this));
|
||||
Localization.init(getApplicationContext());
|
||||
Localization.getPreferredLocalization(this),
|
||||
Localization.getPreferredContentCountry(this));
|
||||
Localization.initPrettyTime(Localization.resolvePrettyTime(getApplicationContext()));
|
||||
|
||||
StateSaver.init(this);
|
||||
initNotificationChannels();
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
package org.schabi.newpipe;
|
||||
|
||||
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -41,7 +43,6 @@ import android.widget.AdapterView;
|
|||
import android.widget.ArrayAdapter;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||
|
@ -52,9 +53,10 @@ import androidx.drawerlayout.widget.DrawerLayout;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
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.DrawerHeaderBinding;
|
||||
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.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 {
|
||||
private static final String TAG = "MainActivity";
|
||||
public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release");
|
||||
|
@ -468,7 +464,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
protected void onResume() {
|
||||
assureCorrectAppLanguage(this);
|
||||
// Change the date format to match the selected language on resume
|
||||
Localization.init(getApplicationContext());
|
||||
Localization.initPrettyTime(Localization.resolvePrettyTime(getApplicationContext()));
|
||||
super.onResume();
|
||||
|
||||
// Close drawer on return, and don't show animation,
|
||||
|
|
|
@ -9,19 +9,10 @@ import android.icu.text.CompactDecimalFormat;
|
|||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.PluralsRes;
|
||||
import androidx.annotation.StringRes;
|
||||
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.RoundingMode;
|
||||
import java.text.NumberFormat;
|
||||
|
@ -33,6 +24,12 @@ import java.util.Arrays;
|
|||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
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() { }
|
||||
|
||||
public static void init(final Context context) {
|
||||
initPrettyTime(context);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String concatenateStrings(final String... strings) {
|
||||
return concatenateStrings(Arrays.asList(strings));
|
||||
|
@ -307,12 +300,16 @@ public final class Localization {
|
|||
// Pretty Time
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
private static void initPrettyTime(final Context context) {
|
||||
prettyTime = new PrettyTime(getAppLocale(context));
|
||||
public static void initPrettyTime(final PrettyTime time) {
|
||||
prettyTime = time;
|
||||
// Do not use decades as YouTube doesn't either.
|
||||
prettyTime.removeUnit(Decade.class);
|
||||
}
|
||||
|
||||
public static PrettyTime resolvePrettyTime(final Context context) {
|
||||
return new PrettyTime(getAppLocale(context));
|
||||
}
|
||||
|
||||
public static String relativeTime(final OffsetDateTime offsetDateTime) {
|
||||
return relativeTime(OffsetDateTimeKt.toCalendar(offsetDateTime));
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue