forked from upstream-mirrors/OpenTracks
Add support to choose the ISO 8601 date format as the default track name.
Note using the "yyyy-MM-dd HH:mm" format so it is readable for users. However, the colon, ":", is not a valid FAT32 filename character. So when saving to the SD card, the filename becomes "yyyy-MM-dd HH_mm".
This commit is contained in:
@@ -200,6 +200,18 @@ limitations under the License.
|
|||||||
<item>@string/sensor_type_value_zephyr</item>
|
<item>@string/sensor_type_value_zephyr</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="settings_recording_track_name_options">
|
||||||
|
<item>@string/settings_recording_track_name_date_local_option</item>
|
||||||
|
<item>@string/settings_recording_track_name_date_iso_8601_option</item>
|
||||||
|
<item>@string/settings_recording_track_name_number_option</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="settings_recording_track_name_values">
|
||||||
|
<item>@string/settings_recording_track_name_date_local_value</item>
|
||||||
|
<item>@string/settings_recording_track_name_date_iso_8601_value</item>
|
||||||
|
<item>@string/settings_recording_track_name_number_value</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="waypoint_types">
|
<string-array name="waypoint_types">
|
||||||
<item>@string/waypoint_type_atm</item>
|
<item>@string/waypoint_type_atm</item>
|
||||||
<item>@string/waypoint_type_bank</item>
|
<item>@string/waypoint_type_bank</item>
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ limitations under the License.
|
|||||||
<string name="sensor_type_value_polar">POLAR</string>
|
<string name="sensor_type_value_polar">POLAR</string>
|
||||||
<string name="sensor_type_value_srm_ant_bridge">SRM_ANT_BRIDGE</string>
|
<string name="sensor_type_value_srm_ant_bridge">SRM_ANT_BRIDGE</string>
|
||||||
<string name="sensor_type_value_zephyr">ZEPHYR</string>
|
<string name="sensor_type_value_zephyr">ZEPHYR</string>
|
||||||
|
<string name="settings_recording_track_name_date_iso_8601_value">DATE_ISO_8601</string>
|
||||||
|
<string name="settings_recording_track_name_date_local_value">DATE_LOCAL</string>
|
||||||
|
<string name="settings_recording_track_name_number_value">NUMBER</string>
|
||||||
<string name="track_action_end">com.google.android.apps.mytracks.END_CURRENT_TRACK</string>
|
<string name="track_action_end">com.google.android.apps.mytracks.END_CURRENT_TRACK</string>
|
||||||
<string name="track_action_save">android.intent.action.SAVE</string>
|
<string name="track_action_save">android.intent.action.SAVE</string>
|
||||||
<string name="track_action_start">com.google.android.apps.mytracks.START_NEW_TRACK</string>
|
<string name="track_action_start">com.google.android.apps.mytracks.START_NEW_TRACK</string>
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ limitations under the License.
|
|||||||
<string name="send_to_fusion_tables_key">sendToFusionTables</string>
|
<string name="send_to_fusion_tables_key">sendToFusionTables</string>
|
||||||
<string name="send_to_maps_key">sendToMaps</string>
|
<string name="send_to_maps_key">sendToMaps</string>
|
||||||
<string name="sensor_type_key">sensorType</string>
|
<string name="sensor_type_key">sensorType</string>
|
||||||
|
<string name="settings_recording_track_name_key">settingsRecordingTrackName</string>
|
||||||
<string name="share_url_only_key">shareUrlOnly</string>
|
<string name="share_url_only_key">shareUrlOnly</string>
|
||||||
<string name="split_frequency_key">splitFrequency</string>
|
<string name="split_frequency_key">splitFrequency</string>
|
||||||
<string name="timestamp_track_name_key">timestampTrackName</string>
|
|
||||||
<string name="track_color_mode_dynamic_speed_variation_key">trackColorModeDynamicVariation
|
<string name="track_color_mode_dynamic_speed_variation_key">trackColorModeDynamicVariation
|
||||||
</string>
|
</string>
|
||||||
<string name="track_color_mode_fixed_speed_medium_display_key">trackColorModeFixedMediumDisplay
|
<string name="track_color_mode_fixed_speed_medium_display_key">trackColorModeFixedMediumDisplay
|
||||||
|
|||||||
@@ -1677,28 +1677,6 @@ limitations under the License.
|
|||||||
Screenshot: settings_recording_top.png">
|
Screenshot: settings_recording_top.png">
|
||||||
Time/distance after which a new marker will be inserted.
|
Time/distance after which a new marker will be inserted.
|
||||||
</string>
|
</string>
|
||||||
<string name="settings_recording_name"
|
|
||||||
translation_description="In the 'Recording' settings, the checkbox on whether the track should
|
|
||||||
be named based on the track's start time or based on a number.
|
|
||||||
|
|
||||||
Character limit: ~23 (1 line)
|
|
||||||
Screenshot: settings_recording_bottom.png">
|
|
||||||
Use timestamp
|
|
||||||
</string>
|
|
||||||
<string name="settings_recording_name_summary_off"
|
|
||||||
translation_description="In the 'Recording' settings, the summary for the 'Use timestamp'
|
|
||||||
checkbox when it is unchecked explaining using a number as the default track name.
|
|
||||||
|
|
||||||
Screenshot: settings_recording_bottom_unchecked.png">
|
|
||||||
Use a number as the default track name.
|
|
||||||
</string>
|
|
||||||
<string name="settings_recording_name_summary_on"
|
|
||||||
translation_description="In the 'Recording' settings, the summary for the 'Use timestamp'
|
|
||||||
checkbox when it is checked explaining using the track's start time as the default track name.
|
|
||||||
|
|
||||||
Screenshot: settings_recording_bottom.png">
|
|
||||||
Use the track\'s start time as the default track name.
|
|
||||||
</string>
|
|
||||||
<string name="settings_recording_track_distance"
|
<string name="settings_recording_track_distance"
|
||||||
translation_description="In the 'Recording' settings, the dropdown option to configure the
|
translation_description="In the 'Recording' settings, the dropdown option to configure the
|
||||||
distance between two tracks.
|
distance between two tracks.
|
||||||
@@ -1716,6 +1694,39 @@ limitations under the License.
|
|||||||
Maximum distance between two recordings of your position. If two positions are further than
|
Maximum distance between two recordings of your position. If two positions are further than
|
||||||
this, the track will be split.
|
this, the track will be split.
|
||||||
</string>
|
</string>
|
||||||
|
<string name="settings_recording_track_name"
|
||||||
|
translation_description="In the 'Recording' settings, the title for the dropdown list to choose
|
||||||
|
the default track name.
|
||||||
|
|
||||||
|
Character limit: ~23 (1 line)">
|
||||||
|
Track name
|
||||||
|
</string>
|
||||||
|
<string name="settings_recording_track_name_date_iso_8601_option"
|
||||||
|
translation_description="In the 'Recording' settings, the option in the 'Track name' dropdown
|
||||||
|
list to use the track start time in ISO-8601 date format as the track name.
|
||||||
|
|
||||||
|
Character limit: ~21 (1 line)">
|
||||||
|
Date (ISO 8601)
|
||||||
|
</string>
|
||||||
|
<string name="settings_recording_track_name_date_local_option"
|
||||||
|
translation_description="In the 'Recording' settings, the option in the 'Track name' dropdown
|
||||||
|
list to use the track start time in local date format as the track name.
|
||||||
|
|
||||||
|
Character limit: ~21 (1 line)">
|
||||||
|
Date (local)
|
||||||
|
</string>
|
||||||
|
<string name="settings_recording_track_name_number_option"
|
||||||
|
translation_description="In the 'Recording' settings, the option in the 'Track name' dropdown
|
||||||
|
list to use a number as the track name.
|
||||||
|
|
||||||
|
Character limit: ~21 (1 line)">
|
||||||
|
Number
|
||||||
|
</string>
|
||||||
|
<string name="settings_recording_track_name_summary"
|
||||||
|
translation_description="In the 'Recording' settings, the summary for the 'Track name' dropdown
|
||||||
|
list explaining that it chooses the default track name format.">
|
||||||
|
Default track name
|
||||||
|
</string>
|
||||||
<string name="settings_recording_voice"
|
<string name="settings_recording_voice"
|
||||||
translation_description="In the 'Recording' settings, the dropdown option to configure the voice
|
translation_description="In the 'Recording' settings, the dropdown option to configure the voice
|
||||||
announcement frequency.
|
announcement frequency.
|
||||||
|
|||||||
@@ -137,12 +137,12 @@ limitations under the License.
|
|||||||
android:entryValues="@array/recording_auto_resume_timeout_values"
|
android:entryValues="@array/recording_auto_resume_timeout_values"
|
||||||
android:defaultValue="10" />
|
android:defaultValue="10" />
|
||||||
|
|
||||||
<CheckBoxPreference
|
<ListPreference android:key="@string/settings_recording_track_name_key"
|
||||||
android:key="@string/timestamp_track_name_key"
|
android:title="@string/settings_recording_track_name"
|
||||||
android:title="@string/settings_recording_name"
|
android:summary="@string/settings_recording_track_name_summary"
|
||||||
android:summaryOn="@string/settings_recording_name_summary_on"
|
android:entries="@array/settings_recording_track_name_options"
|
||||||
android:summaryOff="@string/settings_recording_name_summary_off"
|
android:entryValues="@array/settings_recording_track_name_values"
|
||||||
android:defaultValue="true" />
|
android:defaultValue="@string/settings_recording_track_name_date_local_value"/>
|
||||||
|
|
||||||
<com.google.android.apps.mytracks.AutoCompleteTextPreference
|
<com.google.android.apps.mytracks.AutoCompleteTextPreference
|
||||||
android:key="@string/default_activity_key"
|
android:key="@string/default_activity_key"
|
||||||
|
|||||||
+30
-16
@@ -18,43 +18,57 @@ package com.google.android.apps.mytracks.services;
|
|||||||
import com.google.android.apps.mytracks.Constants;
|
import com.google.android.apps.mytracks.Constants;
|
||||||
import com.google.android.apps.mytracks.util.StringUtils;
|
import com.google.android.apps.mytracks.util.StringUtils;
|
||||||
import com.google.android.maps.mytracks.R;
|
import com.google.android.maps.mytracks.R;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a default track name based on the current default track name policy.
|
* Creates a default track name based on the track name setting.
|
||||||
*
|
*
|
||||||
* @author Matthew Simmons
|
* @author Matthew Simmons
|
||||||
*/
|
*/
|
||||||
class DefaultTrackNameFactory {
|
public class DefaultTrackNameFactory {
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static final String ISO_8601_FORMAT = "yyyy-MM-dd HH:mm";
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
DefaultTrackNameFactory(Context context) {
|
public DefaultTrackNameFactory(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new track name.
|
* Gets the default track name.
|
||||||
*
|
*
|
||||||
* @param trackId The ID for the current track.
|
* @param trackId the track id
|
||||||
* @param startTime The start time, in milliseconds since the epoch, of the
|
* @param startTime the track start time
|
||||||
* current track.
|
|
||||||
* @return The new track name.
|
|
||||||
*/
|
*/
|
||||||
String newTrackName(long trackId, long startTime) {
|
public String getDefaultTrackName(long trackId, long startTime) {
|
||||||
if (useTimestampTrackName()) {
|
String trackNameSetting = getTrackNameSetting();
|
||||||
|
if (trackNameSetting.equals(
|
||||||
|
context.getString(R.string.settings_recording_track_name_date_local_value))) {
|
||||||
return StringUtils.formatDateTime(context, startTime);
|
return StringUtils.formatDateTime(context, startTime);
|
||||||
|
} else if (trackNameSetting.equals(
|
||||||
|
context.getString(R.string.settings_recording_track_name_date_iso_8601_value))) {
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat(ISO_8601_FORMAT);
|
||||||
|
return dateFormat.format(startTime);
|
||||||
} else {
|
} else {
|
||||||
return String.format(context.getString(R.string.track_name_format), trackId);
|
return String.format(context.getString(R.string.track_name_format), trackId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determines whether the preferences allow a timestamp-based track name */
|
/**
|
||||||
protected boolean useTimestampTrackName() {
|
* Gets the track name setting from the shared preferences.
|
||||||
SharedPreferences prefs = context.getSharedPreferences(
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
String getTrackNameSetting() {
|
||||||
|
SharedPreferences sharedPreferences = context.getSharedPreferences(
|
||||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
return prefs.getBoolean(
|
return sharedPreferences.getString(
|
||||||
context.getString(R.string.timestamp_track_name_key), true);
|
context.getString(R.string.settings_recording_track_name_key),
|
||||||
|
context.getString(R.string.settings_recording_track_name_date_local_value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -586,7 +586,7 @@ public class TrackRecordingService extends Service {
|
|||||||
Uri trackUri = providerUtils.insertTrack(track);
|
Uri trackUri = providerUtils.insertTrack(track);
|
||||||
recordingTrackId = Long.parseLong(trackUri.getLastPathSegment());
|
recordingTrackId = Long.parseLong(trackUri.getLastPathSegment());
|
||||||
track.setId(recordingTrackId);
|
track.setId(recordingTrackId);
|
||||||
track.setName(new DefaultTrackNameFactory(this).newTrackName(
|
track.setName(new DefaultTrackNameFactory(this).getDefaultTrackName(
|
||||||
recordingTrackId, startTime));
|
recordingTrackId, startTime));
|
||||||
track.setCategory(getDefaultActivityType(this));
|
track.setCategory(getDefaultActivityType(this));
|
||||||
isRecording = true;
|
isRecording = true;
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ import java.util.TimeZone;
|
|||||||
public class FileUtils {
|
public class FileUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum Fat32 path length. See
|
* The maximum FAT32 path length. See the FAT32 spec at
|
||||||
* http://www.scribd.com/doc/2187273/FAT32-File-System-Specification
|
* http://msdn.microsoft.com/en-us/windows/hardware/gg463080
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final int MAX_FAT32_PATH_LENGTH = 260;
|
static final int MAX_FAT32_PATH_LENGTH = 260;
|
||||||
@@ -148,7 +148,7 @@ public class FileUtils {
|
|||||||
for (int i = 0; i < name.length(); i++) {
|
for (int i = 0; i < name.length(); i++) {
|
||||||
int codePoint = name.codePointAt(i);
|
int codePoint = name.codePointAt(i);
|
||||||
char character = name.charAt(i);
|
char character = name.charAt(i);
|
||||||
if (Character.isLetterOrDigit(character) || codePoint > 127 || character == '-') {
|
if (Character.isLetterOrDigit(character) || codePoint > 127 || isSpecialFat32(character)) {
|
||||||
buffer.appendCodePoint(codePoint);
|
buffer.appendCodePoint(codePoint);
|
||||||
} else {
|
} else {
|
||||||
buffer.append("_");
|
buffer.append("_");
|
||||||
@@ -157,6 +157,42 @@ public class FileUtils {
|
|||||||
String result = buffer.toString();
|
String result = buffer.toString();
|
||||||
return result.replaceAll("_+", "_");
|
return result.replaceAll("_+", "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if it is a special FAT32 character.
|
||||||
|
*
|
||||||
|
* @param character the character
|
||||||
|
*/
|
||||||
|
private boolean isSpecialFat32(char character) {
|
||||||
|
switch (character) {
|
||||||
|
case '$':
|
||||||
|
case '%':
|
||||||
|
case '\'':
|
||||||
|
case '-':
|
||||||
|
case '_':
|
||||||
|
case '@':
|
||||||
|
case '~':
|
||||||
|
case '`':
|
||||||
|
case '!':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case '^':
|
||||||
|
case '#':
|
||||||
|
case '&':
|
||||||
|
case '+':
|
||||||
|
case ',':
|
||||||
|
case ';':
|
||||||
|
case '=':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case ' ':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Truncates the name if necessary so the filename path length (directory +
|
* Truncates the name if necessary so the filename path length (directory +
|
||||||
|
|||||||
+37
-31
@@ -16,49 +16,55 @@
|
|||||||
package com.google.android.apps.mytracks.services;
|
package com.google.android.apps.mytracks.services;
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.util.StringUtils;
|
import com.google.android.apps.mytracks.util.StringUtils;
|
||||||
|
import com.google.android.maps.mytracks.R;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link DefaultTrackNameFactory}
|
* Tests {@link DefaultTrackNameFactory}
|
||||||
*
|
*
|
||||||
* @author Matthew Simmons
|
* @author Matthew Simmons
|
||||||
*/
|
*/
|
||||||
public class DefaultTrackNameFactoryTest extends AndroidTestCase {
|
public class DefaultTrackNameFactoryTest extends AndroidTestCase {
|
||||||
/**
|
|
||||||
* A version of the factory which allows us to supply our own answer as to
|
|
||||||
* whether a timestamp-based track name should be used.
|
|
||||||
*/
|
|
||||||
private static class MockDefaultTrackNameFactory
|
|
||||||
extends DefaultTrackNameFactory {
|
|
||||||
private final boolean useTimestamp;
|
|
||||||
|
|
||||||
MockDefaultTrackNameFactory(Context context, boolean useTimestamp) {
|
private static final int TRACK_ID = 1;
|
||||||
super(context);
|
private static final long START_TIME = 1288213406000L;
|
||||||
this.useTimestamp = useTimestamp;
|
|
||||||
}
|
public void testDefaultTrackName_date_local() {
|
||||||
|
DefaultTrackNameFactory defaultTrackNameFactory = new DefaultTrackNameFactory(getContext()) {
|
||||||
@Override
|
@Override
|
||||||
protected boolean useTimestampTrackName() {
|
String getTrackNameSetting() {
|
||||||
return useTimestamp;
|
return getContext().getString(R.string.settings_recording_track_name_date_local_value);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
assertEquals(StringUtils.formatDateTime(getContext(), START_TIME),
|
||||||
|
defaultTrackNameFactory.getDefaultTrackName(TRACK_ID, START_TIME));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long TIMESTAMP = 1288213406000L;
|
|
||||||
|
|
||||||
public void testTimestampTrackName() {
|
public void testDefaultTrackName_date_iso_8601() {
|
||||||
DefaultTrackNameFactory factory =
|
DefaultTrackNameFactory defaultTrackNameFactory = new DefaultTrackNameFactory(getContext()) {
|
||||||
new MockDefaultTrackNameFactory(getContext(), true);
|
@Override
|
||||||
|
String getTrackNameSetting() {
|
||||||
|
return getContext().getString(R.string.settings_recording_track_name_date_iso_8601_value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
|
||||||
|
DefaultTrackNameFactory.ISO_8601_FORMAT);
|
||||||
|
assertEquals(simpleDateFormat.format(new Date(START_TIME)),
|
||||||
|
defaultTrackNameFactory.getDefaultTrackName(TRACK_ID, START_TIME));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDefaultTrackName_number() {
|
||||||
|
DefaultTrackNameFactory defaultTrackNameFactory = new DefaultTrackNameFactory(getContext()) {
|
||||||
|
@Override
|
||||||
|
String getTrackNameSetting() {
|
||||||
|
return getContext().getString(R.string.settings_recording_track_name_number_value);
|
||||||
|
}
|
||||||
|
};
|
||||||
assertEquals(
|
assertEquals(
|
||||||
StringUtils.formatDateTime(getContext(), TIMESTAMP), factory.newTrackName(1, TIMESTAMP));
|
"Track " + TRACK_ID, defaultTrackNameFactory.getDefaultTrackName(TRACK_ID, START_TIME));
|
||||||
}
|
|
||||||
|
|
||||||
public void testIncrementingTrackName() {
|
|
||||||
DefaultTrackNameFactory factory =
|
|
||||||
new MockDefaultTrackNameFactory(getContext(), false);
|
|
||||||
|
|
||||||
assertEquals("Track 1", factory.newTrackName(1, TIMESTAMP));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,13 +62,45 @@ public class FileUtilsTest extends TestCase {
|
|||||||
assertEquals(expectedName, dirName);
|
assertEquals(expectedName, dirName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests sanitize filename.
|
||||||
|
*/
|
||||||
public void testSanitizeFileName() {
|
public void testSanitizeFileName() {
|
||||||
String name = "Swim\10ming-^across: the/ pacific (ocean).您好-привет_";
|
String name = "Swim\10ming-^across:/the/ pacific (ocean).";
|
||||||
String expected = "Swim_ming-_across_the_pacific_ocean_您好-привет_";
|
String expected = "Swim_ming-^across_the_ pacific (ocean)_";
|
||||||
|
assertEquals(expected, fileUtils.sanitizeFileName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests characters in other languages, like Chinese and Russian, are allowed.
|
||||||
|
*/
|
||||||
|
public void testSanitizeFileName_i18n() {
|
||||||
|
String name = "您好-привет";
|
||||||
|
String expected = "您好-привет";
|
||||||
|
|
||||||
|
assertEquals(expected, fileUtils.sanitizeFileName(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests special FAT32 characters are allowed.
|
||||||
|
*/
|
||||||
|
public void testSanitizeFileName_special_characters() {
|
||||||
|
String name = "$%'-_@~`!(){}^#&+,;=[] ";
|
||||||
|
String expected = "$%'-_@~`!(){}^#&+,;=[] ";
|
||||||
|
|
||||||
assertEquals(expected, fileUtils.sanitizeFileName(name));
|
assertEquals(expected, fileUtils.sanitizeFileName(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing collapsing multiple underscores characters.
|
||||||
|
*/
|
||||||
|
public void testSanitizeFileName_collapse() {
|
||||||
|
String name = "hello//there";
|
||||||
|
String expected = "hello_there";
|
||||||
|
|
||||||
|
assertEquals(expected, fileUtils.sanitizeFileName(name));
|
||||||
|
}
|
||||||
|
|
||||||
public void testTruncateFileName() {
|
public void testTruncateFileName() {
|
||||||
File directory = new File("/dir1/dir2/");
|
File directory = new File("/dir1/dir2/");
|
||||||
String suffix = ".gpx";
|
String suffix = ".gpx";
|
||||||
|
|||||||
Reference in New Issue
Block a user