mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 17:43:06 +02:00
My Tracks 2.0.1. Add support for Google location settings.
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="src" path=".apt_generated">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/MyTracks"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,7 @@
|
||||
<factorypath>
|
||||
<factorypathentry kind="WKSPJAR" id="/MyTracksTest/libs/AndroidMockGenerator.jar" enabled="true" runInBatchMode="false"/>
|
||||
<factorypathentry kind="VARJAR" id="ANDROID_SDK/platforms/android-15/android.jar" enabled="true" runInBatchMode="false"/>
|
||||
<factorypathentry kind="VARJAR" id="ANDROID_SDK/add-ons/addon-google_apis-google_inc_-15/libs/maps.jar" enabled="true" runInBatchMode="false"/>
|
||||
<factorypathentry kind="WKSPJAR" id="/MyTracksLib/bin/mytrackslib.jar" enabled="true" runInBatchMode="false"/>
|
||||
<factorypathentry kind="VARJAR" id="MYTRACKS_BIN/classes" enabled="true" runInBatchMode="false"/>
|
||||
</factorypath>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>MyTracksTest</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>MyTracks</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,7 @@
|
||||
#Tue Oct 25 14:08:44 PDT 2011
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.apt.aptEnabled=true
|
||||
org.eclipse.jdt.apt.genSrcDir=.apt_generated
|
||||
org.eclipse.jdt.apt.processorOptions/bin_dir=%PROJECT.DIR%/bin/classes
|
||||
org.eclipse.jdt.apt.processorOptions/logfile=%PROJECT.DIR%/AnnotationProcessor.log
|
||||
org.eclipse.jdt.apt.reconcileEnabled=false
|
||||
@@ -0,0 +1,358 @@
|
||||
#Fri Oct 21 20:06:28 BRST 2011
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.processAnnotations=enabled
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=48
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=48
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=48
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=80
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=true
|
||||
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=100
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=2
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=false
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
@@ -0,0 +1,61 @@
|
||||
#Thu Jul 21 03:06:24 BRT 2011
|
||||
eclipse.preferences.version=1
|
||||
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
|
||||
formatter_profile=_MyTracks
|
||||
formatter_settings_version=12
|
||||
org.eclipse.jdt.ui.ignorelowercasenames=true
|
||||
org.eclipse.jdt.ui.importorder=com;android;java;javax;org;
|
||||
org.eclipse.jdt.ui.ondemandthreshold=99
|
||||
org.eclipse.jdt.ui.staticondemandthreshold=99
|
||||
sp_cleanup.add_default_serial_version_id=true
|
||||
sp_cleanup.add_generated_serial_version_id=false
|
||||
sp_cleanup.add_missing_annotations=true
|
||||
sp_cleanup.add_missing_deprecated_annotations=true
|
||||
sp_cleanup.add_missing_methods=false
|
||||
sp_cleanup.add_missing_nls_tags=false
|
||||
sp_cleanup.add_missing_override_annotations=true
|
||||
sp_cleanup.add_missing_override_annotations_interface_methods=true
|
||||
sp_cleanup.add_serial_version_id=false
|
||||
sp_cleanup.always_use_blocks=true
|
||||
sp_cleanup.always_use_parentheses_in_expressions=false
|
||||
sp_cleanup.always_use_this_for_non_static_field_access=false
|
||||
sp_cleanup.always_use_this_for_non_static_method_access=false
|
||||
sp_cleanup.convert_to_enhanced_for_loop=false
|
||||
sp_cleanup.correct_indentation=false
|
||||
sp_cleanup.format_source_code=false
|
||||
sp_cleanup.format_source_code_changes_only=false
|
||||
sp_cleanup.make_local_variable_final=false
|
||||
sp_cleanup.make_parameters_final=false
|
||||
sp_cleanup.make_private_fields_final=true
|
||||
sp_cleanup.make_type_abstract_if_missing_method=false
|
||||
sp_cleanup.make_variable_declarations_final=true
|
||||
sp_cleanup.never_use_blocks=false
|
||||
sp_cleanup.never_use_parentheses_in_expressions=true
|
||||
sp_cleanup.on_save_use_additional_actions=false
|
||||
sp_cleanup.organize_imports=true
|
||||
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
|
||||
sp_cleanup.remove_private_constructors=true
|
||||
sp_cleanup.remove_trailing_whitespaces=false
|
||||
sp_cleanup.remove_trailing_whitespaces_all=true
|
||||
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
|
||||
sp_cleanup.remove_unnecessary_casts=true
|
||||
sp_cleanup.remove_unnecessary_nls_tags=false
|
||||
sp_cleanup.remove_unused_imports=false
|
||||
sp_cleanup.remove_unused_local_variables=false
|
||||
sp_cleanup.remove_unused_private_fields=true
|
||||
sp_cleanup.remove_unused_private_members=false
|
||||
sp_cleanup.remove_unused_private_methods=true
|
||||
sp_cleanup.remove_unused_private_types=true
|
||||
sp_cleanup.sort_members=false
|
||||
sp_cleanup.sort_members_all=false
|
||||
sp_cleanup.use_blocks=false
|
||||
sp_cleanup.use_blocks_only_for_return_and_throw=false
|
||||
sp_cleanup.use_parentheses_in_expressions=false
|
||||
sp_cleanup.use_this_for_non_static_field_access=false
|
||||
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
|
||||
sp_cleanup.use_this_for_non_static_method_access=false
|
||||
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2012 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.google.android.maps.mytracks.test"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<instrumentation
|
||||
android:name="android.test.InstrumentationTestRunner"
|
||||
android:targetPackage="com.google.android.maps.mytracks" />
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="7"
|
||||
android:targetSdkVersion="15" />
|
||||
|
||||
<application
|
||||
android:icon="@android:drawable/sym_def_app_icon"
|
||||
android:label="My Tracks Tests" >
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="com.android.ide.eclipse.adt.junit.launchConfigurationType">
|
||||
<stringAttribute key="com.android.ide.eclipse.adt.commandline" value=""/>
|
||||
<intAttribute key="com.android.ide.eclipse.adt.delay" value="0"/>
|
||||
<stringAttribute key="com.android.ide.eclipse.adt.instrumentation" value="android.test.InstrumentationTestRunner"/>
|
||||
<booleanAttribute key="com.android.ide.eclipse.adt.nobootanim" value="true"/>
|
||||
<intAttribute key="com.android.ide.eclipse.adt.speed" value="0"/>
|
||||
<booleanAttribute key="com.android.ide.eclipse.adt.target" value="true"/>
|
||||
<booleanAttribute key="com.android.ide.eclipse.adt.wipedata" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/MyTracksTests"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=MyTracksTests"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="MyTracksTests"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value=""/>
|
||||
</launchConfiguration>
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<lint>
|
||||
</lint>
|
||||
@@ -0,0 +1,13 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Indicates whether an apk should be generated for each density.
|
||||
split.density=false
|
||||
# Project target.
|
||||
target=Google Inc.:Google APIs:15
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingService;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for the BootReceiver.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class BootReceiverTest extends AndroidTestCase {
|
||||
private static final String SERVICE_NAME = "com.google.android.apps.mytracks.services.TrackRecordingService";
|
||||
|
||||
/**
|
||||
* Tests the behavior when receive notification which is the phone boot.
|
||||
*/
|
||||
public void testOnReceive_startService() {
|
||||
// Make sure no TrackRecordingService
|
||||
Intent stopIntent = new Intent(getContext(), TrackRecordingService.class);
|
||||
getContext().stopService(stopIntent);
|
||||
assertFalse(isServiceExisted(getContext(), SERVICE_NAME));
|
||||
|
||||
BootReceiver bootReceiver = new BootReceiver();
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_BOOT_COMPLETED);
|
||||
bootReceiver.onReceive(getContext(), intent);
|
||||
// Check if the service is started
|
||||
assertTrue(isServiceExisted(getContext(), SERVICE_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the behavior when receive notification which is not the phone boot.
|
||||
*/
|
||||
public void testOnReceive_noStartService() {
|
||||
// Make sure no TrackRecordingService
|
||||
Intent stopIntent = new Intent(getContext(), TrackRecordingService.class);
|
||||
getContext().stopService(stopIntent);
|
||||
assertFalse(isServiceExisted(getContext(), SERVICE_NAME));
|
||||
|
||||
BootReceiver bootReceiver = new BootReceiver();
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_BUG_REPORT);
|
||||
bootReceiver.onReceive(getContext(), intent);
|
||||
// Check if the service is not started
|
||||
assertFalse(isServiceExisted(getContext(), SERVICE_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a service is started in a context.
|
||||
*
|
||||
* @param context the context for checking a service
|
||||
* @param serviceName the service name to find if existed
|
||||
*/
|
||||
private boolean isServiceExisted(Context context, String serviceName) {
|
||||
ActivityManager activityManager = (ActivityManager) context
|
||||
.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<ActivityManager.RunningServiceInfo> serviceList = activityManager
|
||||
.getRunningServices(Integer.MAX_VALUE);
|
||||
for (int i = 0; i < serviceList.size(); i++) {
|
||||
RunningServiceInfo serviceInfo = serviceList.get(i);
|
||||
ComponentName componentName = serviceInfo.service;
|
||||
if (componentName.getClassName().equals(serviceName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests {@link ChartValueSeries}.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class ChartValueSeriesTest extends AndroidTestCase {
|
||||
private ChartValueSeries series;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
series = new ChartValueSeries(getContext(),
|
||||
Integer.MIN_VALUE,
|
||||
Integer.MAX_VALUE,
|
||||
new int[] {100, 1000 },
|
||||
R.string.description_elevation_metric,
|
||||
R.string.description_elevation_imperial,
|
||||
R.color.elevation_fill,
|
||||
R.color.elevation_border);
|
||||
}
|
||||
|
||||
public void testInitialConditions() {
|
||||
assertEquals(1, series.getInterval());
|
||||
assertEquals(0, series.getMinMarkerValue());
|
||||
assertEquals(5, series.getMaxMarkerValue());
|
||||
assertTrue(series.isEnabled());
|
||||
}
|
||||
|
||||
public void testEnabled() {
|
||||
series.setEnabled(false);
|
||||
assertFalse(series.isEnabled());
|
||||
}
|
||||
|
||||
public void testSmallUpdates() {
|
||||
series.update(0);
|
||||
series.update(10);
|
||||
series.updateDimension();
|
||||
assertEquals(100, series.getInterval());
|
||||
assertEquals(0, series.getMinMarkerValue());
|
||||
assertEquals(500, series.getMaxMarkerValue());
|
||||
}
|
||||
|
||||
public void testBigUpdates() {
|
||||
series.update(0);
|
||||
series.update(901);
|
||||
series.updateDimension();
|
||||
assertEquals(1000, series.getInterval());
|
||||
assertEquals(0, series.getMinMarkerValue());
|
||||
assertEquals(5000, series.getMaxMarkerValue());
|
||||
}
|
||||
|
||||
public void testNotZeroBasedUpdates() {
|
||||
series.update(220);
|
||||
series.update(250);
|
||||
series.updateDimension();
|
||||
assertEquals(100, series.getInterval());
|
||||
assertEquals(200, series.getMinMarkerValue());
|
||||
assertEquals(700, series.getMaxMarkerValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.maps.SingleColorTrackPathPainter;
|
||||
import com.google.android.maps.MapView;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Path;
|
||||
import android.location.Location;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests for the MyTracks map overlay.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
* @author Vangelis S.
|
||||
*/
|
||||
public class MapOverlayTest extends AndroidTestCase {
|
||||
private Canvas canvas;
|
||||
private MockMyTracksOverlay myTracksOverlay;
|
||||
private MapView mockView;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
canvas = new Canvas();
|
||||
myTracksOverlay = new MockMyTracksOverlay(getContext());
|
||||
|
||||
// Enable drawing.
|
||||
myTracksOverlay.setTrackDrawingEnabled(true);
|
||||
|
||||
// Set a TrackPathPainter with a MockPath.
|
||||
myTracksOverlay.setTrackPathPainter(new SingleColorTrackPathPainter(getContext()) {
|
||||
@Override
|
||||
public Path newPath() {
|
||||
return new MockPath();
|
||||
}
|
||||
});
|
||||
|
||||
mockView = null;
|
||||
}
|
||||
|
||||
public void testAddLocation() throws Exception {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
location.setLongitude(20);
|
||||
myTracksOverlay.addLocation(location);
|
||||
assertEquals(1, myTracksOverlay.getNumLocations());
|
||||
assertEquals(0, myTracksOverlay.getNumWaypoints());
|
||||
|
||||
location.setLatitude(20);
|
||||
location.setLongitude(30);
|
||||
myTracksOverlay.addLocation(location);
|
||||
assertEquals(2, myTracksOverlay.getNumLocations());
|
||||
assertEquals(0, myTracksOverlay.getNumWaypoints());
|
||||
assertNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
|
||||
// Draw and make sure that we don't lose any point.
|
||||
myTracksOverlay.draw(canvas, mockView, false);
|
||||
assertEquals(2, myTracksOverlay.getNumLocations());
|
||||
assertEquals(0, myTracksOverlay.getNumWaypoints());
|
||||
assertNotNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
assertTrue(myTracksOverlay.getTrackPathPainter().getLastPath() instanceof MockPath);
|
||||
MockPath path = (MockPath) myTracksOverlay.getTrackPathPainter().getLastPath();
|
||||
assertEquals(2, path.totalPoints);
|
||||
|
||||
myTracksOverlay.draw(canvas, mockView, true);
|
||||
assertEquals(2, myTracksOverlay.getNumLocations());
|
||||
assertEquals(0, myTracksOverlay.getNumWaypoints());
|
||||
assertNotNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
}
|
||||
|
||||
public void testClearPoints() throws Exception {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
location.setLongitude(20);
|
||||
myTracksOverlay.addLocation(location);
|
||||
assertEquals(1, myTracksOverlay.getNumLocations());
|
||||
myTracksOverlay.clearPoints();
|
||||
assertEquals(0, myTracksOverlay.getNumLocations());
|
||||
|
||||
// Same after drawing on canvas.
|
||||
final int locations = 100;
|
||||
for (int i = 0; i < locations; ++i) {
|
||||
myTracksOverlay.addLocation(location);
|
||||
}
|
||||
assertEquals(locations, myTracksOverlay.getNumLocations());
|
||||
myTracksOverlay.draw(canvas, mockView, false);
|
||||
myTracksOverlay.draw(canvas, mockView, true);
|
||||
myTracksOverlay.clearPoints();
|
||||
assertEquals(0, myTracksOverlay.getNumLocations());
|
||||
}
|
||||
|
||||
public void testAddWaypoint() throws Exception {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
location.setLongitude(20);
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.setLocation(location);
|
||||
myTracksOverlay.addWaypoint(waypoint);
|
||||
assertEquals(1, myTracksOverlay.getNumWaypoints());
|
||||
assertEquals(0, myTracksOverlay.getNumLocations());
|
||||
assertNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
|
||||
final int waypoints = 10;
|
||||
for (int i = 0; i < waypoints; ++i) {
|
||||
waypoint = new Waypoint();
|
||||
waypoint.setLocation(location);
|
||||
myTracksOverlay.addWaypoint(waypoint);
|
||||
}
|
||||
assertEquals(1 + waypoints, myTracksOverlay.getNumWaypoints());
|
||||
assertEquals(0, myTracksOverlay.getNumLocations());
|
||||
assertNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
}
|
||||
|
||||
public void testClearWaypoints() throws Exception {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
location.setLongitude(20);
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.setLocation(location);
|
||||
myTracksOverlay.addWaypoint(waypoint);
|
||||
assertEquals(1, myTracksOverlay.getNumWaypoints());
|
||||
myTracksOverlay.clearWaypoints();
|
||||
assertEquals(0, myTracksOverlay.getNumWaypoints());
|
||||
}
|
||||
|
||||
public void testDrawing() {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
for (int i = 0; i < 40; ++i) {
|
||||
location.setLongitude(20 + i);
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.setLocation(location);
|
||||
myTracksOverlay.addWaypoint(waypoint);
|
||||
}
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
location = new Location("gps");
|
||||
location.setLatitude(20 + i / 2);
|
||||
location.setLongitude(150 - i);
|
||||
myTracksOverlay.addLocation(location);
|
||||
}
|
||||
|
||||
// Shadow.
|
||||
myTracksOverlay.draw(canvas, mockView, true);
|
||||
// We don't expect to do anything if
|
||||
assertNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
assertEquals(40, myTracksOverlay.getNumWaypoints());
|
||||
assertEquals(100, myTracksOverlay.getNumLocations());
|
||||
|
||||
// No shadow.
|
||||
myTracksOverlay.draw(canvas, mockView, false);
|
||||
assertNotNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
assertTrue(myTracksOverlay.getTrackPathPainter().getLastPath() instanceof MockPath);
|
||||
MockPath path = (MockPath) myTracksOverlay.getTrackPathPainter().getLastPath();
|
||||
assertEquals(40, myTracksOverlay.getNumWaypoints());
|
||||
assertEquals(100, myTracksOverlay.getNumLocations());
|
||||
assertEquals(100, path.totalPoints);
|
||||
// TODO: Check the points from the path (and the segments).
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.maps.MapView;
|
||||
import com.google.android.maps.Projection;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* Elements for Tests for the MyTracks map overlay.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
* @author Vangelis S.
|
||||
*
|
||||
* A mock version of {@code MapOverlay} that does not use
|
||||
* {@class MapView}.
|
||||
*/
|
||||
public class MockMyTracksOverlay extends MapOverlay {
|
||||
|
||||
private Projection mockProjection;
|
||||
|
||||
public MockMyTracksOverlay(Context context) {
|
||||
super(context);
|
||||
mockProjection = new MockProjection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Projection getMapProjection(MapView mapView) {
|
||||
return mockProjection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rect getMapViewRect(MapView mapView) {
|
||||
return new Rect(0, 0, 100, 100);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
/**
|
||||
* Elements for Tests for the MyTracks map overlay.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
* @author Vangelis S.
|
||||
*
|
||||
* A mock class that intercepts {@code Path}'s and records calls to
|
||||
* {@code #moveTo()} and {@code #lineTo()}.
|
||||
*/
|
||||
public class MockPath extends Path {
|
||||
|
||||
/** A list of disjoined path segments. */
|
||||
public final List<List<PointF>> segments = new LinkedList<List<PointF>>();
|
||||
/** The total number of points in this path. */
|
||||
public int totalPoints;
|
||||
private List<PointF> currentSegment;
|
||||
|
||||
@Override
|
||||
public void lineTo(float x, float y) {
|
||||
super.lineTo(x, y);
|
||||
Assert.assertNotNull(currentSegment);
|
||||
currentSegment.add(new PointF(x, y));
|
||||
totalPoints++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(float x, float y) {
|
||||
super.moveTo(x, y);
|
||||
segments.add(currentSegment =
|
||||
new ArrayList<PointF>(Arrays.asList(new PointF(x, y))));
|
||||
totalPoints++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.maps.GeoPoint;
|
||||
import com.google.android.maps.Projection;
|
||||
|
||||
import android.graphics.Point;
|
||||
|
||||
/**
|
||||
* Elements for Tests for the MyTracks map overlay.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
* @author Vangelis S.
|
||||
*
|
||||
* A mock {@code Projection} that acts as the identity matrix.
|
||||
*/
|
||||
public class MockProjection implements Projection {
|
||||
|
||||
@Override
|
||||
public Point toPixels(GeoPoint in, Point out) {
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float metersToEquatorPixels(float meters) {
|
||||
return meters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeoPoint fromPixels(int x, int y) {
|
||||
return new GeoPoint(y, x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* Commons utilities for creating stubs of track, location. The class will be
|
||||
* enriched if needs more similar stubs for test.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class TrackStubUtils {
|
||||
|
||||
static final String LOCATION_PROVIDER = "gps";
|
||||
public static final double INITIAL_LATITUDE = 22;
|
||||
public static final double INITIAL_LONGITUDE = 22;
|
||||
public static final double INITIAL_ALTITUDE = 22;
|
||||
static final float INITIAL_ACCURACY = 5;
|
||||
static final float INITIAL_SPEED = 10;
|
||||
static final float INITIAL_BEARING = 3.0f;
|
||||
// Used to change the value of latitude, longitude, and altitude.
|
||||
static final double DIFFERENCE = 0.01;
|
||||
|
||||
/**
|
||||
* Gets a a {@link Track} stub with specified number of locations.
|
||||
*
|
||||
* @param numberOfLocations the number of locations for the track
|
||||
* @return a track stub.
|
||||
*/
|
||||
public static Track createTrack(int numberOfLocations) {
|
||||
Track track = new Track();
|
||||
for (int i = 0; i < numberOfLocations; i++) {
|
||||
track.addLocation(createMyTracksLocation(INITIAL_LATITUDE + i * DIFFERENCE, INITIAL_LONGITUDE
|
||||
+ i * DIFFERENCE, INITIAL_ALTITUDE + i * DIFFERENCE));
|
||||
}
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a MyTracks location with default values.
|
||||
*
|
||||
* @return a track stub.
|
||||
*/
|
||||
public static MyTracksLocation createMyTracksLocation() {
|
||||
return createMyTracksLocation(INITIAL_LATITUDE, INITIAL_LONGITUDE, INITIAL_ALTITUDE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link MyTracksLocation} stub with specified values.
|
||||
*
|
||||
* @return a MyTracksLocation stub.
|
||||
*/
|
||||
public static MyTracksLocation createMyTracksLocation(double latitude, double longitude,
|
||||
double altitude) {
|
||||
// Initial Location
|
||||
Location loc = new Location(LOCATION_PROVIDER);
|
||||
loc.setLatitude(latitude);
|
||||
loc.setLongitude(longitude);
|
||||
loc.setAltitude(altitude);
|
||||
loc.setAccuracy(INITIAL_ACCURACY);
|
||||
loc.setSpeed(INITIAL_SPEED);
|
||||
loc.setTime(System.currentTimeMillis());
|
||||
loc.setBearing(INITIAL_BEARING);
|
||||
SensorDataSet sd = SensorDataSet.newBuilder().build();
|
||||
MyTracksLocation myTracksLocation = new MyTracksLocation(loc, sd);
|
||||
|
||||
return myTracksLocation;
|
||||
}
|
||||
|
||||
}
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import android.util.Pair;
|
||||
|
||||
/**
|
||||
* Tests for {@link DescriptionGeneratorImpl}.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class DescriptionGeneratorImplTest extends AndroidTestCase {
|
||||
|
||||
private static final long START_TIME = 1288721514000L;
|
||||
private DescriptionGeneratorImpl descriptionGenerator;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
descriptionGenerator = new DescriptionGeneratorImpl(getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#generateTrackDescription(Track,
|
||||
* java.util.Vector, java.util.Vector, boolean)}.
|
||||
*/
|
||||
public void testGenerateTrackDescription() {
|
||||
Track track = new Track();
|
||||
TripStatistics stats = new TripStatistics();
|
||||
stats.setTotalDistance(20000);
|
||||
stats.setTotalTime(600000);
|
||||
stats.setMovingTime(300000);
|
||||
stats.setMaxSpeed(100);
|
||||
stats.setMaxElevation(550);
|
||||
stats.setMinElevation(-500);
|
||||
stats.setTotalElevationGain(6000);
|
||||
stats.setMaxGrade(0.42);
|
||||
stats.setMinGrade(0.11);
|
||||
stats.setStartTime(START_TIME);
|
||||
track.setTripStatistics(stats);
|
||||
track.setCategory("hiking");
|
||||
String expected = "Created by"
|
||||
+ " <a href='http://www.google.com/mobile/mytracks'>My Tracks</a> on Android.<p>"
|
||||
+ "Name: -<br>"
|
||||
+ "Activity type: hiking<br>"
|
||||
+ "Description: -<br>"
|
||||
+ "Total distance: 20.00 km (12.4 mi)<br>"
|
||||
+ "Total time: 10:00<br>"
|
||||
+ "Moving time: 05:00<br>"
|
||||
+ "Average speed: 120.00 km/h (74.6 mi/h)<br>"
|
||||
+ "Average moving speed: 240.00 km/h (149.1 mi/h)<br>"
|
||||
+ "Max speed: 360.00 km/h (223.7 mi/h)<br>"
|
||||
+ "Average pace: 0.50 min/km (0.8 min/mi)<br>"
|
||||
+ "Average moving pace: 0.25 min/km (0.4 min/mi)<br>"
|
||||
+ "Fastest pace: 0.17 min/km (0.3 min/mi)<br>"
|
||||
+ "Max elevation: 550 m (1804 ft)<br>"
|
||||
+ "Min elevation: -500 m (-1640 ft)<br>"
|
||||
+ "Elevation gain: 6000 m (19685 ft)<br>"
|
||||
+ "Max grade: 42 %<br>"
|
||||
+ "Min grade: 11 %<br>"
|
||||
+ "Recorded: " + StringUtils.formatDateTime(getContext(), START_TIME) + "<br>";
|
||||
assertEquals(expected, descriptionGenerator.generateTrackDescription(track, null, null, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#generateWaypointDescription(Waypoint)}.
|
||||
*/
|
||||
public void testGenerateWaypointDescription() {
|
||||
Waypoint waypoint = new Waypoint();
|
||||
TripStatistics stats = new TripStatistics();
|
||||
stats.setTotalDistance(20000);
|
||||
stats.setTotalTime(600000);
|
||||
stats.setMovingTime(300000);
|
||||
stats.setMaxSpeed(100);
|
||||
stats.setMaxElevation(550);
|
||||
stats.setMinElevation(-500);
|
||||
stats.setTotalElevationGain(6000);
|
||||
stats.setMaxGrade(0.42);
|
||||
stats.setMinGrade(0.11);
|
||||
stats.setStartTime(START_TIME);
|
||||
waypoint.setTripStatistics(stats);
|
||||
String expected = "Total distance: 20.00 km (12.4 mi)\n"
|
||||
+ "Total time: 10:00\n"
|
||||
+ "Moving time: 05:00\n"
|
||||
+ "Average speed: 120.00 km/h (74.6 mi/h)\n"
|
||||
+ "Average moving speed: 240.00 km/h (149.1 mi/h)\n"
|
||||
+ "Max speed: 360.00 km/h (223.7 mi/h)\n"
|
||||
+ "Average pace: 0.50 min/km (0.8 min/mi)\n"
|
||||
+ "Average moving pace: 0.25 min/km (0.4 min/mi)\n"
|
||||
+ "Fastest pace: 0.17 min/km (0.3 min/mi)\n"
|
||||
+ "Max elevation: 550 m (1804 ft)\n"
|
||||
+ "Min elevation: -500 m (-1640 ft)\n"
|
||||
+ "Elevation gain: 6000 m (19685 ft)\n"
|
||||
+ "Max grade: 42 %\n"
|
||||
+ "Min grade: 11 %\n"
|
||||
+ "Recorded: " + StringUtils.formatDateTime(getContext(), START_TIME) + "\n";
|
||||
assertEquals(expected, descriptionGenerator.generateWaypointDescription(waypoint));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#writeDistance(double, StringBuilder,
|
||||
* int, String)}.
|
||||
*/
|
||||
public void testWriteDistance() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
descriptionGenerator.writeDistance(1100, builder, R.string.description_total_distance, "<br>");
|
||||
assertEquals("Total distance: 1.10 km (0.7 mi)<br>", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#writeTime(long, StringBuilder, int,
|
||||
* String)}.
|
||||
*/
|
||||
public void testWriteTime() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
descriptionGenerator.writeTime(1000, builder, R.string.description_total_time, "<br>");
|
||||
assertEquals("Total time: 00:01<br>", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#writeSpeed(double, StringBuilder,
|
||||
* int, String)}.
|
||||
*/
|
||||
public void testWriteSpeed() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
descriptionGenerator.writeSpeed(1.1, builder, R.string.description_average_speed, "\n");
|
||||
assertEquals("Average speed: 3.96 km/h (2.5 mi/h)\n", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#writeElevation(double, StringBuilder,
|
||||
* int, String)}.
|
||||
*/
|
||||
public void testWriteElevation() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
descriptionGenerator.writeElevation(4.2, builder, R.string.description_min_elevation, "<br>");
|
||||
assertEquals("Min elevation: 4 m (14 ft)<br>", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#writePace(Pair, StringBuilder, int,
|
||||
* String)}.
|
||||
*/
|
||||
public void testWritePace() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
descriptionGenerator.writePace(
|
||||
new Pair<Double, Double>(1.1, 2.2), builder, R.string.description_average_pace, "\n");
|
||||
assertEquals("Average pace: 54.55 min/km (27.3 min/mi)\n", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#writeGrade(double, StringBuilder,
|
||||
* int, String)}.
|
||||
*/
|
||||
public void testWriteGrade() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
descriptionGenerator.writeGrade(.042, builder, R.string.description_max_grade, "<br>");
|
||||
assertEquals("Max grade: 4 %<br>", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#writeGrade(double, StringBuilder,
|
||||
* int, String)} with a NaN.
|
||||
*/
|
||||
public void testWriteGrade_nan() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
descriptionGenerator.writeGrade(Double.NaN, builder, R.string.description_max_grade, "<br>");
|
||||
assertEquals("Max grade: 0 %<br>", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#writeGrade(double, StringBuilder,
|
||||
* int, String)} with an infinite number.
|
||||
*/
|
||||
public void testWriteGrade_infinite() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
descriptionGenerator.writeGrade(
|
||||
Double.POSITIVE_INFINITY, builder, R.string.description_max_grade, "<br>");
|
||||
assertEquals("Max grade: 0 %<br>", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#getPace(double)}.
|
||||
*/
|
||||
public void testGetPace() {
|
||||
assertEquals(12.0, descriptionGenerator.getPace(5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DescriptionGeneratorImpl#getPace(double)} with zero speed.
|
||||
*/
|
||||
public void testGetPace_zero() {
|
||||
assertEquals(0.0, descriptionGenerator.getPace(0));
|
||||
}
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationFactory;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* A unit test for {@link MyTracksProviderUtilsImpl}.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
*/
|
||||
public class MyTracksProviderUtilsImplTest extends AndroidTestCase {
|
||||
private Context context;
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
MockContentResolver mockContentResolver = new MockContentResolver();
|
||||
RenamingDelegatingContext targetContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
context = new MockContext(mockContentResolver, targetContext);
|
||||
MyTracksProvider provider = new MyTracksProvider();
|
||||
provider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, provider);
|
||||
setContext(context);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
}
|
||||
|
||||
public void testLocationIterator_noPoints() {
|
||||
testIterator(1, 0, 1, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_customFactory() {
|
||||
final Location location = new Location("test_location");
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
testIterator(1, 15, 4, false, new LocationFactory() {
|
||||
@Override
|
||||
public Location createLocation() {
|
||||
counter.incrementAndGet();
|
||||
return location;
|
||||
}
|
||||
});
|
||||
// Make sure we were called exactly as many times as we had track points.
|
||||
assertEquals(15, counter.get());
|
||||
}
|
||||
|
||||
public void testLocationIterator_nullFactory() {
|
||||
try {
|
||||
testIterator(1, 15, 4, false, null);
|
||||
fail("Expecting IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Expected.
|
||||
}
|
||||
}
|
||||
|
||||
public void testLocationIterator_noBatchAscending() {
|
||||
testIterator(1, 50, 100, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
testIterator(2, 50, 50, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_noBatchDescending() {
|
||||
testIterator(1, 50, 100, true, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
testIterator(2, 50, 50, true, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_batchAscending() {
|
||||
testIterator(1, 50, 11, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
testIterator(2, 50, 25, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_batchDescending() {
|
||||
testIterator(1, 50, 11, true, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
testIterator(2, 50, 25, true, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
public void testLocationIterator_largeTrack() {
|
||||
testIterator(1, 20000, 2000, false, MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
}
|
||||
|
||||
private List<Location> testIterator(long trackId, int numPoints, int batchSize,
|
||||
boolean descending, LocationFactory locationFactory) {
|
||||
long lastPointId = initializeTrack(trackId, numPoints);
|
||||
((MyTracksProviderUtilsImpl) providerUtils).setDefaultCursorBatchSize(batchSize);
|
||||
List<Location> locations = new ArrayList<Location>(numPoints);
|
||||
LocationIterator it = providerUtils.getLocationIterator(trackId, -1, descending, locationFactory);
|
||||
try {
|
||||
while (it.hasNext()) {
|
||||
Location loc = it.next();
|
||||
assertNotNull(loc);
|
||||
locations.add(loc);
|
||||
// Make sure the IDs are returned in the right order.
|
||||
assertEquals(descending ? lastPointId - locations.size() + 1
|
||||
: lastPointId - numPoints + locations.size(), it.getLocationId());
|
||||
}
|
||||
assertEquals(numPoints, locations.size());
|
||||
} finally {
|
||||
it.close();
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
private long initializeTrack(long id, int numPoints) {
|
||||
Track track = new Track();
|
||||
track.setId(id);
|
||||
track.setName("Test: " + id);
|
||||
track.setNumberOfPoints(numPoints);
|
||||
providerUtils.insertTrack(track);
|
||||
track = providerUtils.getTrack(id);
|
||||
assertNotNull(track);
|
||||
|
||||
Location[] locations = new Location[numPoints];
|
||||
for (int i = 0; i < numPoints; ++i) {
|
||||
Location loc = new Location("test");
|
||||
loc.setLatitude(37.0 + (double) i / 10000.0);
|
||||
loc.setLongitude(57.0 - (double) i / 10000.0);
|
||||
loc.setAccuracy((float) i / 100.0f);
|
||||
loc.setAltitude(i * 2.5);
|
||||
locations[i] = loc;
|
||||
}
|
||||
providerUtils.bulkInsertTrackPoints(locations, numPoints, id);
|
||||
|
||||
// Load all inserted locations.
|
||||
long lastPointId = -1;
|
||||
int counter = 0;
|
||||
LocationIterator it = providerUtils.getLocationIterator(id, -1, false,
|
||||
MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
|
||||
try {
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
lastPointId = it.getLocationId();
|
||||
counter++;
|
||||
}
|
||||
} finally {
|
||||
it.close();
|
||||
}
|
||||
|
||||
assertTrue(numPoints == 0 || lastPointId > 0);
|
||||
assertEquals(numPoints, track.getNumberOfPoints());
|
||||
assertEquals(numPoints, counter);
|
||||
|
||||
return lastPointId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import com.google.android.apps.mytracks.content.SearchEngine.ScoredResult;
|
||||
import com.google.android.apps.mytracks.content.SearchEngine.SearchQuery;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
|
||||
import android.content.ContentUris;
|
||||
import android.location.Location;
|
||||
import android.net.Uri;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for {@link SearchEngine}.
|
||||
* These are not meant to be quality tests, but instead feature-by-feature tests
|
||||
* (in other words, they don't test the mixing of different score boostings, just
|
||||
* each boosting separately)
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class SearchEngineTest extends AndroidTestCase {
|
||||
|
||||
private static final Location HERE = new Location("gps");
|
||||
private static final long NOW = 1234567890000L; // After OLDEST_ALLOWED_TIMESTAMP
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
private SearchEngine engine;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
MockContentResolver mockContentResolver = new MockContentResolver();
|
||||
RenamingDelegatingContext targetContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
MockContext context = new MockContext(mockContentResolver, targetContext);
|
||||
MyTracksProvider provider = new MyTracksProvider();
|
||||
provider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, provider);
|
||||
setContext(context);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
engine = new SearchEngine(providerUtils);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
providerUtils.deleteAllTracks();
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private long insertTrack(String title, String description, String category, double distance, long hoursAgo) {
|
||||
Track track = new Track();
|
||||
track.setName(title);
|
||||
track.setDescription(description);
|
||||
track.setCategory(category);
|
||||
|
||||
TripStatistics stats = track.getTripStatistics();
|
||||
if (hoursAgo > 0) {
|
||||
// Started twice hoursAgo, so the average time is hoursAgo.
|
||||
stats.setStartTime(NOW - hoursAgo * 1000L * 60L * 60L * 2);
|
||||
stats.setStopTime(NOW);
|
||||
}
|
||||
|
||||
int latitude = (int) ((HERE.getLatitude() + distance) * 1E6);
|
||||
int longitude = (int) ((HERE.getLongitude() + distance) * 1E6);
|
||||
stats.setBounds(latitude, longitude, latitude, longitude);
|
||||
|
||||
Uri uri = providerUtils.insertTrack(track);
|
||||
return ContentUris.parseId(uri);
|
||||
}
|
||||
|
||||
private long insertTrack(String title, String description, String category) {
|
||||
return insertTrack(title, description, category, 0, -1);
|
||||
}
|
||||
|
||||
private long insertTrack(String title, double distance) {
|
||||
return insertTrack(title, "", "", distance, -1);
|
||||
}
|
||||
|
||||
private long insertTrack(String title, long hoursAgo) {
|
||||
return insertTrack(title, "", "", 0.0, hoursAgo);
|
||||
}
|
||||
|
||||
private long insertWaypoint(String title, String description, String category, double distance, long hoursAgo, long trackId) {
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.setName(title);
|
||||
waypoint.setDescription(description);
|
||||
waypoint.setCategory(category);
|
||||
waypoint.setTrackId(trackId);
|
||||
|
||||
Location location = new Location(HERE);
|
||||
location.setLatitude(location.getLatitude() + distance);
|
||||
location.setLongitude(location.getLongitude() + distance);
|
||||
if (hoursAgo >= 0) {
|
||||
location.setTime(NOW - hoursAgo * 1000L * 60L * 60L);
|
||||
}
|
||||
waypoint.setLocation(location);
|
||||
|
||||
Uri uri = providerUtils.insertWaypoint(waypoint);
|
||||
return ContentUris.parseId(uri);
|
||||
}
|
||||
|
||||
private long insertWaypoint(String title, String description, String category) {
|
||||
return insertWaypoint(title, description, category, 0.0, -1, -1);
|
||||
}
|
||||
|
||||
private long insertWaypoint(String title, double distance) {
|
||||
return insertWaypoint(title, "", "", distance, -1, -1);
|
||||
}
|
||||
|
||||
private long insertWaypoint(String title, long hoursAgo) {
|
||||
return insertWaypoint(title, "", "", 0.0, hoursAgo, -1);
|
||||
}
|
||||
|
||||
private long insertWaypoint(String title, long hoursAgo, long trackId) {
|
||||
return insertWaypoint(title, "", "", 0.0, hoursAgo, trackId);
|
||||
}
|
||||
|
||||
public void testSearchText() {
|
||||
// Insert 7 tracks (purposefully out of result order):
|
||||
// - one which won't match
|
||||
// - one which will match the description
|
||||
// - one which will match the category
|
||||
// - one which will match the title
|
||||
// - one which will match in title and category
|
||||
// - one which will match in title and description
|
||||
// - one which will match in all fields
|
||||
insertTrack("bb", "cc", "dd");
|
||||
long descriptionMatchId = insertTrack("bb", "aa", "cc");
|
||||
long categoryMatchId = insertTrack("bb", "cc", "aa");
|
||||
long titleMatchId = insertTrack("aa", "bb", "cc");
|
||||
long titleCategoryMatchId = insertTrack("aa", "bb", "ca");
|
||||
long titleDescriptionMatchId = insertTrack("aa", "ba", "cc");
|
||||
long allMatchId = insertTrack("aa", "ba", "ca");
|
||||
|
||||
SearchQuery query = new SearchQuery("a", null, -1, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Title > Description > Category.
|
||||
assertTrackResults(results,
|
||||
allMatchId, titleDescriptionMatchId, titleCategoryMatchId, titleMatchId, descriptionMatchId,
|
||||
categoryMatchId);
|
||||
}
|
||||
|
||||
public void testSearchWaypointText() {
|
||||
// Insert 7 waypoints (purposefully out of result order):
|
||||
// - one which won't match
|
||||
// - one which will match the description
|
||||
// - one which will match the category
|
||||
// - one which will match the title
|
||||
// - one which will match in title and category
|
||||
// - one which will match in title and description
|
||||
// - one which will match in all fields
|
||||
insertWaypoint("bb", "cc", "dd");
|
||||
long descriptionMatchId = insertWaypoint("bb", "aa", "cc");
|
||||
long categoryMatchId = insertWaypoint("bb", "cc", "aa");
|
||||
long titleMatchId = insertWaypoint("aa", "bb", "cc");
|
||||
long titleCategoryMatchId = insertWaypoint("aa", "bb", "ca");
|
||||
long titleDescriptionMatchId = insertWaypoint("aa", "ba", "cc");
|
||||
long allMatchId = insertWaypoint("aa", "ba", "ca");
|
||||
|
||||
SearchQuery query = new SearchQuery("a", null, -1, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Title > Description > Category.
|
||||
assertWaypointResults(results,
|
||||
allMatchId, titleDescriptionMatchId, titleCategoryMatchId, titleMatchId, descriptionMatchId,
|
||||
categoryMatchId);
|
||||
}
|
||||
|
||||
public void testSearchMixedText() {
|
||||
// Insert 5 entries (purposefully out of result order):
|
||||
// - one waypoint which will match by description
|
||||
// - one waypoint which won't match
|
||||
// - one waypoint which will match by title
|
||||
// - one track which won't match
|
||||
// - one track which will match by title
|
||||
long descriptionWaypointId = insertWaypoint("bb", "aa", "cc");
|
||||
insertWaypoint("bb", "cc", "dd");
|
||||
long titleWaypointId = insertWaypoint("aa", "bb", "cc");
|
||||
insertTrack("bb", "cc", "dd");
|
||||
long trackId = insertTrack("aa", "bb", "cc");
|
||||
|
||||
SearchQuery query = new SearchQuery("a", null, -1, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Title > Description > Category.
|
||||
assertEquals(results.toString(), 3, results.size());
|
||||
assertTrackResult(trackId, results.get(0));
|
||||
assertWaypointResult(titleWaypointId, results.get(1));
|
||||
assertWaypointResult(descriptionWaypointId, results.get(2));
|
||||
}
|
||||
|
||||
public void testSearchTrackDistance() {
|
||||
// All results match text, but they're at difference distances from the user.
|
||||
long farFarAwayId = insertTrack("aa", 0.3);
|
||||
long nearId = insertTrack("ab", 0.1);
|
||||
long farId = insertTrack("ac", 0.2);
|
||||
|
||||
SearchQuery query = new SearchQuery("a", HERE, -1, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Distance order.
|
||||
assertTrackResults(results, nearId, farId, farFarAwayId);
|
||||
}
|
||||
|
||||
public void testSearchWaypointDistance() {
|
||||
// All results match text, but they're at difference distances from the user.
|
||||
long farFarAwayId = insertWaypoint("aa", 0.3);
|
||||
long nearId = insertWaypoint("ab", 0.1);
|
||||
long farId = insertWaypoint("ac", 0.2);
|
||||
|
||||
SearchQuery query = new SearchQuery("a", HERE, -1, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Distance order.
|
||||
assertWaypointResults(results, nearId, farId, farFarAwayId);
|
||||
}
|
||||
|
||||
public void testSearchTrackRecent() {
|
||||
// All results match text, but they're were recorded at different times.
|
||||
long oldestId = insertTrack("aa", 3);
|
||||
long recentId = insertTrack("ab", 1);
|
||||
long oldId = insertTrack("ac", 2);
|
||||
|
||||
SearchQuery query = new SearchQuery("a", null, -1, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Reverse time order.
|
||||
assertTrackResults(results, recentId, oldId, oldestId);
|
||||
}
|
||||
|
||||
public void testSearchWaypointRecent() {
|
||||
// All results match text, but they're were recorded at different times.
|
||||
long oldestId = insertWaypoint("aa", 2);
|
||||
long recentId = insertWaypoint("ab", 0);
|
||||
long oldId = insertWaypoint("ac", 1);
|
||||
|
||||
SearchQuery query = new SearchQuery("a", null, -1, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Reverse time order.
|
||||
assertWaypointResults(results, recentId, oldId, oldestId);
|
||||
}
|
||||
|
||||
public void testSearchCurrentTrack() {
|
||||
// All results match text, but one of them is the current track.
|
||||
long currentId = insertTrack("ab", 1);
|
||||
long otherId = insertTrack("aa", 1);
|
||||
|
||||
SearchQuery query = new SearchQuery("a", null, currentId, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Current track should be demoted.
|
||||
assertTrackResults(results, otherId, currentId);
|
||||
}
|
||||
|
||||
public void testSearchCurrentTrackWaypoint() {
|
||||
// All results match text, but one of them is in the current track.
|
||||
long otherId = insertWaypoint("aa", 1, 456);
|
||||
long currentId = insertWaypoint("ab", 1, 123);
|
||||
|
||||
SearchQuery query = new SearchQuery("a", null, 123, NOW);
|
||||
ArrayList<ScoredResult> results = new ArrayList<ScoredResult>(engine.search(query));
|
||||
|
||||
// Waypoint in current track should be promoted.
|
||||
assertWaypointResults(results, currentId, otherId);
|
||||
}
|
||||
|
||||
private void assertTrackResult(long trackId, ScoredResult result) {
|
||||
assertNotNull("Not a track", result.track);
|
||||
assertNull("Ambiguous result", result.waypoint);
|
||||
assertEquals(trackId, result.track.getId());
|
||||
}
|
||||
|
||||
private void assertTrackResults(List<ScoredResult> results, long... trackIds) {
|
||||
String errMsg = "Expected IDs=" + Arrays.toString(trackIds) + "; results=" + results;
|
||||
assertEquals(results.size(), trackIds.length);
|
||||
for (int i = 0; i < results.size(); i++) {
|
||||
ScoredResult result = results.get(i);
|
||||
assertNotNull(errMsg, result.track);
|
||||
assertNull(errMsg, result.waypoint);
|
||||
assertEquals(errMsg, trackIds[i], result.track.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void assertWaypointResult(long waypointId, ScoredResult result) {
|
||||
assertNotNull("Not a waypoint", result.waypoint);
|
||||
assertNull("Ambiguous result", result.track);
|
||||
assertEquals(waypointId, result.waypoint.getId());
|
||||
}
|
||||
|
||||
private void assertWaypointResults(List<ScoredResult> results, long... waypointIds) {
|
||||
String errMsg = "Expected IDs=" + Arrays.toString(waypointIds) + "; results=" + results;
|
||||
assertEquals(results.size(), waypointIds.length);
|
||||
for (int i = 0; i < results.size(); i++) {
|
||||
ScoredResult result = results.get(i);
|
||||
assertNotNull(errMsg, result.waypoint);
|
||||
assertNull(errMsg, result.track);
|
||||
assertEquals(errMsg, waypointIds[i], result.waypoint.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,843 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import static com.google.android.testing.mocking.AndroidMock.anyInt;
|
||||
import static com.google.android.testing.mocking.AndroidMock.capture;
|
||||
import static com.google.android.testing.mocking.AndroidMock.eq;
|
||||
import static com.google.android.testing.mocking.AndroidMock.expect;
|
||||
import static com.google.android.testing.mocking.AndroidMock.isA;
|
||||
import static com.google.android.testing.mocking.AndroidMock.leq;
|
||||
import static com.google.android.testing.mocking.AndroidMock.same;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationFactory;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
|
||||
import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
|
||||
import com.google.android.apps.mytracks.content.TrackDataListener.ProviderState;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.provider.BaseColumns;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.easymock.Capture;
|
||||
import org.easymock.IAnswer;
|
||||
|
||||
/**
|
||||
* Tests for {@link TrackDataHub}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
private static final long TRACK_ID = 42L;
|
||||
private static final int TARGET_POINTS = 50;
|
||||
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
private TrackDataHub hub;
|
||||
private TrackDataListeners listeners;
|
||||
private DataSourcesWrapper dataSources;
|
||||
private SharedPreferences sharedPreferences;
|
||||
private TrackDataListener listener1;
|
||||
private TrackDataListener listener2;
|
||||
private Capture<OnSharedPreferenceChangeListener> preferenceListenerCapture =
|
||||
new Capture<SharedPreferences.OnSharedPreferenceChangeListener>();
|
||||
private MockContext context;
|
||||
private float declination;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
MockContentResolver mockContentResolver = new MockContentResolver();
|
||||
RenamingDelegatingContext targetContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
context = new MockContext(mockContentResolver, targetContext);
|
||||
|
||||
sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
providerUtils = AndroidMock.createMock("providerUtils", MyTracksProviderUtils.class);
|
||||
dataSources = AndroidMock.createNiceMock("dataSources", DataSourcesWrapper.class);
|
||||
|
||||
listeners = new TrackDataListeners();
|
||||
hub = new TrackDataHub(context, listeners, sharedPreferences, providerUtils, TARGET_POINTS) {
|
||||
@Override
|
||||
protected DataSourcesWrapper newDataSources() {
|
||||
return dataSources;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runInListenerThread(Runnable runnable) {
|
||||
// Run everything in the same thread.
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getDeclinationFor(Location location, long timestamp) {
|
||||
return declination;
|
||||
}
|
||||
};
|
||||
|
||||
listener1 = AndroidMock.createStrictMock("listener1", TrackDataListener.class);
|
||||
listener2 = AndroidMock.createStrictMock("listener2", TrackDataListener.class);
|
||||
PreferencesUtils.setLong(context, R.string.recording_track_id_key, TRACK_ID);
|
||||
PreferencesUtils.setLong(context, R.string.selected_track_id_key, TRACK_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
AndroidMock.reset(dataSources);
|
||||
|
||||
// Expect everything to be unregistered.
|
||||
if (preferenceListenerCapture.hasCaptured()) {
|
||||
dataSources.unregisterOnSharedPreferenceChangeListener(preferenceListenerCapture.getValue());
|
||||
}
|
||||
dataSources.removeLocationUpdates(isA(LocationListener.class));
|
||||
dataSources.unregisterSensorListener(isA(SensorEventListener.class));
|
||||
dataSources.unregisterContentObserver(isA(ContentObserver.class));
|
||||
AndroidMock.expectLastCall().times(3);
|
||||
|
||||
AndroidMock.replay(dataSources);
|
||||
|
||||
hub.stop();
|
||||
hub = null;
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testTrackListen() {
|
||||
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||
Track track = new Track();
|
||||
expect(providerUtils.getTrack(TRACK_ID)).andStubReturn(track);
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TracksColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
// Expect the initial loading.
|
||||
// Both listeners (registered before and after start) should get the same data.
|
||||
listener1.onTrackUpdated(track);
|
||||
listener2.onTrackUpdated(track);
|
||||
|
||||
replay();
|
||||
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.TRACK_UPDATES));
|
||||
hub.start();
|
||||
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.TRACK_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
ContentObserver observer = observerCapture.getValue();
|
||||
expect(providerUtils.getTrack(TRACK_ID)).andStubReturn(track);
|
||||
|
||||
// Now expect an update.
|
||||
listener1.onTrackUpdated(track);
|
||||
listener2.onTrackUpdated(track);
|
||||
|
||||
replay();
|
||||
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Unregister one, get another update.
|
||||
expect(providerUtils.getTrack(TRACK_ID)).andStubReturn(track);
|
||||
listener2.onTrackUpdated(track);
|
||||
|
||||
replay();
|
||||
|
||||
hub.unregisterTrackDataListener(listener1);
|
||||
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Unregister the other, expect internal unregistration
|
||||
dataSources.unregisterContentObserver(observer);
|
||||
|
||||
replay();
|
||||
|
||||
hub.unregisterTrackDataListener(listener2);
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
private static class FixedSizeCursorAnswer implements IAnswer<Cursor> {
|
||||
private final int size;
|
||||
|
||||
public FixedSizeCursorAnswer(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor answer() throws Throwable {
|
||||
MatrixCursor cursor = new MatrixCursor(new String[] { BaseColumns._ID });
|
||||
for (long i = 1; i <= size; i++) {
|
||||
cursor.addRow(new Object[] { i });
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FixedSizeLocationIterator implements LocationIterator {
|
||||
private final long startId;
|
||||
private final Location[] locs;
|
||||
private final Set<Integer> splitIndexSet = new HashSet<Integer>();
|
||||
private int currentIdx = -1;
|
||||
|
||||
public FixedSizeLocationIterator(long startId, int size) {
|
||||
this(startId, size, null);
|
||||
}
|
||||
|
||||
public FixedSizeLocationIterator(long startId, int size, int... splitIndices) {
|
||||
this.startId = startId;
|
||||
this.locs = new Location[size];
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Location loc = new Location("gps");
|
||||
loc.setLatitude(-15.0 + i / 1000.0);
|
||||
loc.setLongitude(37 + i / 1000.0);
|
||||
loc.setAltitude(i);
|
||||
|
||||
locs[i] = loc;
|
||||
}
|
||||
|
||||
if (splitIndices != null) {
|
||||
for (int splitIdx : splitIndices) {
|
||||
splitIndexSet.add(splitIdx);
|
||||
|
||||
Location splitLoc = locs[splitIdx];
|
||||
splitLoc.setLatitude(100.0);
|
||||
splitLoc.setLongitude(200.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void expectLocationsDelivered(TrackDataListener listener) {
|
||||
for (int i = 0; i < locs.length; i++) {
|
||||
if (splitIndexSet.contains(i)) {
|
||||
listener.onSegmentSplit();
|
||||
} else {
|
||||
listener.onNewTrackPoint(locs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void expectSampledLocationsDelivered(
|
||||
TrackDataListener listener, int sampleFrequency, boolean includeSampledOut) {
|
||||
for (int i = 0; i < locs.length; i++) {
|
||||
if (splitIndexSet.contains(i)) {
|
||||
listener.onSegmentSplit();
|
||||
} else if (i % sampleFrequency == 0) {
|
||||
listener.onNewTrackPoint(locs[i]);
|
||||
} else if (includeSampledOut) {
|
||||
listener.onSampledOutTrackPoint(locs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return currentIdx < (locs.length - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location next() {
|
||||
currentIdx++;
|
||||
return locs[currentIdx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLocationId() {
|
||||
return startId + currentIdx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
public void testWaypointListen() {
|
||||
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||
|
||||
Waypoint wpt1 = new Waypoint(),
|
||||
wpt2 = new Waypoint(),
|
||||
wpt3 = new Waypoint(),
|
||||
wpt4 = new Waypoint();
|
||||
Location loc = new Location("gps");
|
||||
loc.setLatitude(10.0);
|
||||
loc.setLongitude(8.0);
|
||||
wpt1.setLocation(loc);
|
||||
wpt2.setLocation(loc);
|
||||
wpt3.setLocation(loc);
|
||||
wpt4.setLocation(loc);
|
||||
|
||||
expect(providerUtils.getWaypointsCursor(
|
||||
eq(TRACK_ID), leq(0L), eq(Constants.MAX_DISPLAYED_WAYPOINTS_POINTS)))
|
||||
.andStubAnswer(new FixedSizeCursorAnswer(2));
|
||||
expect(providerUtils.createWaypoint(isA(Cursor.class)))
|
||||
.andReturn(wpt1)
|
||||
.andReturn(wpt2)
|
||||
.andReturn(wpt1)
|
||||
.andReturn(wpt2);
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(WaypointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
// Expect the initial loading.
|
||||
// Both listeners (registered before and after start) should get the same data.
|
||||
listener1.clearWaypoints();
|
||||
listener1.onNewWaypoint(wpt1);
|
||||
listener1.onNewWaypoint(wpt2);
|
||||
listener1.onNewWaypointsDone();
|
||||
listener2.clearWaypoints();
|
||||
listener2.onNewWaypoint(wpt1);
|
||||
listener2.onNewWaypoint(wpt2);
|
||||
listener2.onNewWaypointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.WAYPOINT_UPDATES));
|
||||
hub.start();
|
||||
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.WAYPOINT_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
ContentObserver observer = observerCapture.getValue();
|
||||
|
||||
expect(providerUtils.getWaypointsCursor(
|
||||
eq(TRACK_ID), leq(0L), eq(Constants.MAX_DISPLAYED_WAYPOINTS_POINTS)))
|
||||
.andStubAnswer(new FixedSizeCursorAnswer(3));
|
||||
expect(providerUtils.createWaypoint(isA(Cursor.class)))
|
||||
.andReturn(wpt1)
|
||||
.andReturn(wpt2)
|
||||
.andReturn(wpt3);
|
||||
|
||||
// Now expect an update.
|
||||
listener1.clearWaypoints();
|
||||
listener2.clearWaypoints();
|
||||
listener1.onNewWaypoint(wpt1);
|
||||
listener2.onNewWaypoint(wpt1);
|
||||
listener1.onNewWaypoint(wpt2);
|
||||
listener2.onNewWaypoint(wpt2);
|
||||
listener1.onNewWaypoint(wpt3);
|
||||
listener2.onNewWaypoint(wpt3);
|
||||
listener1.onNewWaypointsDone();
|
||||
listener2.onNewWaypointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Unregister one, get another update.
|
||||
expect(providerUtils.getWaypointsCursor(
|
||||
eq(TRACK_ID), leq(0L), eq(Constants.MAX_DISPLAYED_WAYPOINTS_POINTS)))
|
||||
.andStubAnswer(new FixedSizeCursorAnswer(4));
|
||||
expect(providerUtils.createWaypoint(isA(Cursor.class)))
|
||||
.andReturn(wpt1)
|
||||
.andReturn(wpt2)
|
||||
.andReturn(wpt3)
|
||||
.andReturn(wpt4);
|
||||
|
||||
// Now expect an update.
|
||||
listener2.clearWaypoints();
|
||||
listener2.onNewWaypoint(wpt1);
|
||||
listener2.onNewWaypoint(wpt2);
|
||||
listener2.onNewWaypoint(wpt3);
|
||||
listener2.onNewWaypoint(wpt4);
|
||||
listener2.onNewWaypointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.unregisterTrackDataListener(listener1);
|
||||
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Unregister the other, expect internal unregistration
|
||||
dataSources.unregisterContentObserver(observer);
|
||||
|
||||
replay();
|
||||
|
||||
hub.unregisterTrackDataListener(listener2);
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
public void testPointsListen() {
|
||||
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||
|
||||
listener1.clearTrackPoints();
|
||||
locationIterator.expectLocationsDelivered(listener1);
|
||||
listener1.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.start();
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Register a second listener - it will get the same points as the previous one
|
||||
locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||
|
||||
listener2.clearTrackPoints();
|
||||
locationIterator.expectLocationsDelivered(listener2);
|
||||
listener2.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.start();
|
||||
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Deliver more points - should go to both listeners, without clearing.
|
||||
ContentObserver observer = observerCapture.getValue();
|
||||
|
||||
locationIterator = new FixedSizeLocationIterator(11, 10, 1);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(11L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(20L);
|
||||
|
||||
locationIterator.expectLocationsDelivered(listener1);
|
||||
locationIterator.expectLocationsDelivered(listener2);
|
||||
listener1.onNewTrackPointsDone();
|
||||
listener2.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Unregister listener1, switch tracks to ensure data is cleared/reloaded.
|
||||
locationIterator = new FixedSizeLocationIterator(101, 10);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID + 1), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID + 1)).andReturn(110L);
|
||||
|
||||
listener2.clearTrackPoints();
|
||||
locationIterator.expectLocationsDelivered(listener2);
|
||||
listener2.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.unregisterTrackDataListener(listener1);
|
||||
hub.loadTrack(TRACK_ID + 1);
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
public void testPointsListen_beforeStart() {
|
||||
|
||||
}
|
||||
|
||||
public void testPointsListen_reRegister() {
|
||||
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||
|
||||
listener1.clearTrackPoints();
|
||||
locationIterator.expectLocationsDelivered(listener1);
|
||||
listener1.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.start();
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Unregister
|
||||
ContentObserver observer = observerCapture.getValue();
|
||||
dataSources.unregisterContentObserver(observer);
|
||||
|
||||
replay();
|
||||
|
||||
hub.unregisterTrackDataListener(listener1);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Register again, except only points since unregistered.
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||
|
||||
listener1.clearTrackPoints();
|
||||
locationIterator.expectLocationsDelivered(listener1);
|
||||
listener1.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
public void testPointsListen_reRegisterTrackChanged() {
|
||||
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(10L);
|
||||
|
||||
listener1.clearTrackPoints();
|
||||
locationIterator.expectLocationsDelivered(listener1);
|
||||
listener1.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.start();
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Unregister
|
||||
ContentObserver observer = observerCapture.getValue();
|
||||
dataSources.unregisterContentObserver(observer);
|
||||
|
||||
replay();
|
||||
|
||||
hub.unregisterTrackDataListener(listener1);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Register again after track changed, expect all points.
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
locationIterator = new FixedSizeLocationIterator(1, 10);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID + 1), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID + 1)).andReturn(10L);
|
||||
|
||||
listener1.clearTrackPoints();
|
||||
locationIterator.expectLocationsDelivered(listener1);
|
||||
listener1.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.loadTrack(TRACK_ID + 1);
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
public void testPointsListen_largeTrackSampling() {
|
||||
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 200, 4, 25, 71, 120);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(200L);
|
||||
|
||||
listener1.clearTrackPoints();
|
||||
listener2.clearTrackPoints();
|
||||
locationIterator.expectSampledLocationsDelivered(listener1, 4, false);
|
||||
locationIterator.expectSampledLocationsDelivered(listener2, 4, true);
|
||||
listener1.onNewTrackPointsDone();
|
||||
listener2.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.registerTrackDataListener(listener1,
|
||||
EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||
hub.registerTrackDataListener(listener2,
|
||||
EnumSet.of(ListenerDataType.POINT_UPDATES, ListenerDataType.SAMPLED_OUT_POINT_UPDATES));
|
||||
hub.start();
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
public void testPointsListen_resampling() {
|
||||
Capture<ContentObserver> observerCapture = new Capture<ContentObserver>();
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
// Deliver 30 points (no sampling happens)
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 30, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(30L);
|
||||
|
||||
listener1.clearTrackPoints();
|
||||
locationIterator.expectLocationsDelivered(listener1);
|
||||
listener1.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
hub.start();
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.POINT_UPDATES));
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Now deliver 30 more (incrementally sampled)
|
||||
ContentObserver observer = observerCapture.getValue();
|
||||
locationIterator = new FixedSizeLocationIterator(31, 30);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(31L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(60L);
|
||||
|
||||
locationIterator.expectSampledLocationsDelivered(listener1, 2, false);
|
||||
listener1.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Now another 30 (triggers resampling)
|
||||
locationIterator = new FixedSizeLocationIterator(1, 90);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
|
||||
.andReturn(locationIterator);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(90L);
|
||||
|
||||
listener1.clearTrackPoints();
|
||||
locationIterator.expectSampledLocationsDelivered(listener1, 2, false);
|
||||
listener1.onNewTrackPointsDone();
|
||||
|
||||
replay();
|
||||
|
||||
observer.onChange(false);
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
public void testLocationListen() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void testCompassListen() throws Exception {
|
||||
AndroidMock.resetToDefault(listener1);
|
||||
|
||||
Sensor compass = newSensor();
|
||||
expect(dataSources.getSensor(Sensor.TYPE_ORIENTATION)).andReturn(compass);
|
||||
Capture<SensorEventListener> listenerCapture = new Capture<SensorEventListener>();
|
||||
dataSources.registerSensorListener(capture(listenerCapture), same(compass), anyInt());
|
||||
|
||||
Capture<LocationListener> locationListenerCapture = new Capture<LocationListener>();
|
||||
dataSources.requestLocationUpdates(capture(locationListenerCapture));
|
||||
|
||||
SensorEvent event = newSensorEvent();
|
||||
event.sensor = compass;
|
||||
|
||||
// First, get a dummy heading update.
|
||||
listener1.onCurrentHeadingChanged(0.0);
|
||||
|
||||
// Then, get a heading update without a known location (thus can't calculate declination).
|
||||
listener1.onCurrentHeadingChanged(42.0f);
|
||||
|
||||
// Also expect location updates which are not relevant to us.
|
||||
listener1.onProviderStateChange(isA(ProviderState.class));
|
||||
AndroidMock.expectLastCall().anyTimes();
|
||||
|
||||
replay();
|
||||
|
||||
hub.registerTrackDataListener(listener1,
|
||||
EnumSet.of(ListenerDataType.COMPASS_UPDATES, ListenerDataType.LOCATION_UPDATES));
|
||||
hub.start();
|
||||
|
||||
SensorEventListener sensorListener = listenerCapture.getValue();
|
||||
LocationListener locationListener = locationListenerCapture.getValue();
|
||||
event.values[0] = 42.0f;
|
||||
sensorListener.onSensorChanged(event);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
// Expect the heading update to include declination.
|
||||
listener1.onCurrentHeadingChanged(52.0);
|
||||
|
||||
// Also expect location updates which are not relevant to us.
|
||||
listener1.onProviderStateChange(isA(ProviderState.class));
|
||||
AndroidMock.expectLastCall().anyTimes();
|
||||
listener1.onCurrentLocationChanged(isA(Location.class));
|
||||
AndroidMock.expectLastCall().anyTimes();
|
||||
|
||||
replay();
|
||||
|
||||
// Now try injecting a location update, triggering a declination update.
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10.0);
|
||||
location.setLongitude(20.0);
|
||||
location.setAltitude(30.0);
|
||||
declination = 10.0f;
|
||||
locationListener.onLocationChanged(location);
|
||||
sensorListener.onSensorChanged(event);
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
listener1.onCurrentHeadingChanged(52.0);
|
||||
|
||||
replay();
|
||||
|
||||
// Now try changing the known declination - it should still return the old declination, since
|
||||
// updates only happen sparsely.
|
||||
declination = 20.0f;
|
||||
sensorListener.onSensorChanged(event);
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
private Sensor newSensor() throws Exception {
|
||||
Constructor<Sensor> constructor = Sensor.class.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
return constructor.newInstance();
|
||||
}
|
||||
|
||||
private SensorEvent newSensorEvent() throws Exception {
|
||||
Constructor<SensorEvent> constructor = SensorEvent.class.getDeclaredConstructor(int.class);
|
||||
constructor.setAccessible(true);
|
||||
return constructor.newInstance(3);
|
||||
}
|
||||
|
||||
public void testDisplayPreferencesListen() throws Exception {
|
||||
PreferencesUtils.setBoolean(context, R.string.report_speed_key, true);
|
||||
PreferencesUtils.setBoolean(context, R.string.metric_units_key, true);
|
||||
|
||||
Capture<OnSharedPreferenceChangeListener> listenerCapture =
|
||||
new Capture<OnSharedPreferenceChangeListener>();
|
||||
dataSources.registerOnSharedPreferenceChangeListener(capture(listenerCapture));
|
||||
|
||||
expect(listener1.onUnitsChanged(true)).andReturn(false);
|
||||
expect(listener2.onUnitsChanged(true)).andReturn(false);
|
||||
expect(listener1.onReportSpeedChanged(true)).andReturn(false);
|
||||
expect(listener2.onReportSpeedChanged(true)).andReturn(false);
|
||||
|
||||
replay();
|
||||
|
||||
hub.registerTrackDataListener(listener1, EnumSet.of(ListenerDataType.DISPLAY_PREFERENCES));
|
||||
hub.start();
|
||||
hub.registerTrackDataListener(listener2, EnumSet.of(ListenerDataType.DISPLAY_PREFERENCES));
|
||||
|
||||
verifyAndReset();
|
||||
|
||||
expect(listener1.onReportSpeedChanged(false)).andReturn(false);
|
||||
expect(listener2.onReportSpeedChanged(false)).andReturn(false);
|
||||
|
||||
replay();
|
||||
|
||||
PreferencesUtils.setBoolean(context, R.string.report_speed_key, false);
|
||||
OnSharedPreferenceChangeListener listener = listenerCapture.getValue();
|
||||
listener.onSharedPreferenceChanged(
|
||||
sharedPreferences, PreferencesUtils.getKey(context, R.string.report_speed_key));
|
||||
|
||||
AndroidMock.verify(dataSources, providerUtils, listener1, listener2);
|
||||
AndroidMock.reset(dataSources, providerUtils, listener1, listener2);
|
||||
|
||||
expect(listener1.onUnitsChanged(false)).andReturn(false);
|
||||
expect(listener2.onUnitsChanged(false)).andReturn(false);
|
||||
|
||||
replay();
|
||||
|
||||
PreferencesUtils.setBoolean(context, R.string.metric_units_key, false);
|
||||
listener.onSharedPreferenceChanged(
|
||||
sharedPreferences, PreferencesUtils.getKey(context, R.string.metric_units_key));
|
||||
|
||||
verifyAndReset();
|
||||
}
|
||||
|
||||
private void expectStart() {
|
||||
dataSources.registerOnSharedPreferenceChangeListener(capture(preferenceListenerCapture));
|
||||
}
|
||||
|
||||
private void replay() {
|
||||
AndroidMock.replay(dataSources, providerUtils, listener1, listener2);
|
||||
}
|
||||
|
||||
private void verifyAndReset() {
|
||||
AndroidMock.verify(listener1, listener2, dataSources, providerUtils);
|
||||
AndroidMock.reset(listener1, listener2, dataSources, providerUtils);
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest.WaypointType;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests for the WaypointCreationRequest class.
|
||||
* {@link WaypointCreationRequest}
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class WaypointCreationRequestTest extends AndroidTestCase {
|
||||
|
||||
public void testTypeParceling() {
|
||||
WaypointCreationRequest original = WaypointCreationRequest.DEFAULT_WAYPOINT;
|
||||
Parcel p = Parcel.obtain();
|
||||
original.writeToParcel(p, 0);
|
||||
p.setDataPosition(0);
|
||||
WaypointCreationRequest copy = WaypointCreationRequest.CREATOR.createFromParcel(p);
|
||||
assertEquals(original.getType(), copy.getType());
|
||||
assertFalse(copy.isTrackStatistics());
|
||||
assertNull(copy.getName());
|
||||
assertNull(copy.getDescription());
|
||||
assertNull(copy.getIconUrl());
|
||||
}
|
||||
|
||||
public void testAllAttributesParceling() {
|
||||
WaypointCreationRequest original = new WaypointCreationRequest(
|
||||
WaypointType.WAYPOINT, false, "name", "category", "description", "img.png");
|
||||
Parcel p = Parcel.obtain();
|
||||
original.writeToParcel(p, 0);
|
||||
p.setDataPosition(0);
|
||||
WaypointCreationRequest copy = WaypointCreationRequest.CREATOR.createFromParcel(p);
|
||||
assertEquals(original.getType(), copy.getType());
|
||||
assertFalse(copy.isTrackStatistics());
|
||||
assertEquals("name", copy.getName());
|
||||
assertEquals("category", copy.getCategory());
|
||||
assertEquals("description", copy.getDescription());
|
||||
assertEquals("img.png", copy.getIconUrl());
|
||||
}
|
||||
}
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Instrumentation;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.KeyEvent;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests creating a track with markers, and editing and sending send a track.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class CreateAndSendTrackTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
|
||||
|
||||
private static final String WAYPOINT_NAME = "testWaypoint";
|
||||
private Instrumentation instrumentation;
|
||||
private TrackListActivity activityMyTracks;
|
||||
|
||||
@TargetApi(8)
|
||||
public CreateAndSendTrackTest() {
|
||||
super(TrackListActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
activityMyTracks = getActivity();
|
||||
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not check any service and try to send to google.
|
||||
*/
|
||||
public void testCreateAndSendTrack_notSend() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, false);
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_send_google), true);
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.send_google_title));
|
||||
EndToEndTestUtils.rotateCurrentActivity();
|
||||
instrumentation.waitForIdleSync();
|
||||
|
||||
ArrayList<CheckBox> checkBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
|
||||
for (int i = 0; i < checkBoxs.size(); i++) {
|
||||
if (checkBoxs.get(i).isChecked()) {
|
||||
EndToEndTestUtils.SOLO.clickOnCheckBox(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (checkBoxs.size() < 3) {
|
||||
EndToEndTestUtils.SOLO.scrollDown();
|
||||
checkBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
|
||||
for (int i = 0; i < checkBoxs.size(); i++) {
|
||||
if (checkBoxs.get(i).isChecked()) {
|
||||
EndToEndTestUtils.SOLO.clickOnCheckBox(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.send_google_send_now));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.send_google_no_service_selected)));
|
||||
// Stop here for do not really send.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all services and send to google.
|
||||
*/
|
||||
public void testCreateAndSendTrack_Send() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, false);
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_send_google), true);
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.send_google_title));
|
||||
ArrayList<CheckBox> checkBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
|
||||
for (int i = 0; i < checkBoxs.size(); i++) {
|
||||
if (!checkBoxs.get(i).isChecked()) {
|
||||
EndToEndTestUtils.SOLO.clickOnCheckBox(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (checkBoxs.size() < 3) {
|
||||
EndToEndTestUtils.SOLO.scrollDown();
|
||||
checkBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
|
||||
for (int i = 0; i < checkBoxs.size(); i++) {
|
||||
if (!checkBoxs.get(i).isChecked()) {
|
||||
EndToEndTestUtils.SOLO.clickOnCheckBox(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.send_google_send_now));
|
||||
|
||||
// If no account is binded with this device.
|
||||
if (EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.send_google_no_account_title), 1, 10000)) {
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
} else {
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.generic_progress_title)));
|
||||
// Waiting the send is finish.
|
||||
while (EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.generic_progress_title), 1, 500)) {
|
||||
}
|
||||
|
||||
// For we not sure the send will be successful, just check whether the result dialog is display.
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.share_track_share_url)));
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests editing a track.
|
||||
*/
|
||||
public void testEditTrack() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, false);
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_edit), true);
|
||||
|
||||
String newTrackName = EndToEndTestUtils.TRACK_NAME_PREFIX + "_new" + System.currentTimeMillis();
|
||||
String newType = "type" + newTrackName;
|
||||
String newDesc = "desc" + newTrackName;
|
||||
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.generic_save));
|
||||
sendKeys(KeyEvent.KEYCODE_DEL);
|
||||
ArrayList<EditText> editTexts = EndToEndTestUtils.SOLO.getCurrentEditTexts();
|
||||
|
||||
EndToEndTestUtils.SOLO.enterText(editTexts.get(0), newTrackName);
|
||||
EndToEndTestUtils.SOLO.enterText(editTexts.get(1), newType);
|
||||
// In landscape, there are only two visible edit texts.
|
||||
if (editTexts.size() > 2) {
|
||||
EndToEndTestUtils.SOLO.enterText(editTexts.get(2), newDesc);
|
||||
} else {
|
||||
EndToEndTestUtils.SOLO.scrollDown();
|
||||
editTexts = EndToEndTestUtils.SOLO.getCurrentEditTexts();
|
||||
EndToEndTestUtils.SOLO.enterText(editTexts.get(editTexts.size() - 1), newDesc);
|
||||
}
|
||||
EndToEndTestUtils.SOLO.clickOnButton(activityMyTracks.getString(R.string.generic_save));
|
||||
instrumentation.waitForIdleSync();
|
||||
// Go back to track list.
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
instrumentation.waitForIdleSync();
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(newTrackName));
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(newDesc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates one track with a two locations, a way point and a statistics point.
|
||||
*/
|
||||
public void testCreateTrackWithMarkers() {
|
||||
EndToEndTestUtils.startRecording();
|
||||
instrumentation.waitForIdleSync();
|
||||
// Send Gps before send marker.
|
||||
EndToEndTestUtils.sendGps(2);
|
||||
if (EndToEndTestUtils.hasActionBar) {
|
||||
// Check the title is Recording.
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(activityMyTracks
|
||||
.getString(R.string.icon_recording)));
|
||||
}
|
||||
createWaypoint();
|
||||
EndToEndTestUtils.sendGps(2);
|
||||
// Back to tracks list.
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
EndToEndTestUtils.stopRecording(false);
|
||||
EndToEndTestUtils.trackName = EndToEndTestUtils.TRACK_NAME_PREFIX + System.currentTimeMillis();
|
||||
EndToEndTestUtils.SOLO.enterText(0, EndToEndTestUtils.trackName);
|
||||
if(!EndToEndTestUtils.isEmulator) {
|
||||
// Close soft keyboard.
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
}
|
||||
EndToEndTestUtils.SOLO.clickOnButton(activityMyTracks.getString(R.string.generic_save));
|
||||
|
||||
instrumentation.waitForIdleSync();
|
||||
// Check the new track
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.trackName, 1, 5000, true,
|
||||
false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the display of track start time. Use relative time (x mins ago) for
|
||||
* the start time if it is within the past week. But only show the start time
|
||||
* if it is different from the track name.
|
||||
*/
|
||||
public void testTrackStartTime() {
|
||||
// Delete all track first.
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_delete_all), true);
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
|
||||
// Reset all settings.
|
||||
EndToEndTestUtils.resetAllSettings(activityMyTracks, false);
|
||||
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.track_list_empty_message)));
|
||||
// Test should not show relative time.
|
||||
EndToEndTestUtils.startRecording();
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.stopRecording(false);
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.generic_save));
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
instrumentation.waitForIdleSync();
|
||||
assertFalse(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.RELATIVE_STARTTIME_POSTFIX, 1, 5000));
|
||||
|
||||
// Test should show relative time for createSimpleTrack would save a track
|
||||
// name that is different with the start time.
|
||||
EndToEndTestUtils.createSimpleTrack(2);
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(EndToEndTestUtils.RELATIVE_STARTTIME_POSTFIX, 1, 5000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a way point and a split maker during track recording.
|
||||
*/
|
||||
private void createWaypoint() {
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_markers), true);
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.marker_list_empty_message));
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_insert_marker), true);
|
||||
// Rotate when show insert page.
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
EndToEndTestUtils.SOLO.enterText(0, WAYPOINT_NAME);
|
||||
if(!EndToEndTestUtils.isEmulator) {
|
||||
// Close soft keyboard.
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
}
|
||||
EndToEndTestUtils.SOLO.clickOnButton(activityMyTracks.getString(R.string.generic_add));
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(WAYPOINT_NAME));
|
||||
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
EndToEndTestUtils.SOLO.finishOpenedActivities();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Instrumentation;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.widget.ListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests the delete of MyTracks.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class DeleteTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
|
||||
|
||||
private Instrumentation instrumentation;
|
||||
private TrackListActivity activityMyTracks;
|
||||
|
||||
@TargetApi(8)
|
||||
public DeleteTest() {
|
||||
super(TrackListActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
activityMyTracks = getActivity();
|
||||
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all tracks.
|
||||
*/
|
||||
public void testDeleteAllTracks() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
// There is at least one track.
|
||||
ArrayList<ListView> trackListView = EndToEndTestUtils.SOLO.getCurrentListViews();
|
||||
assertTrue(trackListView.size() > 0);
|
||||
assertTrue(trackListView.get(0).getCount() > 0);
|
||||
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_delete_all), true);
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
// There is no track now.
|
||||
trackListView = EndToEndTestUtils.SOLO.getCurrentListViews();
|
||||
assertEquals(0, trackListView.get(0).getCount());
|
||||
// Export when there is no track.
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_save_all), true);
|
||||
EndToEndTestUtils.SOLO
|
||||
.clickOnText(String.format(activityMyTracks.getString(R.string.menu_save_format),
|
||||
EndToEndTestUtils.GPX.toUpperCase()));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.sd_card_save_error_no_track)));
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes only one track.
|
||||
*/
|
||||
public void testDeleteSingleTrack() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
// Get the number of track( or tracks)
|
||||
ArrayList<ListView> trackListView = EndToEndTestUtils.SOLO.getCurrentListViews();
|
||||
int trackNumberOld = trackListView.get(0).getCount();
|
||||
|
||||
EndToEndTestUtils.SOLO.clickOnView(trackListView.get(0).getChildAt(0));
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_delete), true);
|
||||
EndToEndTestUtils
|
||||
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
trackListView = EndToEndTestUtils.SOLO.getCurrentListViews();
|
||||
int trackNumberNew = trackListView.get(0).getCount();
|
||||
assertEquals(trackNumberOld - 1, trackNumberNew);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a track which is under recording.
|
||||
*/
|
||||
public void testDeleteOneTrackUnderRecording() {
|
||||
EndToEndTestUtils.startRecording();
|
||||
instrumentation.waitForIdleSync();
|
||||
assertTrue(EndToEndTestUtils.findMenuItem(
|
||||
activityMyTracks.getString(R.string.menu_stop_recording), false));
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_delete), true);
|
||||
EndToEndTestUtils
|
||||
.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
assertTrue(EndToEndTestUtils.findMenuItem(
|
||||
activityMyTracks.getString(R.string.menu_record_track), false));
|
||||
instrumentation.waitForIdleSync();
|
||||
assertTrue(EndToEndTestUtils.findMenuItem(
|
||||
activityMyTracks.getString(R.string.menu_record_track), false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
EndToEndTestUtils.SOLO.finishOpenedActivities();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
}
|
||||
+603
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.ChartView;
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
import com.jayway.android.robotium.solo.Solo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Instrumentation;
|
||||
import android.content.res.Configuration;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Provides utilities to smoke test.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class EndToEndTestUtils {
|
||||
private static final String ANDROID_LOCAL_IP = "10.0.2.2";
|
||||
// usually 5554.
|
||||
private static final int ANDROID_LOCAL_PORT = 5554;
|
||||
|
||||
private static final int ORIENTATION_PORTRAIT = 1;
|
||||
private static final int ORIENTATION_LANDSCAPE = 0;
|
||||
// Pause 200ms between each send.
|
||||
static int PAUSE = 200;
|
||||
private static final float START_LONGITUDE = 51;
|
||||
private static final float START_LATITUDE = -1.3f;
|
||||
private static final float DELTA_LONGITUDE = 0.0005f;
|
||||
private static final float DELTA_LADITUDE = 0.0005f;
|
||||
|
||||
private static final String MOREOPTION_CLASSNAME = "com.android.internal.view.menu.ActionMenuPresenter$OverflowMenuButton";
|
||||
|
||||
static final String TRACK_NAME_PREFIX = "testTrackName";
|
||||
static final String GPX = "gpx";
|
||||
static final String KML = "kml";
|
||||
static final String CSV = "csv";
|
||||
static final String TCX = "tcx";
|
||||
static final String BACKUPS = "backups";
|
||||
static final String MENU_MORE = "More";
|
||||
static String trackName;
|
||||
|
||||
// Following is some check strings in English and Chinese
|
||||
private static final HashMap<String, String> RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL = new HashMap<String, String>();
|
||||
private static final HashMap<String, String> VIEW_MODE_ENGLISH_MULTILINGUAL = new HashMap<String, String>();
|
||||
public static String RELATIVE_STARTTIME_POSTFIX = "";
|
||||
public static String VIEW_MODE = "";
|
||||
|
||||
static Solo SOLO;
|
||||
static Instrumentation instrumentation;
|
||||
static TrackListActivity activityMytracks;
|
||||
// Check whether the UI has an action bar which is related with the version of
|
||||
// Android OS.
|
||||
static boolean hasActionBar = false;
|
||||
static boolean isEmulator = true;
|
||||
static boolean isCheckedFirstLaunch = false;
|
||||
|
||||
private EndToEndTestUtils() {}
|
||||
|
||||
private static void checkLanguage() {
|
||||
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("es", "mins ago");
|
||||
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("de", "Minuten");
|
||||
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("fr", "minute");
|
||||
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("ar", "دقيقة");
|
||||
RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.put("zh", "分钟前");
|
||||
|
||||
VIEW_MODE_ENGLISH_MULTILINGUAL.put("es", "mode");
|
||||
VIEW_MODE_ENGLISH_MULTILINGUAL.put("de", "modus");
|
||||
VIEW_MODE_ENGLISH_MULTILINGUAL.put("fr", "Mode");
|
||||
VIEW_MODE_ENGLISH_MULTILINGUAL.put("ar", "وضع");
|
||||
VIEW_MODE_ENGLISH_MULTILINGUAL.put("zh", "模式");
|
||||
|
||||
|
||||
// Check the language, test in Chinese or English.
|
||||
String deviceLanguage = instrumentation.getContext().getResources().getConfiguration().locale.getLanguage();
|
||||
if (RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.get(deviceLanguage) != null) {
|
||||
RELATIVE_STARTTIME_POSTFIX = RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.get(deviceLanguage);
|
||||
VIEW_MODE = VIEW_MODE_ENGLISH_MULTILINGUAL.get(deviceLanguage);
|
||||
} else {
|
||||
RELATIVE_STARTTIME_POSTFIX = RELATIVE_STARTTIME_POSTFIX_MULTILINGUAL.get("es");
|
||||
VIEW_MODE = VIEW_MODE_ENGLISH_MULTILINGUAL.get("es");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends Gps data to emulator.
|
||||
*
|
||||
* @param number send times
|
||||
*/
|
||||
public static void sendGps(int number) {
|
||||
if (number < 1) {
|
||||
return;
|
||||
}
|
||||
// If it's a real device, does not send simulated GPS signal.
|
||||
if (!isEmulator) {
|
||||
return;
|
||||
}
|
||||
|
||||
PrintStream out = null;
|
||||
Socket socket = null;
|
||||
try {
|
||||
socket = new Socket(ANDROID_LOCAL_IP, ANDROID_LOCAL_PORT);
|
||||
out = new PrintStream(socket.getOutputStream());
|
||||
float longitude = START_LONGITUDE;
|
||||
float latitude = START_LATITUDE;
|
||||
for (int i = 0; i < number; i++) {
|
||||
Thread.sleep(PAUSE);
|
||||
out.println("geo fix " + latitude + " " + longitude);
|
||||
longitude += DELTA_LONGITUDE;
|
||||
latitude += DELTA_LADITUDE;
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
System.exit(-1);
|
||||
} catch (IOException e) {
|
||||
System.exit(-1);
|
||||
} catch (InterruptedException e) {
|
||||
System.exit(-1);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the status whether the test is run on an emulator or not.
|
||||
*/
|
||||
static void setIsEmulator() {
|
||||
isEmulator = android.os.Build.MODEL.equals("google_sdk");
|
||||
}
|
||||
|
||||
/**
|
||||
* A setup for all end-to-end tests.
|
||||
*
|
||||
* @param instrumentation the instrumentation is used for test
|
||||
* @param activityMyTracks the startup activity
|
||||
*/
|
||||
static void setupForAllTest(Instrumentation instrumentation, TrackListActivity activityMyTracks) {
|
||||
setIsEmulator();
|
||||
EndToEndTestUtils.instrumentation = instrumentation;
|
||||
EndToEndTestUtils.activityMytracks = activityMyTracks;
|
||||
EndToEndTestUtils.SOLO = new Solo(EndToEndTestUtils.instrumentation,
|
||||
EndToEndTestUtils.activityMytracks);
|
||||
// Check if open MyTracks first time after install. If so, there would be a
|
||||
// welcome view with accept buttons. And makes sure only check once.
|
||||
if (!EndToEndTestUtils.isCheckedFirstLaunch) {
|
||||
if ((EndToEndTestUtils.getButtonOnScreen(EndToEndTestUtils.activityMytracks
|
||||
.getString(R.string.eula_accept), false, false) != null)) {
|
||||
EndToEndTestUtils.verifyFirstLaunch();
|
||||
} else if (EndToEndTestUtils.SOLO.waitForText(
|
||||
// After reset setting, welcome page will show again.
|
||||
activityMytracks.getString(R.string.welcome_title), 0, 500)) {
|
||||
resetPreferredUnits();
|
||||
}
|
||||
checkLanguage();
|
||||
EndToEndTestUtils.isCheckedFirstLaunch = true;
|
||||
EndToEndTestUtils.setHasActionBar();
|
||||
} else if (EndToEndTestUtils.SOLO.waitForText(
|
||||
// After reset setting, welcome page will show again.
|
||||
activityMytracks.getString(R.string.welcome_title), 0, 500)) {
|
||||
resetPreferredUnits();
|
||||
}
|
||||
|
||||
// Check whether is under recording. If previous test failed, the recording
|
||||
// may not be recording.
|
||||
if (isUnderRecording()) {
|
||||
stopRecording(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if need reset preferred units.
|
||||
*/
|
||||
private static void resetPreferredUnits() {
|
||||
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
|
||||
SOLO.waitForText(activityMytracks.getString(R.string.settings_stats_units_title));
|
||||
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rotates the given activity.
|
||||
*
|
||||
* @param activity a given activity
|
||||
*/
|
||||
static void rotateActivity(Activity activity) {
|
||||
activity
|
||||
.setRequestedOrientation(activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? ORIENTATION_LANDSCAPE
|
||||
: ORIENTATION_PORTRAIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts terms and configures units.
|
||||
*/
|
||||
static void verifyFirstLaunch() {
|
||||
getButtonOnScreen(activityMytracks.getString(R.string.eula_accept), true, true);
|
||||
if (SOLO.waitForText(activityMytracks.getString(R.string.generic_ok))) {
|
||||
// Click for welcome.
|
||||
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
|
||||
// Click for choose units.
|
||||
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a simple track which can be used by subsequent test. This method
|
||||
* will save a customized track name.
|
||||
*
|
||||
* @param numberOfGpsData number of simulated Gps data
|
||||
*/
|
||||
static void createSimpleTrack(int numberOfGpsData) {
|
||||
startRecording();
|
||||
EndToEndTestUtils.sendGps(numberOfGpsData);
|
||||
instrumentation.waitForIdleSync();
|
||||
stopRecording(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is no track in track list. For some tests need at least one
|
||||
* track, the method can save time to create a new track.
|
||||
*
|
||||
* @param isClick if not empty, true means click any track
|
||||
* @return return true if the track list is empty
|
||||
*/
|
||||
static boolean isTrackListEmpty(boolean isClick) {
|
||||
int trackNumber = SOLO.getCurrentListViews().get(0).getCount();
|
||||
if(trackNumber <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
View oneTrack = SOLO.getCurrentListViews().get(0).getChildAt(0);
|
||||
trackName = (String) ((TextView) oneTrack.findViewById(R.id.list_item_name)).getText();
|
||||
if (isClick) {
|
||||
SOLO.scrollUp();
|
||||
SOLO.clickOnView(oneTrack);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new track if the track is empty.
|
||||
*
|
||||
* @param gpsNumber the number of gps signals
|
||||
* @param showTrackList whether stay on track list activity or track detail
|
||||
* activity
|
||||
*/
|
||||
static void createTrackIfEmpty(int gpsNumber, boolean showTrackList) {
|
||||
if (EndToEndTestUtils.isTrackListEmpty(!showTrackList)) {
|
||||
// Create a simple track.
|
||||
EndToEndTestUtils.createSimpleTrack(gpsNumber);
|
||||
if (showTrackList) {
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts recoding track.
|
||||
*/
|
||||
static void startRecording() {
|
||||
if (hasActionBar) {
|
||||
Button startButton = getButtonOnScreen(activityMytracks.getString(R.string.menu_record_track), false, false);
|
||||
// In case a track is recording.
|
||||
if (startButton == null) {
|
||||
stopRecording(true);
|
||||
startButton = getButtonOnScreen(activityMytracks.getString(R.string.menu_record_track), false, false);
|
||||
}
|
||||
SOLO.clickOnView(startButton);
|
||||
} else {
|
||||
showMoreMenuItem();
|
||||
if (!SOLO.searchText(activityMytracks.getString(R.string.menu_record_track))) {
|
||||
// Check if in TrackDetailActivity.
|
||||
if (SOLO.searchText(activityMytracks.getString(R.string.menu_play))) {
|
||||
SOLO.goBack();
|
||||
} else {
|
||||
// In case a track is recording.
|
||||
stopRecording(true);
|
||||
showMoreMenuItem();
|
||||
}
|
||||
}
|
||||
instrumentation.waitForIdleSync();
|
||||
SOLO.clickOnText(activityMytracks.getString(R.string.menu_record_track));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the MyTracks is under recording.
|
||||
*
|
||||
* @return true if it is under recording.
|
||||
*/
|
||||
static boolean isUnderRecording() {
|
||||
if (hasActionBar) {
|
||||
return getButtonOnScreen(activityMytracks
|
||||
.getString(R.string.menu_record_track), false, false) == null;
|
||||
}
|
||||
showMoreMenuItem();
|
||||
if (SOLO.searchText(activityMytracks.getString(R.string.menu_record_track))
|
||||
|| SOLO.searchText(activityMytracks.getString(R.string.menu_play))) {
|
||||
SOLO.goBack();
|
||||
return false;
|
||||
}
|
||||
SOLO.goBack();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops recoding track.
|
||||
*
|
||||
* @param isSave true means should save this track
|
||||
*/
|
||||
static void stopRecording(boolean isSave) {
|
||||
if (hasActionBar) {
|
||||
getButtonOnScreen(activityMytracks.getString(R.string.menu_stop_recording), false, true);
|
||||
} else {
|
||||
showMoreMenuItem();
|
||||
instrumentation.waitForIdleSync();
|
||||
SOLO.clickOnText(activityMytracks.getString(R.string.menu_stop_recording));
|
||||
}
|
||||
if (isSave) {
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMytracks.getString(R.string.generic_save), 1, 5000);
|
||||
// Make every track name is unique to make sure every check can be
|
||||
// trusted.
|
||||
EndToEndTestUtils.trackName = EndToEndTestUtils.TRACK_NAME_PREFIX
|
||||
+ System.currentTimeMillis();
|
||||
SOLO.enterText(0, trackName);
|
||||
if(!EndToEndTestUtils.isEmulator) {
|
||||
// Close soft keyboard.
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
}
|
||||
SOLO.clickLongOnText(activityMytracks.getString(R.string.generic_save));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a kind of track in MyTracks folder.
|
||||
*
|
||||
* @param trackKind the kind of track
|
||||
*/
|
||||
static void deleteExportedFiles(String trackKind) {
|
||||
File[] allFiles = (new File(FileUtils.buildExternalDirectoryPath(trackKind.toLowerCase())))
|
||||
.listFiles();
|
||||
if (allFiles != null) {
|
||||
for (File oneFile : allFiles) {
|
||||
oneFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a kind of exported files.
|
||||
*
|
||||
* @param trackKind the kind of track
|
||||
* @return files array of such kind of exported tracks
|
||||
*/
|
||||
static File[] getExportedFiles(final String trackKind) {
|
||||
String filePath = FileUtils.buildExternalDirectoryPath(trackKind);
|
||||
FileFilter filter = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.getName().indexOf("." + trackKind) > 0;
|
||||
}
|
||||
};
|
||||
return (new File(filePath)).listFiles(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a track to a kind of file in SD card.
|
||||
*
|
||||
* @param trackKind the kind of track
|
||||
*/
|
||||
static void saveTrackToSdCard(String trackKind) {
|
||||
deleteExportedFiles(trackKind);
|
||||
instrumentation.waitForIdleSync();
|
||||
findMenuItem(activityMytracks.getString(R.string.menu_save), true);
|
||||
instrumentation.waitForIdleSync();
|
||||
SOLO.clickOnText(trackKind.toUpperCase());
|
||||
// rotateAllActivities();
|
||||
SOLO.waitForText(activityMytracks.getString(R.string.generic_success_title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a button is existed in the screen.
|
||||
*
|
||||
* @param buttonName the name string of the button
|
||||
* @param isWait whether wait the text
|
||||
* @param isClick whether click the button if find it
|
||||
* @return the button to search, and null means can not find the button
|
||||
*/
|
||||
static Button getButtonOnScreen(String buttonName, boolean isWait,boolean isClick) {
|
||||
instrumentation.waitForIdleSync();
|
||||
if (isWait) {
|
||||
SOLO.waitForText(buttonName);
|
||||
}
|
||||
ArrayList<Button> currentButtons = SOLO.getCurrentButtons();
|
||||
for (Button button : currentButtons) {
|
||||
String title = (String) button.getText();
|
||||
if (title.equalsIgnoreCase(buttonName)) {
|
||||
if(isClick) {
|
||||
SOLO.clickOnView(button);
|
||||
}
|
||||
return button;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an action bar is shown.
|
||||
*
|
||||
* @return false means can not check failed.
|
||||
*/
|
||||
static boolean setHasActionBar() {
|
||||
instrumentation.waitForIdleSync();
|
||||
// If can find record button without pressing Menu, it should be an action
|
||||
// bar.
|
||||
Button startButton = getButtonOnScreen(activityMytracks.getString(R.string.menu_record_track), false, false);
|
||||
Button stopButton = getButtonOnScreen(activityMytracks.getString(R.string.menu_stop_recording), false, false);
|
||||
if (startButton != null || stopButton != null) {
|
||||
hasActionBar = true;
|
||||
} else {
|
||||
showMoreMenuItem();
|
||||
if (SOLO.searchText(activityMytracks.getString(R.string.menu_record_track))
|
||||
|| SOLO.searchText(activityMytracks.getString(R.string.menu_stop_recording))) {
|
||||
hasActionBar = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
SOLO.goBack();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the current activity.
|
||||
*/
|
||||
static void rotateCurrentActivity() {
|
||||
EndToEndTestUtils.rotateActivity(SOLO.getCurrentActivity());
|
||||
instrumentation.waitForIdleSync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates all activities.
|
||||
*/
|
||||
static void rotateAllActivities() {
|
||||
ArrayList<Activity> allActivities = SOLO.getAllOpenedActivities();
|
||||
for (Activity activity : allActivities) {
|
||||
EndToEndTestUtils.rotateActivity(activity);
|
||||
}
|
||||
|
||||
instrumentation.waitForIdleSync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an item in the menu with the option to click the item.
|
||||
*
|
||||
* @param menuName the name of item
|
||||
* @param click true means need click this menu
|
||||
* @return true if find this menu
|
||||
*/
|
||||
static boolean findMenuItem(String menuName, boolean click) {
|
||||
boolean findResult = false;
|
||||
|
||||
// Firstly find in action bar.
|
||||
Button button = getButtonOnScreen(menuName, false, false);
|
||||
if (button != null) {
|
||||
findResult = true;
|
||||
if (click) {
|
||||
SOLO.clickOnView(button);
|
||||
instrumentation.waitForIdleSync();
|
||||
}
|
||||
return findResult;
|
||||
}
|
||||
|
||||
showMoreMenuItem();
|
||||
if (SOLO.searchText(menuName)) {
|
||||
findResult = true;
|
||||
} else if (SOLO.searchText(MENU_MORE)) {
|
||||
SOLO.clickOnText(MENU_MORE);
|
||||
findResult = SOLO.searchText(menuName);
|
||||
}
|
||||
|
||||
if (findResult && click) {
|
||||
SOLO.clickOnText(menuName);
|
||||
instrumentation.waitForIdleSync();
|
||||
} else {
|
||||
SOLO.goBack();
|
||||
}
|
||||
return findResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get more menu items operation is different for different Android OS.
|
||||
*/
|
||||
public static void showMoreMenuItem() {
|
||||
if (hasActionBar) {
|
||||
View moreButton = getMoreOptionView();
|
||||
if (moreButton != null) {
|
||||
SOLO.clickOnView(moreButton);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SOLO.sendKey(KeyEvent.KEYCODE_MENU);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the more option menu. It should match following conditions:
|
||||
* <ul>
|
||||
* <li>The view extends ImageButton.</li>
|
||||
* <li>The view name equals {@link EndToEndTestUtils#MOREOPTION_CLASSNAME}.</li>
|
||||
* </ul>
|
||||
* @return the more option view. Null means can not find it.
|
||||
*/
|
||||
private static View getMoreOptionView() {
|
||||
ArrayList<View> allViews = SOLO.getViews();
|
||||
for (View view : allViews) {
|
||||
if (view instanceof ImageButton && view.getClass().getName().equals(MOREOPTION_CLASSNAME)) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a text view with specified test in a view.
|
||||
*
|
||||
* @param findText text to find
|
||||
* @param parent which text view in in
|
||||
* @return the text view, null means can not find it
|
||||
*/
|
||||
static TextView findTextView(String findText, View parent) {
|
||||
ArrayList<TextView> textViews = EndToEndTestUtils.SOLO.getCurrentTextViews(parent);
|
||||
for (TextView textView : textViews) {
|
||||
String text = (String) textView.getText();
|
||||
if (textView.isShown() && text.endsWith(findText)) {
|
||||
return textView;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ChartView.
|
||||
*
|
||||
* @return the ChartView or null if not find
|
||||
*/
|
||||
static ChartView getChartView() {
|
||||
ArrayList<View> views = EndToEndTestUtils.SOLO.getViews();
|
||||
for (View view : views) {
|
||||
if (view instanceof ChartView) {
|
||||
return (ChartView) view;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all settings of MyTracks.
|
||||
*
|
||||
* @param activityMyTracks current activity
|
||||
* @param keepInSettingList whether keep in setting list or not
|
||||
*/
|
||||
public static void resetAllSettings(Activity activityMyTracks, boolean keepInSettingList) {
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
|
||||
SOLO.waitForText(activityMyTracks.getString(R.string.settings_reset));
|
||||
SOLO.clickOnText(activityMyTracks.getString(R.string.settings_reset));
|
||||
getButtonOnScreen(activityMytracks.getString(R.string.generic_ok), true, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
if (!keepInSettingList) {
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Instrumentation;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Tests the import and export of MyTracks.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class ExportAndImportTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
|
||||
|
||||
private Instrumentation instrumentation;
|
||||
private TrackListActivity activityMyTracks;
|
||||
|
||||
@TargetApi(8)
|
||||
public ExportAndImportTest() {
|
||||
super(TrackListActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
activityMyTracks = getActivity();
|
||||
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests export and import tracks.
|
||||
* <ul>
|
||||
* <li>Create two tracks, one of them is empty(Have no Gps data).</li>
|
||||
* <li>Tests import when there is no track file.</li>
|
||||
* <li>Tests export tracks to Gpx files.</li>
|
||||
* <li>Tests import files to tracks.</li>
|
||||
* <li>Tests export tracks to Kml files.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void testExportAndImportTracks() {
|
||||
// Create a new track with 3 gps data.
|
||||
EndToEndTestUtils.createTrackIfEmpty(3, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
// Create a empty track.
|
||||
EndToEndTestUtils.createSimpleTrack(0);
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
instrumentation.waitForIdleSync();
|
||||
// Delete all exported gpx and kml tracks.
|
||||
EndToEndTestUtils.deleteExportedFiles(EndToEndTestUtils.GPX);
|
||||
EndToEndTestUtils.deleteExportedFiles(EndToEndTestUtils.KML);
|
||||
int gpxFilesNumber = 0;
|
||||
File[] allGpxFiles = EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX);
|
||||
// For the first export, there is no MyTracks folder.
|
||||
if (allGpxFiles != null) {
|
||||
gpxFilesNumber = EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length;
|
||||
}
|
||||
|
||||
// Get track number in current track list of MyTracks.
|
||||
int trackNumber = EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount();
|
||||
|
||||
// No file to imported.
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_import), true);
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.sd_card_import_error_no_file,
|
||||
FileUtils.buildExternalDirectoryPath(EndToEndTestUtils.GPX)));
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
|
||||
// Click to export tracks(At least one track) to Gpx files.
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_save_all), true);
|
||||
EndToEndTestUtils.SOLO
|
||||
.clickOnText(String.format(activityMyTracks.getString(R.string.menu_save_format),
|
||||
EndToEndTestUtils.GPX.toUpperCase()));
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.sd_card_save_success));
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
// Check export file.
|
||||
assertEquals(gpxFilesNumber + trackNumber,
|
||||
EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length);
|
||||
instrumentation.waitForIdleSync();
|
||||
|
||||
// Click to import track.
|
||||
gpxFilesNumber = EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length;
|
||||
trackNumber = EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount();
|
||||
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_import), true);
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
// Wait for the prefix of import success string is much faster than wait
|
||||
// the whole string.
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.sd_card_import_success_count).split(
|
||||
"%")[0]);
|
||||
// Check import tracks should be equal with the sum of trackNumber and
|
||||
// gpxFilesNumber;
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
assertEquals(trackNumber + gpxFilesNumber, EndToEndTestUtils.SOLO.getCurrentListViews().get(0)
|
||||
.getCount());
|
||||
|
||||
// Click to export tracks(At least two tracks) to KML files.
|
||||
gpxFilesNumber = EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length;
|
||||
trackNumber = EndToEndTestUtils.SOLO.getCurrentListViews().get(0).getCount();
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_save_all), true);
|
||||
EndToEndTestUtils.SOLO
|
||||
.clickOnText(String.format(activityMyTracks.getString(R.string.menu_save_format),
|
||||
EndToEndTestUtils.KML.toUpperCase()));
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.sd_card_save_success));
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
// Check export files.
|
||||
assertEquals(gpxFilesNumber, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length);
|
||||
assertEquals(trackNumber, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.KML).length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
EndToEndTestUtils.SOLO.finishOpenedActivities();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Instrumentation;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Tests the function of go to my location.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class GoToMyLocationTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
|
||||
|
||||
private Instrumentation instrumentation;
|
||||
private TrackListActivity activityMyTracks;
|
||||
|
||||
@TargetApi(8)
|
||||
public GoToMyLocationTest() {
|
||||
super(TrackListActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
activityMyTracks = getActivity();
|
||||
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the menu My Location.
|
||||
*/
|
||||
public void testGotoMyLocation() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, false);
|
||||
EndToEndTestUtils.sendGps(30);
|
||||
instrumentation.waitForIdleSync();
|
||||
View myLocation = EndToEndTestUtils.SOLO.getCurrentActivity()
|
||||
.findViewById(R.id.map_my_location);
|
||||
EndToEndTestUtils.SOLO.clickOnView(myLocation);
|
||||
if (EndToEndTestUtils.isEmulator) {
|
||||
EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.my_location_no_location), 1, 1000);
|
||||
} else {
|
||||
// TODO How to verify the location is shown on the map.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
EndToEndTestUtils.SOLO.finishOpenedActivities();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Instrumentation;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.KeyEvent;
|
||||
import android.widget.EditText;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests some menu items of MyTracks.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class MenuItemsTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
|
||||
|
||||
private Instrumentation instrumentation;
|
||||
private TrackListActivity activityMyTracks;
|
||||
|
||||
@TargetApi(8)
|
||||
public MenuItemsTest() {
|
||||
super(TrackListActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
activityMyTracks = getActivity();
|
||||
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests following items in More menu.
|
||||
* <ul>
|
||||
* <li>Tests the aggregated statistics activity.</li>
|
||||
* <li>Tests the Sensor state activity.</li>
|
||||
* <li>Tests the help menu.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void testSomeMenuItems() {
|
||||
// Menu in TrackListActivity.
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_aggregated_statistics),
|
||||
true);
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.stats_total_distance));
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, false);
|
||||
instrumentation.waitForIdleSync();
|
||||
// Menu in TrackDetailActivity.
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_sensor_state), true);
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.sensor_state_last_sensor_time));
|
||||
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_help), true);
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.help_about));
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests search menu item.
|
||||
*/
|
||||
public void testSearch() {
|
||||
EndToEndTestUtils.createSimpleTrack(1);
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_search), true);
|
||||
ArrayList<EditText> editTexts = EndToEndTestUtils.SOLO.getCurrentEditTexts();
|
||||
EndToEndTestUtils.SOLO.enterText(editTexts.get(0), EndToEndTestUtils.trackName);
|
||||
sendKeys(KeyEvent.KEYCODE_ENTER);
|
||||
instrumentation.waitForIdleSync();
|
||||
assertEquals(1, EndToEndTestUtils.SOLO.getCurrentListViews().size());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
EndToEndTestUtils.SOLO.finishOpenedActivities();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Instrumentation;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
/**
|
||||
* Tests sending a track to SD card.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class SaveToSdCardTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
|
||||
|
||||
private Instrumentation instrumentation;
|
||||
private TrackListActivity activityMyTracks;
|
||||
|
||||
@TargetApi(8)
|
||||
public SaveToSdCardTest() {
|
||||
super(TrackListActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
activityMyTracks = getActivity();
|
||||
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests saving a track to SD card as a GPX file.
|
||||
*/
|
||||
public void testSaveToSdCard_GPX() {
|
||||
EndToEndTestUtils.saveTrackToSdCard(EndToEndTestUtils.GPX);
|
||||
assertEquals(1, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.GPX).length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests saving a track to SD card as a KML file.
|
||||
*/
|
||||
public void testSaveToSdCard_KML() {
|
||||
EndToEndTestUtils.saveTrackToSdCard(EndToEndTestUtils.KML);
|
||||
assertEquals(1, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.KML).length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests saving a track to SD card as a CSV file.
|
||||
*/
|
||||
public void testSaveToSdCard_CSV() {
|
||||
EndToEndTestUtils.saveTrackToSdCard(EndToEndTestUtils.CSV);
|
||||
assertEquals(1, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.CSV).length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests saving a track to SD card as a TCX file.
|
||||
*/
|
||||
public void testSaveToSdCard_TCX() {
|
||||
EndToEndTestUtils.saveTrackToSdCard(EndToEndTestUtils.TCX);
|
||||
assertEquals(1, EndToEndTestUtils.getExportedFiles(EndToEndTestUtils.TCX).length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
EndToEndTestUtils.SOLO.finishOpenedActivities();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.ChartView;
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Instrumentation;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests the setting of MyTracks.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class SettingTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
|
||||
|
||||
private final String DEFAULTACTIVITY = "TestActivity";
|
||||
|
||||
private Instrumentation instrumentation;
|
||||
private TrackListActivity activityMyTracks;
|
||||
|
||||
@TargetApi(8)
|
||||
public SettingTest() {
|
||||
super(TrackListActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
activityMyTracks = getActivity();
|
||||
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes some settings and then reset them. This test case tests three
|
||||
* points:
|
||||
* <ul>
|
||||
* <li>Resets all settings.</li>
|
||||
* <li>Changes the setting of Display.</li>
|
||||
* <li>Changes the setting of Sharing.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void testChangeAndReset() {
|
||||
// Reset all settings.
|
||||
EndToEndTestUtils.resetAllSettings(activityMyTracks, true);
|
||||
// Change a setting of Map.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
|
||||
instrumentation.waitForIdleSync();
|
||||
// Rotate on a sub setting page.
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.settings_stats_units_title));
|
||||
ArrayList<CheckBox> displayCheckBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
|
||||
boolean useMetric = displayCheckBoxs.get(0).isChecked();
|
||||
EndToEndTestUtils.SOLO.clickOnCheckBox(0);
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
// Change a setting of sharing.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_sharing));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.settings_sharing_allow_access), 1, 5000));
|
||||
ArrayList<CheckBox> sharingCheckBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
|
||||
boolean newMapsPublic = sharingCheckBoxs.get(0).isChecked();
|
||||
EndToEndTestUtils.SOLO.clickOnCheckBox(0);
|
||||
instrumentation.waitForIdleSync();
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.settings_sharing_allow_access), 1, 5000));
|
||||
assertEquals(!newMapsPublic, sharingCheckBoxs.get(0).isChecked());
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
|
||||
// Reset all settings.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_reset));
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
|
||||
// Check settings.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.settings_stats_units_title), 1, 20000);
|
||||
displayCheckBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
|
||||
assertEquals(useMetric, displayCheckBoxs.get(0).isChecked());
|
||||
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_sharing));
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.settings_sharing_allow_access));
|
||||
sharingCheckBoxs = EndToEndTestUtils.SOLO.getCurrentCheckBoxes();
|
||||
assertEquals(newMapsPublic, sharingCheckBoxs.get(0).isChecked());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the change of preferred units.
|
||||
*/
|
||||
public void testChangePreferredUnits() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(5, false);
|
||||
// Change it and verify it.
|
||||
ChangePreferredUnits();
|
||||
// Change it back and verify it.
|
||||
ChangePreferredUnits();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the change of stats settings during recording on chart view.
|
||||
*/
|
||||
public void testChangeStatsSettings_underRecording_chart() {
|
||||
EndToEndTestUtils.startRecording();
|
||||
// Test just change preferred units when display CHART tab.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_chart_tab));
|
||||
EndToEndTestUtils.sendGps(3);
|
||||
ChangeStatsSettings(true, false, false, false, false);
|
||||
EndToEndTestUtils.sendGps(3);
|
||||
EndToEndTestUtils.stopRecording(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the change of stats settings during recording on stats tab.
|
||||
*/
|
||||
public void testChangeStatsSettings_underRecording_stats() {
|
||||
EndToEndTestUtils.startRecording();
|
||||
// Test change preferred units and preferred rate when display STATS tab.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
|
||||
EndToEndTestUtils.sendGps(3);
|
||||
ChangeStatsSettings(true, true, false, false, false);
|
||||
EndToEndTestUtils.sendGps(3);
|
||||
EndToEndTestUtils.stopRecording(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests displaying elevation, grade and latitude and longitude information in Stats tab.
|
||||
*/
|
||||
public void testChangeStatsSettings_showExtraInfos() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(5, false);
|
||||
EndToEndTestUtils.resetAllSettings(activityMyTracks, true);
|
||||
ChangeStatsSettings(false, false, true, true, true);
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.stats_min_elevation)));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.stats_min_grade)));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.stats_latitude)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes settings of preferred units and preferred rate.
|
||||
*
|
||||
* @param changeUnits is change the preferred unit
|
||||
* @param changeRate is change the preferred rate
|
||||
* @param changeElevation is change the elevation
|
||||
* @param changeGrade is change the grade
|
||||
* @param changeLatLong is change the latitude and longitude
|
||||
*/
|
||||
private void ChangeStatsSettings(boolean changeUnits, boolean changeRate,
|
||||
boolean changeElevation, boolean changeGrade, boolean changeLatLong) {
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.settings_stats_units_title)));
|
||||
|
||||
// Change preferred units.
|
||||
if (changeUnits) {
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_stats_units_title));
|
||||
}
|
||||
if (changeRate) {
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_stats_rate_title));
|
||||
}
|
||||
if (changeElevation) {
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.stats_elevation));
|
||||
}
|
||||
if (changeGrade) {
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_stats_grade));
|
||||
}
|
||||
if (changeLatLong) {
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_stats_coordinate));
|
||||
}
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes PreferredUnits and verifies the change.
|
||||
*/
|
||||
private void ChangePreferredUnits() {
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(activityMyTracks
|
||||
.getString(R.string.settings_stats_units_title)));
|
||||
|
||||
boolean isImperial = EndToEndTestUtils.findTextView(activityMyTracks
|
||||
.getString(R.string.settings_stats_units_imperial), EndToEndTestUtils.SOLO
|
||||
.getCurrentListViews().get(0)) != null;
|
||||
|
||||
// Change preferred units.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_stats_units_title));
|
||||
isImperial = !isImperial;
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_chart_tab));
|
||||
instrumentation.waitForIdleSync();
|
||||
ChartView chartView = EndToEndTestUtils.getChartView();
|
||||
assertEquals(!isImperial, chartView.isMetricUnits());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the backup.
|
||||
*/
|
||||
public void testBackup() {
|
||||
// Delete all backup at first.
|
||||
EndToEndTestUtils.deleteExportedFiles(EndToEndTestUtils.BACKUPS);
|
||||
EndToEndTestUtils.createTrackIfEmpty(3, true);
|
||||
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.trackName));
|
||||
|
||||
// Write to SD card.
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_backup));
|
||||
EndToEndTestUtils.SOLO
|
||||
.clickOnText(activityMyTracks.getString(R.string.settings_backup_now));
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.sd_card_save_success), 0, 100000));
|
||||
instrumentation.waitForIdleSync();
|
||||
|
||||
// Delete all tracks.
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_delete_all), true);
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
instrumentation.waitForIdleSync();
|
||||
|
||||
// Read from SD card.
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_backup));
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_backup_restore));
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.sd_card_import_success), 0, 10000));
|
||||
// Check restore track.
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.trackName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the setting of recording. This test changes the default name and
|
||||
* activity of tracks, and the creates a new track to check it.
|
||||
*/
|
||||
public void testRecording() {
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_settings), true);
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_recording));
|
||||
// Changes the setting of recording name.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_recording_track_name));
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_recording_track_name_number_option));
|
||||
// Changes the setting of default activity.
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(R.string.settings_recording_default_activity));
|
||||
EndToEndTestUtils.SOLO.enterText(0, DEFAULTACTIVITY);
|
||||
if(!EndToEndTestUtils.isEmulator) {
|
||||
// Close soft keyboard.
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
}
|
||||
EndToEndTestUtils.getButtonOnScreen(activityMyTracks.getString(R.string.generic_ok), true, true);
|
||||
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
|
||||
EndToEndTestUtils.startRecording();
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.stopRecording(false);
|
||||
instrumentation.waitForIdleSync();
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(activityMyTracks.getString(
|
||||
R.string.track_name_format).split(" ")[0]));
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(DEFAULTACTIVITY));
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.generic_save));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
EndToEndTestUtils.SOLO.finishOpenedActivities();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.endtoendtest;
|
||||
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.apps.mytracks.fragments.MapFragment;
|
||||
import com.google.android.maps.MapView;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Instrumentation;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests switching views and the menu list of each view.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class ViewsTest extends ActivityInstrumentationTestCase2<TrackListActivity> {
|
||||
|
||||
private Instrumentation instrumentation;
|
||||
private TrackListActivity activityMyTracks;
|
||||
|
||||
@TargetApi(8)
|
||||
public ViewsTest() {
|
||||
super(TrackListActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
activityMyTracks = getActivity();
|
||||
EndToEndTestUtils.setupForAllTest(instrumentation, activityMyTracks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches view from {@link MapFragment} to @ ChartFragment} , then changes
|
||||
* to @ StatsFragment} . Finally back to {@link MapFragment}. And check some
|
||||
* menus in these views.
|
||||
*/
|
||||
public void testSwitchViewsAndMenusOfView() {
|
||||
EndToEndTestUtils.createTrackIfEmpty(3, false);
|
||||
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
EndToEndTestUtils.SOLO.clickOnText(EndToEndTestUtils.trackName);
|
||||
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_chart_tab));
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
|
||||
EndToEndTestUtils.showMoreMenuItem();
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.menu_settings), 1, 3000));
|
||||
assertFalse(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.menu_satellite_mode), 1, 0));
|
||||
assertFalse(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.menu_map_mode), 1, 0));
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_stats_tab));
|
||||
EndToEndTestUtils.SOLO.sendKey(KeyEvent.KEYCODE_MENU);
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.menu_settings), 1, 3000));
|
||||
assertFalse(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.menu_satellite_mode), 1, 0));
|
||||
assertFalse(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.menu_map_mode), 1, 0));
|
||||
EndToEndTestUtils.SOLO.goBack();
|
||||
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.track_detail_map_tab));
|
||||
EndToEndTestUtils.showMoreMenuItem();
|
||||
assertTrue(EndToEndTestUtils.SOLO.waitForText(
|
||||
activityMyTracks.getString(R.string.menu_settings), 1, 3000));
|
||||
assertTrue(EndToEndTestUtils.SOLO.searchText(EndToEndTestUtils.VIEW_MODE, 1, true, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the switch between satellite mode and map mode.
|
||||
*/
|
||||
public void testSatelliteAndMapView() {
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.createTrackIfEmpty(1, false);
|
||||
instrumentation.waitForIdleSync();
|
||||
// Check current mode.
|
||||
boolean isMapMode = true;
|
||||
// If can not find switch menu in top menu, click More menu.
|
||||
if (!EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_satellite_mode),
|
||||
false)) {
|
||||
isMapMode = false;
|
||||
}
|
||||
EndToEndTestUtils.showMoreMenuItem();
|
||||
// Switch to satellite mode if it's map mode now..
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(isMapMode ? R.string.menu_satellite_mode : R.string.menu_map_mode));
|
||||
|
||||
isMapMode = !isMapMode;
|
||||
|
||||
ArrayList<View> allViews = EndToEndTestUtils.SOLO.getViews();
|
||||
for (View view : allViews) {
|
||||
if (view instanceof MapView) {
|
||||
assertEquals(isMapMode, !((MapView) view).isSatellite());
|
||||
}
|
||||
}
|
||||
instrumentation.waitForIdleSync();
|
||||
|
||||
EndToEndTestUtils.findMenuItem(activityMyTracks.getString(R.string.menu_help), false);
|
||||
instrumentation.waitForIdleSync();
|
||||
EndToEndTestUtils.rotateAllActivities();
|
||||
|
||||
// Switch back.
|
||||
EndToEndTestUtils.showMoreMenuItem();
|
||||
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks
|
||||
.getString(isMapMode ? R.string.menu_satellite_mode : R.string.menu_map_mode));
|
||||
isMapMode = !isMapMode;
|
||||
allViews = EndToEndTestUtils.SOLO.getViews();
|
||||
for (View view : allViews) {
|
||||
if (view instanceof MapView) {
|
||||
assertEquals(isMapMode, !((MapView) view).isSatellite());
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the TrackDetailActivity, or the stop button will can not be
|
||||
// found in next step.
|
||||
EndToEndTestUtils.SOLO.waitForText(activityMyTracks.getString(R.string.track_detail_chart_tab),
|
||||
0, 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
EndToEndTestUtils.SOLO.finishOpenedActivities();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.fragments;
|
||||
|
||||
import com.google.android.apps.mytracks.ChartView;
|
||||
import com.google.android.apps.mytracks.TrackStubUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
|
||||
import com.google.android.apps.mytracks.util.UnitConversions;
|
||||
|
||||
import android.location.Location;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests {@link ChartFragment}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class ChartFragmentTest extends AndroidTestCase {
|
||||
|
||||
private ChartFragment chartFragment;
|
||||
|
||||
private final double HOURS_PER_UNIT = 60.0;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
chartFragment = new ChartFragment();
|
||||
chartFragment.setChartView(new ChartView(getContext()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get the incorrect values of sensor in
|
||||
* {@link ChartFragment#fillDataPoint(Location, double[])}
|
||||
*/
|
||||
public void testFillDataPoint_sensorIncorrect() {
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
|
||||
// No input.
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(Double.NaN, point[ChartView.HEART_RATE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.CADENCE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.POWER_SERIES + 1]);
|
||||
|
||||
// Input incorrect state.
|
||||
// Creates SensorData.
|
||||
Sensor.SensorData.Builder heartRateData = Sensor.SensorData.newBuilder()
|
||||
.setValue(100).setState(Sensor.SensorState.NONE);
|
||||
Sensor.SensorData.Builder cadenceData = Sensor.SensorData.newBuilder()
|
||||
.setValue(101).setState(Sensor.SensorState.NONE);
|
||||
Sensor.SensorData.Builder powerData = Sensor.SensorData.newBuilder()
|
||||
.setValue(102).setState(Sensor.SensorState.NONE);
|
||||
|
||||
// Creates SensorDataSet.
|
||||
SensorDataSet sensorDataSet = myTracksLocation.getSensorDataSet();
|
||||
sensorDataSet = sensorDataSet.toBuilder()
|
||||
.setHeartRate(heartRateData)
|
||||
.setCadence(cadenceData)
|
||||
.setPower(powerData)
|
||||
.build();
|
||||
myTracksLocation.setSensorDataSet(sensorDataSet);
|
||||
// Test.
|
||||
point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(Double.NaN, point[ChartView.HEART_RATE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.CADENCE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.POWER_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get the correct values of sensor in
|
||||
* {@link ChartFragment#fillDataPoint(Location, double[])}.
|
||||
*/
|
||||
public void testFillDataPoint_sensorCorrect() {
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
// No input.
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(Double.NaN, point[ChartView.HEART_RATE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.CADENCE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.POWER_SERIES + 1]);
|
||||
|
||||
// Creates SensorData.
|
||||
Sensor.SensorData.Builder heartRateData = Sensor.SensorData.newBuilder()
|
||||
.setValue(100).setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder cadenceData = Sensor.SensorData.newBuilder()
|
||||
.setValue(101).setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder powerData = Sensor.SensorData.newBuilder()
|
||||
.setValue(102).setState(Sensor.SensorState.SENDING);
|
||||
|
||||
// Creates SensorDataSet.
|
||||
SensorDataSet sensorDataSet = myTracksLocation.getSensorDataSet();
|
||||
sensorDataSet = sensorDataSet.toBuilder()
|
||||
.setHeartRate(heartRateData)
|
||||
.setCadence(cadenceData)
|
||||
.setPower(powerData)
|
||||
.build();
|
||||
myTracksLocation.setSensorDataSet(sensorDataSet);
|
||||
// Test.
|
||||
point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(100.0, point[ChartView.HEART_RATE_SERIES + 1]);
|
||||
assertEquals(101.0, point[ChartView.CADENCE_SERIES + 1]);
|
||||
assertEquals(102.0, point[ChartView.POWER_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get the value of metric Distance in
|
||||
* {@link ChartFragment#fillDataPoint(Location, double[])}.
|
||||
*/
|
||||
public void testFillDataPoint_distanceMetric() {
|
||||
// By distance.
|
||||
chartFragment.setChartByDistance(true);
|
||||
// Resets last location and writes first location.
|
||||
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation1);
|
||||
assertEquals(0.0, point[0]);
|
||||
|
||||
// The second is a same location, just different time.
|
||||
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
|
||||
point = fillDataPointTestHelper(myTracksLocation2);
|
||||
assertEquals(0.0, point[0]);
|
||||
|
||||
// The third location is a new location, and use metric.
|
||||
MyTracksLocation myTracksLocation3 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation3.setLatitude(23);
|
||||
point = fillDataPointTestHelper(myTracksLocation3);
|
||||
|
||||
// Computes the distance between Latitude 22 and 23.
|
||||
float[] results = new float[4];
|
||||
Location.distanceBetween(myTracksLocation2.getLatitude(), myTracksLocation2.getLongitude(),
|
||||
myTracksLocation3.getLatitude(), myTracksLocation3.getLongitude(), results);
|
||||
double distance1 = results[0] * UnitConversions.M_TO_KM;
|
||||
assertEquals(distance1, point[0]);
|
||||
|
||||
// The fourth location is a new location, and use metric.
|
||||
MyTracksLocation myTracksLocation4 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation4.setLatitude(24);
|
||||
point = fillDataPointTestHelper(myTracksLocation4);
|
||||
|
||||
// Computes the distance between Latitude 23 and 24.
|
||||
Location.distanceBetween(myTracksLocation3.getLatitude(), myTracksLocation3.getLongitude(),
|
||||
myTracksLocation4.getLatitude(), myTracksLocation4.getLongitude(), results);
|
||||
double distance2 = results[0] * UnitConversions.M_TO_KM;
|
||||
assertEquals((distance1 + distance2), point[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get the value of imperial Distance in
|
||||
* {@link ChartFragment#fillDataPoint(Location, double[])}.
|
||||
*/
|
||||
public void testFillDataPoint_distanceImperial() {
|
||||
// By distance.
|
||||
chartFragment.setChartByDistance(true);
|
||||
// Setups to use imperial.
|
||||
chartFragment.setMetricUnits(false);
|
||||
|
||||
// The first is a same location, just different time.
|
||||
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation1);
|
||||
assertEquals(0.0, point[0]);
|
||||
|
||||
// The second location is a new location, and use imperial.
|
||||
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation2.setLatitude(23);
|
||||
point = fillDataPointTestHelper(myTracksLocation2);
|
||||
|
||||
/*
|
||||
* Computes the distance between Latitude 22 and 23. And for we set using
|
||||
* imperial, the distance should be multiplied by UnitConversions.KM_TO_MI.
|
||||
*/
|
||||
float[] results = new float[4];
|
||||
Location.distanceBetween(myTracksLocation1.getLatitude(), myTracksLocation1.getLongitude(),
|
||||
myTracksLocation2.getLatitude(), myTracksLocation2.getLongitude(), results);
|
||||
double distance1 = results[0] * UnitConversions.M_TO_KM * UnitConversions.KM_TO_MI;
|
||||
assertEquals(distance1, point[0]);
|
||||
|
||||
// The third location is a new location, and use imperial.
|
||||
MyTracksLocation myTracksLocation3 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation3.setLatitude(24);
|
||||
point = fillDataPointTestHelper(myTracksLocation3);
|
||||
|
||||
/*
|
||||
* Computes the distance between Latitude 23 and 24. And for we set using
|
||||
* imperial, the distance should be multiplied by UnitConversions.KM_TO_MI.
|
||||
*/
|
||||
Location.distanceBetween(myTracksLocation2.getLatitude(), myTracksLocation2.getLongitude(),
|
||||
myTracksLocation3.getLatitude(), myTracksLocation3.getLongitude(), results);
|
||||
double distance2 = results[0] * UnitConversions.M_TO_KM * UnitConversions.KM_TO_MI;
|
||||
assertEquals(distance1 + distance2, point[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get the values of time in
|
||||
* {@link ChartFragment#fillDataPoint(Location, double[])}.
|
||||
*/
|
||||
public void testFillDataPoint_time() {
|
||||
// By time
|
||||
chartFragment.setChartByDistance(false);
|
||||
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation1);
|
||||
assertEquals(0.0, point[0]);
|
||||
long timeSpan = 222;
|
||||
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation2.setTime(myTracksLocation1.getTime() + timeSpan);
|
||||
point = fillDataPointTestHelper(myTracksLocation2);
|
||||
assertEquals((double) timeSpan, point[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get the value of elevation in
|
||||
* {@link ChartFragment#fillDataPoint(Location, double[])} by one and two
|
||||
* points.
|
||||
*/
|
||||
public void testFillDataPoint_elevation() {
|
||||
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
|
||||
|
||||
/*
|
||||
* At first, clear old points of elevation, so give true to the second
|
||||
* parameter. Then only one value INITIALLONGTITUDE in buffer.
|
||||
*/
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation1);
|
||||
assertEquals(TrackStubUtils.INITIAL_ALTITUDE, point[ChartView.ELEVATION_SERIES + 1]);
|
||||
|
||||
/*
|
||||
* Send another value to buffer, now there are two values, INITIALALTITUDE
|
||||
* and INITIALALTITUDE * 2.
|
||||
*/
|
||||
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation2.setAltitude(TrackStubUtils.INITIAL_ALTITUDE * 2);
|
||||
point = fillDataPointTestHelper(myTracksLocation2);
|
||||
assertEquals((TrackStubUtils.INITIAL_ALTITUDE + TrackStubUtils.INITIAL_ALTITUDE * 2) / 2.0,
|
||||
point[ChartView.ELEVATION_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get the value of speed in
|
||||
* {@link ChartFragment#fillDataPoint(Location, double[])}. In this test,
|
||||
* firstly remove all points in memory, and then fill in two points one by
|
||||
* one. The speed values of these points are 129, 130.
|
||||
*/
|
||||
public void testFillDataPoint_speed() {
|
||||
// Set max speed to make the speed of points are valid.
|
||||
chartFragment.setTrackMaxSpeed(200.0);
|
||||
|
||||
/*
|
||||
* At first, clear old points of speed, so give true to the second
|
||||
* parameter. It will not be filled in to the speed buffer.
|
||||
*/
|
||||
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation1.setSpeed(129);
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation1);
|
||||
assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]);
|
||||
|
||||
/*
|
||||
* Tests the logic when both metricUnits and reportSpeed are true.This
|
||||
* location will be filled into speed buffer.
|
||||
*/
|
||||
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
|
||||
|
||||
/*
|
||||
* Add a time span here to make sure the second point is valid, the value
|
||||
* 222 here is doesn't matter.
|
||||
*/
|
||||
myTracksLocation2.setTime(myTracksLocation1.getTime() + 222);
|
||||
myTracksLocation2.setSpeed(130);
|
||||
point = fillDataPointTestHelper(myTracksLocation2);
|
||||
assertEquals(130.0 * UnitConversions.MS_TO_KMH, point[ChartView.SPEED_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to compute speed when use Imperial.
|
||||
*/
|
||||
public void testFillDataPoint_speedImperial() {
|
||||
// Setups to use imperial.
|
||||
chartFragment.setMetricUnits(false);
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation.setSpeed(132);
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(132.0 * UnitConversions.MS_TO_KMH * UnitConversions.KM_TO_MI,
|
||||
point[ChartView.SPEED_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get pace value when reportSpeed is false.
|
||||
*/
|
||||
public void testFillDataPoint_pace_nonZeroSpeed() {
|
||||
// Setups reportSpeed to false.
|
||||
chartFragment.setReportSpeed(false);
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation.setSpeed(134);
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(
|
||||
HOURS_PER_UNIT / (134.0 * UnitConversions.MS_TO_KMH), point[ChartView.PACE_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logic to get pace value when reportSpeed is false and average
|
||||
* speed is zero.
|
||||
*/
|
||||
public void testFillDataPoint_pace_zeroSpeed() {
|
||||
// Setups reportSpeed to false.
|
||||
chartFragment.setReportSpeed(false);
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation.setSpeed(0);
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(0.0, point[ChartView.PACE_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to test fillDataPoint.
|
||||
*
|
||||
* @param location location to fill
|
||||
* @return data of this location
|
||||
*/
|
||||
private double[] fillDataPointTestHelper(Location location) {
|
||||
double[] point = new double[ChartView.NUM_SERIES + 1];
|
||||
chartFragment.fillDataPoint(location, point);
|
||||
return point;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.backup;
|
||||
|
||||
import com.google.android.apps.mytracks.content.ContentTypeIds;
|
||||
|
||||
import android.database.MatrixCursor;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link DatabaseDumper}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class DatabaseDumperTest extends TestCase {
|
||||
/**
|
||||
* This class is the same as {@link MatrixCursor}, except this class
|
||||
* implements {@link #getBlob} ({@link MatrixCursor} leaves it
|
||||
* unimplemented).
|
||||
*/
|
||||
private class BlobAwareMatrixCursor extends MatrixCursor {
|
||||
public BlobAwareMatrixCursor(String[] columnNames) {
|
||||
super(columnNames);
|
||||
}
|
||||
|
||||
@Override public byte[] getBlob(int columnIndex) {
|
||||
return getString(columnIndex).getBytes();
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] COLUMN_NAMES = {
|
||||
"intCol", "longCol", "floatCol", "doubleCol", "stringCol", "boolCol", "blobCol"
|
||||
};
|
||||
private static final byte[] COLUMN_TYPES = {
|
||||
ContentTypeIds.INT_TYPE_ID, ContentTypeIds.LONG_TYPE_ID,
|
||||
ContentTypeIds.FLOAT_TYPE_ID, ContentTypeIds.DOUBLE_TYPE_ID,
|
||||
ContentTypeIds.STRING_TYPE_ID, ContentTypeIds.BOOLEAN_TYPE_ID,
|
||||
ContentTypeIds.BLOB_TYPE_ID
|
||||
};
|
||||
private static final String[][] FAKE_DATA = {
|
||||
{ "42", "123456789", "3.1415", "2.72", "lolcat", "1", "blob" },
|
||||
{ null, "123456789", "3.1415", "2.72", "lolcat", "1", "blob" },
|
||||
{ "42", null, "3.1415", "2.72", "lolcat", "1", "blob" },
|
||||
{ "42", "123456789", null, "2.72", "lolcat", "1", "blob" },
|
||||
{ "42", "123456789", "3.1415", null, "lolcat", "1", "blob" },
|
||||
{ "42", "123456789", "3.1415", "2.72", null, "1", "blob" },
|
||||
{ "42", "123456789", "3.1415", "2.72", "lolcat", null, "blob" },
|
||||
{ "42", "123456789", "3.1415", "2.72", "lolcat", "1", null },
|
||||
};
|
||||
private static final long[] EXPECTED_FIELD_SETS = {
|
||||
0x7F, 0x7E, 0x7D, 0x7B, 0x77, 0x6F, 0x5F, 0x3F
|
||||
};
|
||||
|
||||
private BlobAwareMatrixCursor cursor;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
// Add fake data to the cursor
|
||||
cursor = new BlobAwareMatrixCursor(COLUMN_NAMES);
|
||||
for (String[] row : FAKE_DATA) {
|
||||
cursor.addRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
public void testWriteAllRows_noNulls() throws Exception {
|
||||
testWriteAllRows(false);
|
||||
}
|
||||
|
||||
public void testWriteAllRows_withNulls() throws Exception {
|
||||
testWriteAllRows(true);
|
||||
}
|
||||
|
||||
private void testWriteAllRows(boolean hasNullFields) throws Exception {
|
||||
// Dump it
|
||||
DatabaseDumper dumper = new DatabaseDumper(COLUMN_NAMES, COLUMN_TYPES, hasNullFields);
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
|
||||
DataOutputStream writer = new DataOutputStream(outStream );
|
||||
dumper.writeAllRows(cursor, writer);
|
||||
|
||||
// Read the results
|
||||
byte[] result = outStream.toByteArray();
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(result);
|
||||
DataInputStream reader = new DataInputStream(inputStream);
|
||||
|
||||
// Verify the header
|
||||
assertHeader(reader);
|
||||
|
||||
// Verify the number of rows
|
||||
assertEquals(FAKE_DATA.length, reader.readInt());
|
||||
|
||||
// Row 0 -- everything populated
|
||||
assertEquals(EXPECTED_FIELD_SETS[0], reader.readLong());
|
||||
assertEquals(42, reader.readInt());
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
assertTrue(reader.readBoolean());
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
|
||||
// Row 1 -- no int
|
||||
assertEquals(EXPECTED_FIELD_SETS[1], reader.readLong());
|
||||
if (hasNullFields) reader.readInt();
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
assertTrue(reader.readBoolean());
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
|
||||
// Row 2 -- no long
|
||||
assertEquals(EXPECTED_FIELD_SETS[2], reader.readLong());
|
||||
assertEquals(42, reader.readInt());
|
||||
if (hasNullFields) reader.readLong();
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
assertTrue(reader.readBoolean());
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
|
||||
// Row 3 -- no float
|
||||
assertEquals(EXPECTED_FIELD_SETS[3], reader.readLong());
|
||||
assertEquals(42, reader.readInt());
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
if (hasNullFields) reader.readFloat();
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
assertTrue(reader.readBoolean());
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
|
||||
// Row 4 -- no double
|
||||
assertEquals(EXPECTED_FIELD_SETS[4], reader.readLong());
|
||||
assertEquals(42, reader.readInt());
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
if (hasNullFields) reader.readDouble();
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
assertTrue(reader.readBoolean());
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
|
||||
// Row 5 -- no string
|
||||
assertEquals(EXPECTED_FIELD_SETS[5], reader.readLong());
|
||||
assertEquals(42, reader.readInt());
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
if (hasNullFields) reader.readUTF();
|
||||
assertTrue(reader.readBoolean());
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
|
||||
// Row 6 -- no boolean
|
||||
assertEquals(EXPECTED_FIELD_SETS[6], reader.readLong());
|
||||
assertEquals(42, reader.readInt());
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
if (hasNullFields) reader.readBoolean();
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
|
||||
// Row 7 -- no blob
|
||||
assertEquals(EXPECTED_FIELD_SETS[7], reader.readLong());
|
||||
assertEquals(42, reader.readInt());
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
assertTrue(reader.readBoolean());
|
||||
if (hasNullFields) {
|
||||
int length = reader.readInt();
|
||||
readBlob(reader, length);
|
||||
}
|
||||
}
|
||||
|
||||
public void testFewerRows() throws Exception {
|
||||
// Dump only the first two rows
|
||||
DatabaseDumper dumper = new DatabaseDumper(COLUMN_NAMES, COLUMN_TYPES, false);
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
|
||||
DataOutputStream writer = new DataOutputStream(outStream);
|
||||
|
||||
dumper.writeHeaders(cursor, 2, writer);
|
||||
cursor.moveToFirst();
|
||||
dumper.writeOneRow(cursor, writer);
|
||||
cursor.moveToNext();
|
||||
dumper.writeOneRow(cursor, writer);
|
||||
|
||||
// Read the results
|
||||
byte[] result = outStream.toByteArray();
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(result);
|
||||
DataInputStream reader = new DataInputStream(inputStream);
|
||||
|
||||
// Verify the header
|
||||
assertHeader(reader);
|
||||
|
||||
// Verify the number of rows
|
||||
assertEquals(2, reader.readInt());
|
||||
|
||||
// Row 0
|
||||
assertEquals(EXPECTED_FIELD_SETS[0], reader.readLong());
|
||||
assertEquals(42, reader.readInt());
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
assertTrue(reader.readBoolean());
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
|
||||
// Row 1
|
||||
assertEquals(EXPECTED_FIELD_SETS[1], reader.readLong());
|
||||
// Null field not read
|
||||
assertEquals(123456789L, reader.readLong());
|
||||
assertEquals(3.1415f, reader.readFloat());
|
||||
assertEquals(2.72, reader.readDouble());
|
||||
assertEquals("lolcat", reader.readUTF());
|
||||
assertTrue(reader.readBoolean());
|
||||
assertEquals(4, reader.readInt());
|
||||
assertEquals("blob", readBlob(reader, 4));
|
||||
}
|
||||
|
||||
private void assertHeader(DataInputStream reader) throws IOException {
|
||||
assertEquals(COLUMN_NAMES.length, reader.readInt());
|
||||
for (int i = 0; i < COLUMN_NAMES.length; i++) {
|
||||
assertEquals(COLUMN_NAMES[i], reader.readUTF());
|
||||
assertEquals(COLUMN_TYPES[i], reader.readByte());
|
||||
}
|
||||
}
|
||||
|
||||
private String readBlob(InputStream reader, int length) throws Exception {
|
||||
if (length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
byte[] blob = new byte[length];
|
||||
assertEquals(length, reader.read(blob));
|
||||
return new String(blob);
|
||||
}
|
||||
}
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.backup;
|
||||
|
||||
import com.google.android.apps.mytracks.content.ContentTypeIds;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link DatabaseImporter}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class DatabaseImporterTest extends TestCase {
|
||||
|
||||
private static final Uri DESTINATION_URI = Uri.parse("http://www.google.com/");
|
||||
private static final int TEST_BULK_SIZE = 10;
|
||||
private ArrayList<ContentValues> insertedValues;
|
||||
|
||||
private class TestableDatabaseImporter extends DatabaseImporter {
|
||||
public TestableDatabaseImporter(boolean readNullFields) {
|
||||
super(DESTINATION_URI, null, readNullFields, TEST_BULK_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBulkInsert(ContentValues[] values) {
|
||||
insertedValues.ensureCapacity(insertedValues.size() + values.length);
|
||||
|
||||
// We need to make a copy of the values since the objects are re-used
|
||||
for (ContentValues contentValues : values) {
|
||||
insertedValues.add(new ContentValues(contentValues));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
insertedValues = new ArrayList<ContentValues>();
|
||||
}
|
||||
|
||||
public void testImportAllRows() throws Exception {
|
||||
testImportAllRows(false);
|
||||
}
|
||||
|
||||
public void testImportAllRows_readNullFields() throws Exception {
|
||||
testImportAllRows(true);
|
||||
}
|
||||
|
||||
private void testImportAllRows(boolean readNullFields) throws Exception {
|
||||
// Create a fake data stream to be read
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
|
||||
DataOutputStream writer = new DataOutputStream(outputStream);
|
||||
|
||||
writeFullHeader(writer);
|
||||
|
||||
// Add the number of rows
|
||||
writer.writeInt(2);
|
||||
|
||||
// Add a row with all fields present
|
||||
writer.writeLong(0x7F);
|
||||
writer.writeInt(42);
|
||||
writer.writeBoolean(true);
|
||||
writer.writeUTF("lolcat");
|
||||
writer.writeFloat(3.1415f);
|
||||
writer.writeDouble(2.72);
|
||||
writer.writeLong(123456789L);
|
||||
writer.writeInt(4);
|
||||
writer.writeBytes("blob");
|
||||
|
||||
// Add a row with some missing fields
|
||||
writer.writeLong(0x15);
|
||||
writer.writeInt(42);
|
||||
if (readNullFields) writer.writeBoolean(false);
|
||||
writer.writeUTF("lolcat");
|
||||
if (readNullFields) writer.writeFloat(0.0f);
|
||||
writer.writeDouble(2.72);
|
||||
if (readNullFields) writer.writeLong(0L);
|
||||
if (readNullFields) writer.writeInt(0); // empty blob
|
||||
|
||||
writer.flush();
|
||||
|
||||
// Do the importing
|
||||
DatabaseImporter importer = new TestableDatabaseImporter(readNullFields);
|
||||
byte[] dataBytes = outputStream.toByteArray();
|
||||
importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes)));
|
||||
|
||||
assertEquals(2, insertedValues.size());
|
||||
|
||||
// Verify the first row
|
||||
ContentValues value = insertedValues.get(0);
|
||||
assertEquals(value.toString(), 7, value.size());
|
||||
|
||||
assertValue(42, "col1", value);
|
||||
assertValue(true, "col2", value);
|
||||
assertValue("lolcat", "col3", value);
|
||||
assertValue(3.1415f, "col4", value);
|
||||
assertValue(2.72, "col5", value);
|
||||
assertValue(123456789L, "col6", value);
|
||||
assertBlobValue("blob", "col7", value);
|
||||
|
||||
// Verify the second row
|
||||
value = insertedValues.get(1);
|
||||
assertEquals(value.toString(), 3, value.size());
|
||||
|
||||
assertValue(42, "col1", value);
|
||||
assertValue("lolcat", "col3", value);
|
||||
assertValue(2.72, "col5", value);
|
||||
}
|
||||
|
||||
public void testImportAllRows_noRows() throws Exception {
|
||||
// Create a fake data stream to be read
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
|
||||
DataOutputStream writer = new DataOutputStream(outputStream);
|
||||
|
||||
writeFullHeader(writer);
|
||||
|
||||
// Add the number of rows
|
||||
writer.writeInt(0);
|
||||
|
||||
writer.flush();
|
||||
|
||||
// Do the importing
|
||||
DatabaseImporter importer = new TestableDatabaseImporter(false);
|
||||
byte[] dataBytes = outputStream.toByteArray();
|
||||
importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes)));
|
||||
|
||||
assertTrue(insertedValues.isEmpty());
|
||||
}
|
||||
|
||||
public void testImportAllRows_emptyRows() throws Exception {
|
||||
testImportAllRowsWithEmptyRows(false);
|
||||
}
|
||||
|
||||
public void testImportAllRows_emptyRowsWithNulls() throws Exception {
|
||||
testImportAllRowsWithEmptyRows(true);
|
||||
}
|
||||
|
||||
private void testImportAllRowsWithEmptyRows(boolean readNullFields) throws Exception {
|
||||
// Create a fake data stream to be read
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
|
||||
DataOutputStream writer = new DataOutputStream(outputStream);
|
||||
|
||||
writeFullHeader(writer);
|
||||
|
||||
// Add the number of rows
|
||||
writer.writeInt(3);
|
||||
|
||||
// Add 2 rows with no fields
|
||||
for (int i = 0; i < 2; i++) {
|
||||
writer.writeLong(0);
|
||||
if (readNullFields) {
|
||||
writer.writeInt(0);
|
||||
writer.writeBoolean(false);
|
||||
writer.writeUTF("");
|
||||
writer.writeFloat(0.0f);
|
||||
writer.writeDouble(0.0);
|
||||
writer.writeLong(0L);
|
||||
writer.writeInt(0); // empty blob
|
||||
}
|
||||
}
|
||||
|
||||
// Add a row with some missing fields
|
||||
writer.writeLong(0x15);
|
||||
writer.writeInt(42);
|
||||
if (readNullFields) writer.writeBoolean(false);
|
||||
writer.writeUTF("lolcat");
|
||||
if (readNullFields) writer.writeFloat(0.0f);
|
||||
writer.writeDouble(2.72);
|
||||
if (readNullFields) writer.writeLong(0L);
|
||||
if (readNullFields) writer.writeInt(0); // empty blob
|
||||
|
||||
writer.flush();
|
||||
|
||||
// Do the importing
|
||||
DatabaseImporter importer = new TestableDatabaseImporter(readNullFields);
|
||||
byte[] dataBytes = outputStream.toByteArray();
|
||||
importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes)));
|
||||
|
||||
assertEquals(insertedValues.toString(), 3, insertedValues.size());
|
||||
|
||||
ContentValues value = insertedValues.get(0);
|
||||
assertEquals(value.toString(), 0, value.size());
|
||||
|
||||
value = insertedValues.get(1);
|
||||
assertEquals(value.toString(), 0, value.size());
|
||||
|
||||
// Verify the third row (only one with values)
|
||||
value = insertedValues.get(2);
|
||||
assertEquals(value.toString(), 3, value.size());
|
||||
|
||||
assertFalse(value.containsKey("col2"));
|
||||
assertFalse(value.containsKey("col4"));
|
||||
assertFalse(value.containsKey("col6"));
|
||||
|
||||
assertValue(42, "col1", value);
|
||||
assertValue("lolcat", "col3", value);
|
||||
assertValue(2.72, "col5", value);
|
||||
}
|
||||
|
||||
public void testImportAllRows_bulks() throws Exception {
|
||||
// Create a fake data stream to be read
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
|
||||
DataOutputStream writer = new DataOutputStream(outputStream);
|
||||
|
||||
// Add the header
|
||||
writer.writeInt(2);
|
||||
writer.writeUTF("col1");
|
||||
writer.writeByte(ContentTypeIds.INT_TYPE_ID);
|
||||
writer.writeUTF("col2");
|
||||
writer.writeByte(ContentTypeIds.STRING_TYPE_ID);
|
||||
|
||||
// Add lots of rows (so the insertions are split in multiple bulks)
|
||||
int numRows = TEST_BULK_SIZE * 5 / 2;
|
||||
writer.writeInt(numRows);
|
||||
for (int i = 0; i < numRows; i++) {
|
||||
writer.writeLong(3);
|
||||
writer.writeInt(i);
|
||||
writer.writeUTF(Integer.toString(i * 2));
|
||||
}
|
||||
|
||||
writer.flush();
|
||||
|
||||
// Do the importing
|
||||
DatabaseImporter importer = new TestableDatabaseImporter(false);
|
||||
byte[] dataBytes = outputStream.toByteArray();
|
||||
importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes)));
|
||||
|
||||
// Verify the rows
|
||||
assertEquals(numRows, insertedValues.size());
|
||||
for (int i = 0; i < numRows; i++) {
|
||||
ContentValues value = insertedValues.get(i);
|
||||
assertEquals(value.toString(), 2, value.size());
|
||||
assertValue(i, "col1", value);
|
||||
assertValue(Integer.toString(i * 2), "col2", value);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeFullHeader(DataOutputStream writer) throws IOException {
|
||||
// Add the header
|
||||
writer.writeInt(7);
|
||||
writer.writeUTF("col1");
|
||||
writer.writeByte(ContentTypeIds.INT_TYPE_ID);
|
||||
writer.writeUTF("col2");
|
||||
writer.writeByte(ContentTypeIds.BOOLEAN_TYPE_ID);
|
||||
writer.writeUTF("col3");
|
||||
writer.writeByte(ContentTypeIds.STRING_TYPE_ID);
|
||||
writer.writeUTF("col4");
|
||||
writer.writeByte(ContentTypeIds.FLOAT_TYPE_ID);
|
||||
writer.writeUTF("col5");
|
||||
writer.writeByte(ContentTypeIds.DOUBLE_TYPE_ID);
|
||||
writer.writeUTF("col6");
|
||||
writer.writeByte(ContentTypeIds.LONG_TYPE_ID);
|
||||
writer.writeUTF("col7");
|
||||
writer.writeByte(ContentTypeIds.BLOB_TYPE_ID);
|
||||
}
|
||||
|
||||
private <T> void assertValue(T expectedValue, String name, ContentValues values) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T value = (T) values.get(name);
|
||||
assertNotNull(value);
|
||||
assertEquals(expectedValue, value);
|
||||
}
|
||||
|
||||
private void assertBlobValue(String expectedValue, String name, ContentValues values ){
|
||||
byte[] blob = values.getAsByteArray(name);
|
||||
assertEquals(expectedValue, new String(blob));
|
||||
}
|
||||
}
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.backup;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link PreferenceBackupHelper}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class PreferenceBackupHelperTest extends TestCase {
|
||||
private Map<String, ?> preferenceValues;
|
||||
private SharedPreferences preferences;
|
||||
private PreferenceBackupHelper preferenceBackupHelper;
|
||||
|
||||
/**
|
||||
* Mock shared preferences editor which does not persist state.
|
||||
*/
|
||||
private class MockPreferenceEditor implements SharedPreferences.Editor {
|
||||
private Map<String, Object> newPreferences = new HashMap<String, Object>(preferenceValues);
|
||||
|
||||
@Override
|
||||
public Editor clear() {
|
||||
newPreferences.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commit() {
|
||||
apply();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
preferenceValues = newPreferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putBoolean(String key, boolean value) {
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putFloat(String key, float value) {
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putInt(String key, int value) {
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putLong(String key, long value) {
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor putString(String key, String value) {
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
public Editor putStringSet(String key, Set<String> value) {
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
private <T> Editor put(String key, T value) {
|
||||
newPreferences.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor remove(String key) {
|
||||
newPreferences.remove(key);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock shared preferences which does not persist state.
|
||||
*/
|
||||
private class MockPreferences implements SharedPreferences {
|
||||
@Override
|
||||
public boolean contains(String key) {
|
||||
return preferenceValues.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor edit() {
|
||||
return new MockPreferenceEditor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ?> getAll() {
|
||||
return preferenceValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String key, boolean defValue) {
|
||||
return get(key, defValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(String key, float defValue) {
|
||||
return get(key, defValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(String key, int defValue) {
|
||||
return get(key, defValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(String key, long defValue) {
|
||||
return get(key, defValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String key, String defValue) {
|
||||
return get(key, defValue);
|
||||
}
|
||||
|
||||
public Set<String> getStringSet(String key, Set<String> defValue) {
|
||||
return get(key, defValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerOnSharedPreferenceChangeListener(
|
||||
OnSharedPreferenceChangeListener listener) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterOnSharedPreferenceChangeListener(
|
||||
OnSharedPreferenceChangeListener listener) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T get(String key, T defValue) {
|
||||
Object value = preferenceValues.get(key);
|
||||
if (value == null) return defValue;
|
||||
return (T) value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
preferenceValues = new HashMap<String, Object>();
|
||||
preferences = new MockPreferences();
|
||||
preferenceBackupHelper = new PreferenceBackupHelper();
|
||||
}
|
||||
|
||||
@TargetApi(9)
|
||||
public void testExportImportPreferences() throws Exception {
|
||||
// Populate with some initial values
|
||||
Editor editor = preferences.edit();
|
||||
editor.clear();
|
||||
editor.putBoolean("bool1", true);
|
||||
editor.putBoolean("bool2", false);
|
||||
editor.putFloat("flt1", 3.14f);
|
||||
editor.putInt("int1", 42);
|
||||
editor.putLong("long1", 123456789L);
|
||||
editor.putString("str1", "lolcat");
|
||||
editor.apply();
|
||||
|
||||
// Export it
|
||||
byte[] exported = preferenceBackupHelper.exportPreferences(preferences);
|
||||
|
||||
// Mess with the previous values
|
||||
editor = preferences.edit();
|
||||
editor.clear();
|
||||
editor.putString("str2", "Shouldn't be there after restore");
|
||||
editor.putBoolean("bool2", true);
|
||||
editor.apply();
|
||||
|
||||
// Import it back
|
||||
preferenceBackupHelper.importPreferences(exported, preferences);
|
||||
|
||||
assertFalse(preferences.contains("str2"));
|
||||
assertTrue(preferences.getBoolean("bool1", false));
|
||||
assertFalse(preferences.getBoolean("bool2", true));
|
||||
assertEquals(3.14f, preferences.getFloat("flt1", 0.0f));
|
||||
assertEquals(42, preferences.getInt("int1", 0));
|
||||
assertEquals(123456789L, preferences.getLong("long1", 0));
|
||||
assertEquals("lolcat", preferences.getString("str1", ""));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.docs;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.io.gdata.docs.SpreadsheetsClient.WorksheetEntry;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
import com.google.wireless.gdata.data.Entry;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils}.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class SendDocsUtilsTest extends AndroidTestCase {
|
||||
|
||||
private static final long TIME = 1288721514000L;
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getEntryId(Entry)} with a valid id.
|
||||
*/
|
||||
public void testGetEntryId_valid() {
|
||||
Entry entry = new Entry();
|
||||
entry.setId("https://docs.google.com/feeds/documents/private/full/spreadsheet%3A123");
|
||||
assertEquals("123", SendDocsUtils.getEntryId(entry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getEntryId(Entry)} with an invalid id.
|
||||
*/
|
||||
public void testGetEntryId_invalid() {
|
||||
Entry entry = new Entry();
|
||||
entry.setId("123");
|
||||
assertEquals(null, SendDocsUtils.getEntryId(entry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getNewSpreadsheetId(String)} with a valid id.
|
||||
*/
|
||||
public void testGetNewSpreadsheetId_valid_id() {
|
||||
assertEquals("123", SendDocsUtils.getNewSpreadsheetId(
|
||||
"<id>https://docs.google.com/feeds/documents/private/full/spreadsheet%3A123</id>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getNewSpreadsheetId(String)} without an open
|
||||
* tag, <id>.
|
||||
*/
|
||||
public void testGetNewSpreadsheetId_no_open_tag() {
|
||||
assertEquals(null, SendDocsUtils.getNewSpreadsheetId(
|
||||
"https://docs.google.com/feeds/documents/private/full/spreadsheet%3A123</id>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getNewSpreadsheetId(String)} without an end tag,
|
||||
* </id>.
|
||||
*/
|
||||
public void testGetNewSpreadsheetId_no_end_tag() {
|
||||
assertEquals(null, SendDocsUtils.getNewSpreadsheetId(
|
||||
"<id>https://docs.google.com/feeds/documents/private/full/spreadsheet%3A123"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getNewSpreadsheetId(String)} without the url
|
||||
* prefix,
|
||||
* https://docs.google.com/feeds/documents/private/full/spreadsheet%3A.
|
||||
*/
|
||||
public void testGetNewSpreadsheetId_no_prefix() {
|
||||
assertEquals(null, SendDocsUtils.getNewSpreadsheetId("<id>123</id>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getWorksheetEntryId(WorksheetEntry)} with a
|
||||
* valid entry.
|
||||
*/
|
||||
public void testGetWorksheetEntryId_valid() {
|
||||
WorksheetEntry entry = new WorksheetEntry();
|
||||
entry.setId("/123");
|
||||
assertEquals("123", SendDocsUtils.getWorksheetEntryId(entry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getWorksheetEntryId(WorksheetEntry)} with a
|
||||
* invalid entry.
|
||||
*/
|
||||
public void testGetWorksheetEntryId_invalid() {
|
||||
WorksheetEntry entry = new WorksheetEntry();
|
||||
entry.setId("123");
|
||||
assertEquals(null, SendDocsUtils.getWorksheetEntryId(entry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getRowContent(Track, boolean,
|
||||
* android.content.Context)} with metric units.
|
||||
*/
|
||||
public void testGetRowContent_metric() throws Exception {
|
||||
Track track = getTrack();
|
||||
String expectedData = "<entry xmlns='http://www.w3.org/2005/Atom' "
|
||||
+ "xmlns:gsx='http://schemas.google.com/spreadsheets/2006/extended'>"
|
||||
+ "<gsx:name><![CDATA[trackName]]></gsx:name>"
|
||||
+ "<gsx:description><![CDATA[trackDescription]]></gsx:description>" + "<gsx:date><![CDATA["
|
||||
+ StringUtils.formatDateTime(getContext(), TIME) + "]]></gsx:date>"
|
||||
+ "<gsx:totaltime><![CDATA[0:00:05]]></gsx:totaltime>"
|
||||
+ "<gsx:movingtime><![CDATA[0:00:04]]></gsx:movingtime>"
|
||||
+ "<gsx:distance><![CDATA[20.00]]></gsx:distance>"
|
||||
+ "<gsx:distanceunit><![CDATA[km]]></gsx:distanceunit>"
|
||||
+ "<gsx:averagespeed><![CDATA[14,400.00]]></gsx:averagespeed>"
|
||||
+ "<gsx:averagemovingspeed><![CDATA[18,000.00]]>" + "</gsx:averagemovingspeed>"
|
||||
+ "<gsx:maxspeed><![CDATA[5,400.00]]></gsx:maxspeed>"
|
||||
+ "<gsx:speedunit><![CDATA[km/h]]></gsx:speedunit>"
|
||||
+ "<gsx:elevationgain><![CDATA[6,000]]></gsx:elevationgain>"
|
||||
+ "<gsx:minelevation><![CDATA[-500]]></gsx:minelevation>"
|
||||
+ "<gsx:maxelevation><![CDATA[550]]></gsx:maxelevation>"
|
||||
+ "<gsx:elevationunit><![CDATA[m]]></gsx:elevationunit>"
|
||||
+ "<gsx:map><![CDATA[https://maps.google.com/maps/ms?msa=0&msid=trackMapId]]></gsx:map>"
|
||||
+ "<gsx:fusiontable><![CDATA[-]]></gsx:fusiontable>"
|
||||
+ "</entry>";
|
||||
assertEquals(expectedData, SendDocsUtils.getRowContent(track, true, getContext()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getRowContent(Track, boolean,
|
||||
* android.content.Context)} with imperial units.
|
||||
*/
|
||||
public void testGetRowContent_imperial() throws Exception {
|
||||
Track track = getTrack();
|
||||
String expectedData = "<entry xmlns='http://www.w3.org/2005/Atom' "
|
||||
+ "xmlns:gsx='http://schemas.google.com/spreadsheets/2006/extended'>"
|
||||
+ "<gsx:name><![CDATA[trackName]]></gsx:name>"
|
||||
+ "<gsx:description><![CDATA[trackDescription]]></gsx:description>" + "<gsx:date><![CDATA["
|
||||
+ StringUtils.formatDateTime(getContext(), TIME) + "]]></gsx:date>"
|
||||
+ "<gsx:totaltime><![CDATA[0:00:05]]></gsx:totaltime>"
|
||||
+ "<gsx:movingtime><![CDATA[0:00:04]]></gsx:movingtime>"
|
||||
+ "<gsx:distance><![CDATA[12.43]]></gsx:distance>"
|
||||
+ "<gsx:distanceunit><![CDATA[mi]]></gsx:distanceunit>"
|
||||
+ "<gsx:averagespeed><![CDATA[8,947.75]]></gsx:averagespeed>"
|
||||
+ "<gsx:averagemovingspeed><![CDATA[11,184.68]]>" + "</gsx:averagemovingspeed>"
|
||||
+ "<gsx:maxspeed><![CDATA[3,355.40]]></gsx:maxspeed>"
|
||||
+ "<gsx:speedunit><![CDATA[mi/h]]></gsx:speedunit>"
|
||||
+ "<gsx:elevationgain><![CDATA[19,685]]></gsx:elevationgain>"
|
||||
+ "<gsx:minelevation><![CDATA[-1,640]]></gsx:minelevation>"
|
||||
+ "<gsx:maxelevation><![CDATA[1,804]]></gsx:maxelevation>"
|
||||
+ "<gsx:elevationunit><![CDATA[ft]]></gsx:elevationunit>"
|
||||
+ "<gsx:map><![CDATA[https://maps.google.com/maps/ms?msa=0&msid=trackMapId]]></gsx:map>"
|
||||
+ "<gsx:fusiontable><![CDATA[-]]></gsx:fusiontable>"
|
||||
+ "</entry>";
|
||||
assertEquals(expectedData, SendDocsUtils.getRowContent(track, false, getContext()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a track for testing {@link SendDocsUtils#getRowContent(Track, boolean,
|
||||
* android.content.Context)}.
|
||||
*/
|
||||
private Track getTrack() {
|
||||
TripStatistics stats = new TripStatistics();
|
||||
stats.setStartTime(TIME);
|
||||
stats.setTotalTime(5000);
|
||||
stats.setMovingTime(4000);
|
||||
stats.setTotalDistance(20000);
|
||||
stats.setMaxSpeed(1500);
|
||||
stats.setTotalElevationGain(6000);
|
||||
stats.setMinElevation(-500);
|
||||
stats.setMaxElevation(550);
|
||||
|
||||
Track track = new Track();
|
||||
track.setName("trackName");
|
||||
track.setDescription("trackDescription");
|
||||
track.setMapId("trackMapId");
|
||||
track.setTripStatistics(stats);
|
||||
return track;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#appendTag(StringBuilder, String, String)} with
|
||||
* repeated calls.
|
||||
*/
|
||||
public void testAppendTag() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
SendDocsUtils.appendTag(stringBuilder, "name1", "value1");
|
||||
assertEquals("<gsx:name1><![CDATA[value1]]></gsx:name1>", stringBuilder.toString());
|
||||
|
||||
SendDocsUtils.appendTag(stringBuilder, "name2", "value2");
|
||||
assertEquals(
|
||||
"<gsx:name1><![CDATA[value1]]></gsx:name1><gsx:name2><![CDATA[value2]]></gsx:name2>",
|
||||
stringBuilder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getDistance(double, boolean)} with metric units.
|
||||
*/
|
||||
public void testGetDistance_metric() {
|
||||
assertEquals("1.22", SendDocsUtils.getDistance(1222.3, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getDistance(double, boolean)} with imperial
|
||||
* units.
|
||||
*/
|
||||
public void testGetDistance_imperial() {
|
||||
assertEquals("0.76", SendDocsUtils.getDistance(1222.3, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getSpeed(double, boolean)} with metric units.
|
||||
*/
|
||||
public void testGetSpeed_metric() {
|
||||
assertEquals("15.55", SendDocsUtils.getSpeed(4.32, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getSpeed(double, boolean)} with imperial units.
|
||||
*/
|
||||
public void testGetSpeed_imperial() {
|
||||
assertEquals("9.66", SendDocsUtils.getSpeed(4.32, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getElevation(double, boolean)} with metric
|
||||
* units.
|
||||
*/
|
||||
public void testGetElevation_metric() {
|
||||
assertEquals("3", SendDocsUtils.getElevation(3.456, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendDocsUtils#getElevation(double, boolean)} with imperial
|
||||
* units.
|
||||
*/
|
||||
public void testGetElevation_imperial() {
|
||||
assertEquals("11", SendDocsUtils.getElevation(3.456, false));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for {@link CsvTrackWriter}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class CsvTrackWriterTest extends TrackFormatWriterTest {
|
||||
|
||||
private static final String BEGIN_TAG = "\"";
|
||||
private static final String END_TAG = "\"\n";
|
||||
private static final String SEPARATOR = "\",\"";
|
||||
|
||||
public void testCsvOutput() throws Exception {
|
||||
String expectedTrackHeader = getExpectedLine(
|
||||
"Name", "Activity type", "Description");
|
||||
String expectedTrack = getExpectedLine(TRACK_NAME, TRACK_CATEGORY, TRACK_DESCRIPTION);
|
||||
String expectedMarkerHeader = getExpectedLine("Name",
|
||||
"Marker type",
|
||||
"Description",
|
||||
"Latitude (deg)",
|
||||
"Longitude (deg)",
|
||||
"Altitude (m)",
|
||||
"Bearing (deg)",
|
||||
"Accuracy (m)",
|
||||
"Speed (m/s)",
|
||||
"Time");
|
||||
String expectedMarker1 = getExpectedLine(WAYPOINT1_NAME, WAYPOINT1_CATEGORY,
|
||||
WAYPOINT1_DESCRIPTION, "1.0", "-1.0", "10.0", "100.0", "1,000", "10,000",
|
||||
"1970-01-01T00:01:40.000Z");
|
||||
String expectedMarker2 = getExpectedLine(WAYPOINT2_NAME, WAYPOINT2_CATEGORY,
|
||||
WAYPOINT2_DESCRIPTION, "2.0", "-2.0", "20.0", "200.0", "2,000", "20,000",
|
||||
"1970-01-01T00:03:20.000Z");
|
||||
String expectedPointHeader = getExpectedLine("Segment", "Point", "Latitude (deg)",
|
||||
"Longitude (deg)", "Altitude (m)", "Bearing (deg)", "Accuracy (m)", "Speed (m/s)", "Time",
|
||||
"Power (W)", "Cadence (rpm)", "Heart rate (bpm)", "Battery level (%)");
|
||||
String expectedPoint1 = getExpectedLine("1", "1", "0.0", "0.0", "0.0", "0.0", "0", "0",
|
||||
"1970-01-01T00:00:00.000Z", "100.0", "200.0", "300.0", "400.0");
|
||||
String expectedPoint2 = getExpectedLine("1", "2", "1.0", "-1.0", "10.0", "100.0", "1,000",
|
||||
"10,000", "1970-01-01T00:01:40.000Z", "101.0", "201.0", "301.0", "401.0");
|
||||
String expectedPoint3 = getExpectedLine("2", "1", "2.0", "-2.0", "20.0", "200.0", "2,000",
|
||||
"20,000", "1970-01-01T00:03:20.000Z", "102.0", "202.0", "302.0", "402.0");
|
||||
String expectedPoint4 = getExpectedLine("2", "2", "3.0", "-3.0", "30.0", "300.0", "3,000",
|
||||
"30,000", "1970-01-01T00:05:00.000Z", "103.0", "203.0", "303.0", "403.0");
|
||||
String expected = expectedTrackHeader + expectedTrack + "\n"
|
||||
+ expectedMarkerHeader + expectedMarker1 + expectedMarker2 + "\n"
|
||||
+ expectedPointHeader + expectedPoint1 + expectedPoint2 + expectedPoint3 + expectedPoint4;
|
||||
|
||||
CsvTrackWriter writer = new CsvTrackWriter(getContext());
|
||||
assertEquals(expected, writeTrack(writer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expected CSV line from a list of expected values.
|
||||
*
|
||||
* @param values expected values
|
||||
*/
|
||||
private String getExpectedLine(String... values) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(BEGIN_TAG);
|
||||
boolean first = true;
|
||||
for (String value : values) {
|
||||
if (!first) {
|
||||
builder.append(SEPARATOR);
|
||||
}
|
||||
first = false;
|
||||
builder.append(value);
|
||||
}
|
||||
builder.append(END_TAG);
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import static com.google.android.testing.mocking.AndroidMock.eq;
|
||||
import static com.google.android.testing.mocking.AndroidMock.expect;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
|
||||
import android.content.ContentUris;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.SimpleTimeZone;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.easymock.Capture;
|
||||
import org.easymock.IArgumentMatcher;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Tests for the GPX importer.
|
||||
*
|
||||
* @author Steffen Horlacher
|
||||
*/
|
||||
public class GpxImporterTest extends AndroidTestCase {
|
||||
|
||||
private static final String TRACK_NAME = "blablub";
|
||||
private static final String TRACK_DESC = "s'Laebe isch koi Schlotzer";
|
||||
|
||||
private static final String TRACK_LAT_1 = "48.768364";
|
||||
private static final String TRACK_LON_1 = "9.177886";
|
||||
private static final String TRACK_ELE_1 = "324.0";
|
||||
private static final String TRACK_TIME_1 = "2010-04-22T18:21:00Z";
|
||||
|
||||
private static final String TRACK_LAT_2 = "48.768374";
|
||||
private static final String TRACK_LON_2 = "9.177816";
|
||||
private static final String TRACK_ELE_2 = "333.0";
|
||||
private static final String TRACK_TIME_2 = "2010-04-22T18:21:50.123";
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMAT1 =
|
||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
||||
private static final SimpleDateFormat DATE_FORMAT2 =
|
||||
new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'");
|
||||
static {
|
||||
// We can't omit the timezones in the test, otherwise it'll use the local
|
||||
// timezone and fail depending on where the test runner is.
|
||||
SimpleTimeZone utc = new SimpleTimeZone(0, "UTC");
|
||||
DATE_FORMAT1.setTimeZone(utc);
|
||||
DATE_FORMAT2.setTimeZone(utc);
|
||||
}
|
||||
|
||||
// TODO: use real files from different sources with more track points.
|
||||
private static final String VALID_TEST_GPX = "<gpx><trk><name><![CDATA["
|
||||
+ TRACK_NAME + "]]></name><desc><![CDATA[" + TRACK_DESC
|
||||
+ "]]></desc><trkseg>" + "<trkpt lat=\"" + TRACK_LAT_1 + "\" lon=\""
|
||||
+ TRACK_LON_1 + "\"><ele>" + TRACK_ELE_1 + "</ele><time>" + TRACK_TIME_1
|
||||
+ "</time></trkpt> +" + "<trkpt lat=\"" + TRACK_LAT_2 + "\" lon=\""
|
||||
+ TRACK_LON_2 + "\"><ele>" + TRACK_ELE_2 + "</ele><time>" + TRACK_TIME_2
|
||||
+ "</time></trkpt>" + "</trkseg></trk></gpx>";
|
||||
|
||||
// invalid xml
|
||||
private static final String INVALID_XML_TEST_GPX = VALID_TEST_GPX.substring(
|
||||
0, VALID_TEST_GPX.length() - 50);
|
||||
private static final String INVALID_LOCATION_TEST_GPX = VALID_TEST_GPX
|
||||
.replaceAll(TRACK_LAT_1, "1000.0");
|
||||
private static final String INVALID_TIME_TEST_GPX = VALID_TEST_GPX
|
||||
.replaceAll(TRACK_TIME_1, "invalid");
|
||||
private static final String INVALID_ALTITUDE_TEST_GPX = VALID_TEST_GPX
|
||||
.replaceAll(TRACK_ELE_1, "invalid");
|
||||
private static final String INVALID_LATITUDE_TEST_GPX = VALID_TEST_GPX
|
||||
.replaceAll(TRACK_LAT_1, "invalid");
|
||||
private static final String INVALID_LONGITUDE_TEST_GPX = VALID_TEST_GPX
|
||||
.replaceAll(TRACK_LON_1, "invalid");
|
||||
|
||||
private static final long TRACK_ID = 1;
|
||||
private static final long TRACK_POINT_ID_1 = 1;
|
||||
private static final long TRACK_POINT_ID_2 = 2;
|
||||
|
||||
private static final Uri TRACK_ID_URI = ContentUris.appendId(
|
||||
TracksColumns.CONTENT_URI.buildUpon(), TRACK_ID).build();
|
||||
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
|
||||
private Factory oldProviderUtilsFactory;
|
||||
|
||||
@UsesMocks(MyTracksProviderUtils.class)
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
providerUtils = AndroidMock.createMock(MyTracksProviderUtils.class);
|
||||
oldProviderUtilsFactory =
|
||||
TestingProviderUtilsFactory.installWithInstance(providerUtils);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
TestingProviderUtilsFactory.restoreOldFactory(oldProviderUtilsFactory);
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test import success.
|
||||
*/
|
||||
public void testImportSuccess() throws Exception {
|
||||
Capture<Track> trackParam = new Capture<Track>();
|
||||
|
||||
Location loc1 = new Location(LocationManager.GPS_PROVIDER);
|
||||
loc1.setTime(DATE_FORMAT2.parse(TRACK_TIME_1).getTime());
|
||||
loc1.setLatitude(Double.parseDouble(TRACK_LAT_1));
|
||||
loc1.setLongitude(Double.parseDouble(TRACK_LON_1));
|
||||
loc1.setAltitude(Double.parseDouble(TRACK_ELE_1));
|
||||
|
||||
Location loc2 = new Location(LocationManager.GPS_PROVIDER);
|
||||
loc2.setTime(DATE_FORMAT1.parse(TRACK_TIME_2).getTime());
|
||||
loc2.setLatitude(Double.parseDouble(TRACK_LAT_2));
|
||||
loc2.setLongitude(Double.parseDouble(TRACK_LON_2));
|
||||
loc2.setAltitude(Double.parseDouble(TRACK_ELE_2));
|
||||
|
||||
expect(providerUtils.insertTrack(AndroidMock.capture(trackParam)))
|
||||
.andReturn(TRACK_ID_URI);
|
||||
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(TRACK_POINT_ID_1).andReturn(TRACK_POINT_ID_2);
|
||||
|
||||
// A flush happens after the first insertion to get the starting point ID,
|
||||
// which is why we get two calls
|
||||
expect(providerUtils.bulkInsertTrackPoints(LocationsMatcher.eqLoc(loc1),
|
||||
eq(1), eq(TRACK_ID))).andReturn(1);
|
||||
expect(providerUtils.bulkInsertTrackPoints(LocationsMatcher.eqLoc(loc2),
|
||||
eq(1), eq(TRACK_ID))).andReturn(1);
|
||||
|
||||
providerUtils.updateTrack(AndroidMock.capture(trackParam));
|
||||
|
||||
AndroidMock.replay(providerUtils);
|
||||
|
||||
InputStream is = new ByteArrayInputStream(VALID_TEST_GPX.getBytes());
|
||||
GpxImporter.importGPXFile(is, providerUtils);
|
||||
|
||||
AndroidMock.verify(providerUtils);
|
||||
|
||||
// verify track parameter
|
||||
Track track = trackParam.getValue();
|
||||
assertEquals(TRACK_NAME, track.getName());
|
||||
assertEquals(TRACK_DESC, track.getDescription());
|
||||
assertEquals(DATE_FORMAT2.parse(TRACK_TIME_1).getTime(), track.getTripStatistics()
|
||||
.getStartTime());
|
||||
assertNotSame(-1, track.getStartId());
|
||||
assertNotSame(-1, track.getStopId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with invalid location - track should be deleted.
|
||||
*/
|
||||
public void testImportLocationFailure() throws ParserConfigurationException, IOException {
|
||||
testInvalidXML(INVALID_LOCATION_TEST_GPX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with invalid time - track should be deleted.
|
||||
*/
|
||||
public void testImportTimeFailure() throws ParserConfigurationException, IOException {
|
||||
testInvalidXML(INVALID_TIME_TEST_GPX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with invalid xml - track should be deleted.
|
||||
*/
|
||||
public void testImportXMLFailure() throws ParserConfigurationException, IOException {
|
||||
testInvalidXML(INVALID_XML_TEST_GPX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with invalid altitude - track should be deleted.
|
||||
*/
|
||||
public void testImportInvalidAltitude() throws ParserConfigurationException, IOException {
|
||||
testInvalidXML(INVALID_ALTITUDE_TEST_GPX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with invalid latitude - track should be deleted.
|
||||
*/
|
||||
public void testImportInvalidLatitude() throws ParserConfigurationException, IOException {
|
||||
testInvalidXML(INVALID_LATITUDE_TEST_GPX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with invalid longitude - track should be deleted.
|
||||
*/
|
||||
public void testImportInvalidLongitude() throws ParserConfigurationException, IOException {
|
||||
testInvalidXML(INVALID_LONGITUDE_TEST_GPX);
|
||||
}
|
||||
|
||||
private void testInvalidXML(String xml) throws ParserConfigurationException,
|
||||
IOException {
|
||||
expect(providerUtils.insertTrack((Track) AndroidMock.anyObject()))
|
||||
.andReturn(TRACK_ID_URI);
|
||||
|
||||
expect(providerUtils.bulkInsertTrackPoints((Location[]) AndroidMock.anyObject(),
|
||||
AndroidMock.anyInt(), AndroidMock.anyLong())).andStubReturn(1);
|
||||
expect(providerUtils.getLastLocationId(TRACK_ID)).andStubReturn(TRACK_POINT_ID_1);
|
||||
|
||||
providerUtils.deleteTrack(TRACK_ID);
|
||||
|
||||
AndroidMock.replay(providerUtils);
|
||||
|
||||
InputStream is = new ByteArrayInputStream(xml.getBytes());
|
||||
try {
|
||||
GpxImporter.importGPXFile(is, providerUtils);
|
||||
} catch (SAXException e) {
|
||||
// expected exception
|
||||
}
|
||||
|
||||
AndroidMock.verify(providerUtils);
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround because of capture bug 2617107 in easymock:
|
||||
* http://sourceforge.net
|
||||
* /tracker/?func=detail&aid=2617107&group_id=82958&atid=567837
|
||||
*/
|
||||
private static class LocationsMatcher implements IArgumentMatcher {
|
||||
private final Location[] matchLocs;
|
||||
|
||||
private LocationsMatcher(Location[] expected) {
|
||||
this.matchLocs = expected;
|
||||
}
|
||||
|
||||
public static Location[] eqLoc(Location[] expected) {
|
||||
IArgumentMatcher matcher = new LocationsMatcher(expected);
|
||||
AndroidMock.reportMatcher(matcher);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Location[] eqLoc(Location expected) {
|
||||
return eqLoc(new Location[] { expected});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendTo(StringBuffer buf) {
|
||||
buf.append("eqLoc(").append(Arrays.toString(matchLocs)).append(")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object obj) {
|
||||
if (! (obj instanceof Location[])) { return false; }
|
||||
Location[] locs = (Location[]) obj;
|
||||
if (locs.length < matchLocs.length) { return false; }
|
||||
|
||||
// Only check the first elements (those that will be taken into account)
|
||||
for (int i = 0; i < matchLocs.length; i++) {
|
||||
if (!locationsMatch(locs[i], matchLocs[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean locationsMatch(Location loc1, Location loc2) {
|
||||
return (loc1.getTime() == loc2.getTime()) &&
|
||||
(loc1.getLatitude() == loc2.getLatitude()) &&
|
||||
(loc1.getLongitude() == loc2.getLongitude()) &&
|
||||
(loc1.getAltitude() == loc2.getAltitude());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Tests for {@link GpxTrackWriter}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class GpxTrackWriterTest extends TrackFormatWriterTest {
|
||||
|
||||
public void testXmlOutput() throws Exception {
|
||||
TrackFormatWriter writer = new GpxTrackWriter(getContext());
|
||||
String result = writeTrack(writer);
|
||||
Document doc = parseXmlDocument(result);
|
||||
|
||||
Element gpxTag = getChildElement(doc, "gpx");
|
||||
Element trackTag = getChildElement(gpxTag, "trk");
|
||||
assertEquals(TRACK_NAME, getChildTextValue(trackTag, "name"));
|
||||
assertEquals(TRACK_DESCRIPTION, getChildTextValue(trackTag, "desc"));
|
||||
List<Element> segmentTags = getChildElements(trackTag, "trkseg", 2);
|
||||
List<Element> segPointTags = getChildElements(segmentTags.get(0), "trkpt", 2);
|
||||
assertTagMatchesLocation(segPointTags.get(0), "0", "0", "1970-01-01T00:00:00.000Z", "0");
|
||||
assertTagMatchesLocation(segPointTags.get(1), "1", "-1", "1970-01-01T00:01:40.000Z", "10");
|
||||
|
||||
segPointTags = getChildElements(segmentTags.get(1), "trkpt", 2);
|
||||
assertTagMatchesLocation(segPointTags.get(0), "2", "-2", "1970-01-01T00:03:20.000Z", "20");
|
||||
assertTagMatchesLocation(segPointTags.get(1), "3", "-3", "1970-01-01T00:05:00.000Z", "30");
|
||||
|
||||
List<Element> waypointTags = getChildElements(gpxTag, "wpt", 2);
|
||||
Element wptTag = waypointTags.get(0);
|
||||
assertEquals(WAYPOINT1_NAME, getChildTextValue(wptTag, "name"));
|
||||
assertEquals(WAYPOINT1_DESCRIPTION, getChildTextValue(wptTag, "desc"));
|
||||
assertTagMatchesLocation(wptTag, "1", "-1", "1970-01-01T00:01:40.000Z", "10");
|
||||
|
||||
wptTag = waypointTags.get(1);
|
||||
assertEquals(WAYPOINT2_NAME, getChildTextValue(wptTag, "name"));
|
||||
assertEquals(WAYPOINT2_DESCRIPTION, getChildTextValue(wptTag, "desc"));
|
||||
assertTagMatchesLocation(wptTag, "2", "-2", "1970-01-01T00:03:20.000Z", "20");
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given tag describes a location.
|
||||
*
|
||||
* @param tag the tag
|
||||
* @param latitude the location's latitude
|
||||
* @param longitude the location's longitude
|
||||
* @param time the location's time
|
||||
* @param elevation the location's elevation
|
||||
*/
|
||||
private void assertTagMatchesLocation(
|
||||
Element tag, String latitude, String longitude, String time, String elevation) {
|
||||
assertEquals(latitude, tag.getAttribute("lat"));
|
||||
assertEquals(longitude, tag.getAttribute("lon"));
|
||||
assertEquals(time, getChildTextValue(tag, "time"));
|
||||
assertEquals(elevation, getChildTextValue(tag, "ele"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import com.google.android.apps.mytracks.content.DescriptionGenerator;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.location.Location;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Tests for {@link KmlTrackWriter}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class KmlTrackWriterTest extends TrackFormatWriterTest {
|
||||
|
||||
private static final String FULL_TRACK_DESCRIPTION = "full track description";
|
||||
|
||||
/**
|
||||
* A fake version of {@link DescriptionGenerator} which returns a fixed track
|
||||
* description, thus not depending on the context.
|
||||
*/
|
||||
private class FakeDescriptionGenerator implements DescriptionGenerator {
|
||||
@Override
|
||||
public String generateTrackDescription(
|
||||
Track aTrack, Vector<Double> distances, Vector<Double> elevations, boolean html) {
|
||||
return FULL_TRACK_DESCRIPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateWaypointDescription(Waypoint waypoint) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void testXmlOutput() throws Exception {
|
||||
KmlTrackWriter writer = new KmlTrackWriter(getContext(), new FakeDescriptionGenerator());
|
||||
String result = writeTrack(writer);
|
||||
Document doc = parseXmlDocument(result);
|
||||
|
||||
Element kmlTag = getChildElement(doc, "kml");
|
||||
Element docTag = getChildElement(kmlTag, "Document");
|
||||
assertEquals(TRACK_NAME, getChildTextValue(docTag, "name"));
|
||||
assertEquals(TRACK_DESCRIPTION, getChildTextValue(docTag, "description"));
|
||||
|
||||
// There are 3 placemarks - start, track, and end
|
||||
List<Element> placemarkTags = getChildElements(docTag, "Placemark", 3);
|
||||
assertTagIsPlacemark(
|
||||
placemarkTags.get(0), TRACK_NAME + " (Start)", TRACK_DESCRIPTION, location1);
|
||||
assertTagIsPlacemark(
|
||||
placemarkTags.get(2), TRACK_NAME + " (End)", FULL_TRACK_DESCRIPTION, location4);
|
||||
|
||||
List<Element> folderTag = getChildElements(docTag, "Folder", 1);
|
||||
List<Element> folderPlacemarkTags = getChildElements(folderTag.get(0), "Placemark", 2);
|
||||
assertTagIsPlacemark(
|
||||
folderPlacemarkTags.get(0), WAYPOINT1_NAME, WAYPOINT1_DESCRIPTION, location2);
|
||||
assertTagIsPlacemark(
|
||||
folderPlacemarkTags.get(1), WAYPOINT2_NAME, WAYPOINT2_DESCRIPTION, location3);
|
||||
|
||||
Element trackPlacemarkTag = placemarkTags.get(1);
|
||||
assertEquals(TRACK_NAME, getChildTextValue(trackPlacemarkTag, "name"));
|
||||
assertEquals(TRACK_DESCRIPTION, getChildTextValue(trackPlacemarkTag, "description"));
|
||||
Element multiTrackTag = getChildElement(trackPlacemarkTag, "gx:MultiTrack");
|
||||
List<Element> trackTags = getChildElements(multiTrackTag, "gx:Track", 2);
|
||||
assertTagHasPoints(trackTags.get(0), location1, location2);
|
||||
assertTagHasPoints(trackTags.get(1), location3, location4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given tag is a placemark with the given properties.
|
||||
*
|
||||
* @param tag the tag
|
||||
* @param name the expected placemark name
|
||||
* @param description the expected placemark description
|
||||
* @param location the expected placemark location
|
||||
*/
|
||||
private void assertTagIsPlacemark(
|
||||
Element tag, String name, String description, Location location) {
|
||||
assertEquals(name, getChildTextValue(tag, "name"));
|
||||
assertEquals(description, getChildTextValue(tag, "description"));
|
||||
Element pointTag = getChildElement(tag, "Point");
|
||||
String expected = location.getLongitude() + "," + location.getLatitude() + ","
|
||||
+ location.getAltitude();
|
||||
String actual = getChildTextValue(pointTag, "coordinates");
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given tag has a list of "gx:coord" subtags matching the
|
||||
* expected locations.
|
||||
*
|
||||
* @param tag the parent tag
|
||||
* @param locations list of expected locations
|
||||
*/
|
||||
@TargetApi(8)
|
||||
private void assertTagHasPoints(Element tag, Location... locations) {
|
||||
List<Element> coordTags = getChildElements(tag, "gx:coord", locations.length);
|
||||
for (int i = 0; i < locations.length; i++) {
|
||||
Location location = locations[i];
|
||||
String expected = location.getLongitude() + " " + location.getLatitude() + " "
|
||||
+ location.getAltitude();
|
||||
String actual = coordTags.get(i).getFirstChild().getTextContent();
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* A simple, fake {@link TrackWriter} subclass with all methods mocked out.
|
||||
* Tests are expected to override {@link #writeTrack}.
|
||||
*
|
||||
* @author Matthew Simmons
|
||||
*
|
||||
*/
|
||||
public class MockTrackWriter implements TrackWriter {
|
||||
public OnWriteListener onWriteListener;
|
||||
|
||||
@Override
|
||||
public void setOnWriteListener(OnWriteListener onWriteListener) {
|
||||
this.onWriteListener = onWriteListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirectory(File directory) {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAbsolutePath() {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTrack() {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopWriteTrack() {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasSuccess() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getErrorMessage() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Tests for {@link TcxTrackWriter}.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class TcxTrackWriterTest extends TrackFormatWriterTest {
|
||||
|
||||
public void testXmlOutput() throws Exception {
|
||||
TrackFormatWriter writer = new TcxTrackWriter(getContext());
|
||||
String result = writeTrack(writer);
|
||||
Document doc = parseXmlDocument(result);
|
||||
|
||||
Element root = getChildElement(doc, "TrainingCenterDatabase");
|
||||
Element activitiesTag = getChildElement(root, "Activities");
|
||||
Element activityTag = getChildElement(activitiesTag, "Activity");
|
||||
Element lapTag = getChildElement(activityTag, "Lap");
|
||||
|
||||
List<Element> segmentTags = getChildElements(lapTag, "Track", 2);
|
||||
Element segment1Tag = segmentTags.get(0);
|
||||
Element segment2Tag = segmentTags.get(1);
|
||||
List<Element> seg1PointTags = getChildElements(segment1Tag, "Trackpoint", 2);
|
||||
List<Element> seg2PointTags = getChildElements(segment2Tag, "Trackpoint", 2);
|
||||
assertTagsMatchPoints(seg1PointTags, location1, location2);
|
||||
assertTagsMatchPoints(seg2PointTags, location3, location4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given tags describe the given locations in the same order.
|
||||
*
|
||||
* @param tags list of tags
|
||||
* @param locations list of locations
|
||||
*/
|
||||
private void assertTagsMatchPoints(List<Element> tags, MyTracksLocation... locations) {
|
||||
assertEquals(locations.length, tags.size());
|
||||
for (int i = 0; i < locations.length; i++) {
|
||||
assertTagMatchesLocation(tags.get(i), locations[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given tag describes the given location.
|
||||
*
|
||||
* @param tag the tag
|
||||
* @param location the location
|
||||
*/
|
||||
private void assertTagMatchesLocation(Element tag, MyTracksLocation location) {
|
||||
assertEquals(StringUtils.formatDateTimeIso8601(location.getTime()), getChildTextValue(tag, "Time"));
|
||||
|
||||
Element positionTag = getChildElement(tag, "Position");
|
||||
assertEquals(
|
||||
Double.toString(location.getLatitude()), getChildTextValue(positionTag, "LatitudeDegrees"));
|
||||
assertEquals(Double.toString(location.getLongitude()),
|
||||
getChildTextValue(positionTag, "LongitudeDegrees"));
|
||||
|
||||
assertEquals(Double.toString(location.getAltitude()), getChildTextValue(tag, "AltitudeMeters"));
|
||||
assertTrue(location.getSensorDataSet() != null);
|
||||
Sensor.SensorDataSet sds = location.getSensorDataSet();
|
||||
|
||||
List<Element> heartRate = getChildElements(tag, "HeartRateBpm", 1);
|
||||
assertEquals(Integer.toString(sds.getHeartRate().getValue()),
|
||||
getChildTextValue(heartRate.get(0), "Value"));
|
||||
|
||||
List<Element> extensions = getChildElements(tag, "Extensions", 1);
|
||||
List<Element> tpx = getChildElements(extensions.get(0), "TPX", 1);
|
||||
assertEquals(
|
||||
Integer.toString(sds.getCadence().getValue()), getChildTextValue(tpx.get(0), "RunCadence"));
|
||||
assertEquals(
|
||||
Integer.toString(sds.getPower().getValue()), getChildTextValue(tpx.get(0), "Watts"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.FactoryConfigurationError;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.Text;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Base class for track format writer tests, which sets up a fake track and
|
||||
* gives auxiliary methods for verifying XML output.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public abstract class TrackFormatWriterTest extends AndroidTestCase {
|
||||
|
||||
// All the user-provided strings have "]]>" to ensure that proper escaping is
|
||||
// being done.
|
||||
protected static final String TRACK_NAME = "Home]]>";
|
||||
protected static final String TRACK_CATEGORY = "Hiking";
|
||||
protected static final String TRACK_DESCRIPTION = "The long ]]> journey home";
|
||||
protected static final String WAYPOINT1_NAME = "point]]>1";
|
||||
protected static final String WAYPOINT1_CATEGORY = "Statistics";
|
||||
protected static final String WAYPOINT1_DESCRIPTION = "point 1]]>description";
|
||||
protected static final String WAYPOINT2_NAME = "point]]>2";
|
||||
protected static final String WAYPOINT2_CATEGORY = "Waypoint";
|
||||
protected static final String WAYPOINT2_DESCRIPTION = "point 2]]>description";
|
||||
private static final int BUFFER_SIZE = 10240;
|
||||
protected Track track;
|
||||
protected MyTracksLocation location1, location2, location3, location4;
|
||||
protected Waypoint wp1, wp2;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
track = new Track();
|
||||
track.setName(TRACK_NAME);
|
||||
track.setCategory(TRACK_CATEGORY);
|
||||
track.setDescription(TRACK_DESCRIPTION);
|
||||
|
||||
location1 = new MyTracksLocation("mock");
|
||||
location2 = new MyTracksLocation("mock");
|
||||
location3 = new MyTracksLocation("mock");
|
||||
location4 = new MyTracksLocation("mock");
|
||||
populateLocations(location1, location2, location3, location4);
|
||||
|
||||
wp1 = new Waypoint();
|
||||
wp2 = new Waypoint();
|
||||
wp1.setLocation(location2);
|
||||
wp1.setName(WAYPOINT1_NAME);
|
||||
wp1.setCategory(WAYPOINT1_CATEGORY);
|
||||
wp1.setDescription(WAYPOINT1_DESCRIPTION);
|
||||
wp2.setLocation(location3);
|
||||
wp2.setName(WAYPOINT2_NAME);
|
||||
wp2.setCategory(WAYPOINT2_CATEGORY);
|
||||
wp2.setDescription(WAYPOINT2_DESCRIPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a list of locations with values.
|
||||
*
|
||||
* @param locations a list of locations
|
||||
*/
|
||||
private void populateLocations(MyTracksLocation... locations) {
|
||||
for (int i = 0; i < locations.length; i++) {
|
||||
MyTracksLocation location = locations[i];
|
||||
location.setLatitude(i);
|
||||
location.setLongitude(-i);
|
||||
location.setAltitude(i * 10);
|
||||
location.setBearing(i * 100);
|
||||
location.setAccuracy(i * 1000);
|
||||
location.setSpeed(i * 10000);
|
||||
location.setTime(i * 100000);
|
||||
Sensor.SensorData.Builder power = Sensor.SensorData.newBuilder().setValue(100 + i)
|
||||
.setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder cadence = Sensor.SensorData.newBuilder().setValue(200 + i)
|
||||
.setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder heartRate = Sensor.SensorData.newBuilder().setValue(300 + i)
|
||||
.setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder batteryLevel = Sensor.SensorData.newBuilder().setValue(400 + i)
|
||||
.setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorDataSet sensorDataSet = Sensor.SensorDataSet.newBuilder().setPower(power)
|
||||
.setCadence(cadence).setHeartRate(heartRate).setBatteryLevel(batteryLevel).build();
|
||||
location.setSensorDataSet(sensorDataSet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the right sequence of calls to the writer in order to write the fake
|
||||
* track in {@link #track}.
|
||||
*
|
||||
* @param writer the writer to write to
|
||||
* @return the written contents
|
||||
*/
|
||||
protected String writeTrack(TrackFormatWriter writer) throws Exception {
|
||||
OutputStream output = new ByteArrayOutputStream(BUFFER_SIZE);
|
||||
writer.prepare(track, output);
|
||||
writer.writeHeader();
|
||||
writer.writeBeginWaypoints();
|
||||
writer.writeWaypoint(wp1);
|
||||
writer.writeWaypoint(wp2);
|
||||
writer.writeEndWaypoints();
|
||||
writer.writeBeginTrack(location1);
|
||||
writer.writeOpenSegment();
|
||||
writer.writeLocation(location1);
|
||||
writer.writeLocation(location2);
|
||||
writer.writeCloseSegment();
|
||||
writer.writeOpenSegment();
|
||||
writer.writeLocation(location3);
|
||||
writer.writeLocation(location4);
|
||||
writer.writeCloseSegment();
|
||||
writer.writeEndTrack(location4);
|
||||
writer.writeFooter();
|
||||
writer.close();
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text data contained inside a tag.
|
||||
*
|
||||
* @param parent the parent of the tag containing the text
|
||||
* @param elementName the name of the tag containing the text
|
||||
* @return the text contents
|
||||
*/
|
||||
protected String getChildTextValue(Element parent, String elementName) {
|
||||
Element child = getChildElement(parent, elementName);
|
||||
assertTrue(child.hasChildNodes());
|
||||
NodeList children = child.getChildNodes();
|
||||
int length = children.getLength();
|
||||
assertTrue(length > 0);
|
||||
|
||||
// The children may be a sucession of text elements, just concatenate them
|
||||
String result = "";
|
||||
for (int i = 0; i < length; i++) {
|
||||
Text textNode = (Text) children.item(i);
|
||||
result += textNode.getNodeValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all child elements of a given parent which have the given name.
|
||||
*
|
||||
* @param parent the parent to get children from
|
||||
* @param elementName the element name to look for
|
||||
* @param expectedChildren the number of children we're expected to find
|
||||
* @return a list of the found elements
|
||||
*/
|
||||
protected List<Element> getChildElements(Node parent, String elementName,
|
||||
int expectedChildren) {
|
||||
assertTrue(parent.hasChildNodes());
|
||||
NodeList children = parent.getChildNodes();
|
||||
int length = children.getLength();
|
||||
List<Element> result = new ArrayList<Element>();
|
||||
for (int i = 0; i < length; i++) {
|
||||
Node childNode = children.item(i);
|
||||
if (childNode.getNodeType() == Node.ELEMENT_NODE
|
||||
&& childNode.getNodeName().equalsIgnoreCase(elementName)) {
|
||||
result.add((Element) childNode);
|
||||
}
|
||||
}
|
||||
assertTrue(children.toString(), result.size() == expectedChildren);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the single child element of the given parent with the given type.
|
||||
*
|
||||
* @param parent the parent to get a child from
|
||||
* @param elementName the name of the child to look for
|
||||
* @return the child element
|
||||
*/
|
||||
protected Element getChildElement(Node parent, String elementName) {
|
||||
return getChildElements(parent, elementName, 1).get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given XML contents and returns a DOM {@link Document} for it.
|
||||
*/
|
||||
protected Document parseXmlDocument(String contents)
|
||||
throws FactoryConfigurationError, ParserConfigurationException,
|
||||
SAXException, IOException {
|
||||
DocumentBuilderFactory builderFactory =
|
||||
DocumentBuilderFactory.newInstance();
|
||||
builderFactory.setCoalescing(true);
|
||||
// TODO: Somehow do XML validation on Android
|
||||
// builderFactory.setValidating(true);
|
||||
builderFactory.setNamespaceAware(true);
|
||||
builderFactory.setIgnoringComments(true);
|
||||
builderFactory.setIgnoringElementContentWhitespace(true);
|
||||
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
|
||||
Document doc = documentBuilder.parse(
|
||||
new InputSource(new StringReader(contents)));
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,365 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
|
||||
package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProvider;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
||||
import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.easymock.IArgumentMatcher;
|
||||
import org.easymock.IMocksControl;
|
||||
|
||||
/**
|
||||
* Tests for the track writer.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TrackWriterTest extends AndroidTestCase {
|
||||
/**
|
||||
* {@link TrackWriterImpl} subclass which mocks out methods called from
|
||||
* {@link TrackWriterImpl#openFile}.
|
||||
*/
|
||||
private static final class OpenFileTrackWriter extends TrackWriterImpl {
|
||||
private final ByteArrayOutputStream stream;
|
||||
private final boolean canWrite;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param stream the stream to return from
|
||||
* {@link TrackWriterImpl#newOutputStream}, or null to throw a
|
||||
* {@link FileNotFoundException}
|
||||
* @param canWrite the value that {@link TrackWriterImpl#canWriteFile} will
|
||||
* return
|
||||
*/
|
||||
private OpenFileTrackWriter(Context context,
|
||||
MyTracksProviderUtils providerUtils, Track track,
|
||||
TrackFormatWriter writer, ByteArrayOutputStream stream,
|
||||
boolean canWrite) {
|
||||
super(context, providerUtils, track, writer);
|
||||
|
||||
this.stream = stream;
|
||||
this.canWrite = canWrite;
|
||||
|
||||
// The directory is set in the canWriteFile. However, this class
|
||||
// overwrites canWriteFile, thus needs to set it.
|
||||
setDirectory(new File("/"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canWriteFile() {
|
||||
return canWrite;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OutputStream newOutputStream(String fileName)
|
||||
throws FileNotFoundException {
|
||||
assertEquals(FULL_TRACK_NAME, fileName);
|
||||
|
||||
if (stream == null) {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link TrackWriterImpl} subclass which mocks out methods called from
|
||||
* {@link TrackWriterImpl#writeTrack}.
|
||||
*/
|
||||
private final class WriteTracksTrackWriter extends TrackWriterImpl {
|
||||
private final boolean openResult;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param openResult the return value for {@link TrackWriterImpl#openFile}
|
||||
*/
|
||||
private WriteTracksTrackWriter(Context context,
|
||||
MyTracksProviderUtils providerUtils, Track track,
|
||||
TrackFormatWriter writer, boolean openResult) {
|
||||
super(context, providerUtils, track, writer);
|
||||
this.openResult = openResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean openFile() {
|
||||
openFileCalls++;
|
||||
return openResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeDocument() {
|
||||
writeDocumentCalls++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runOnUiThread(Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
private static final long TRACK_ID = 1234567L;
|
||||
private static final String EXTENSION = "ext";
|
||||
private static final String TRACK_NAME = "Swimming across the pacific";
|
||||
private static final String FULL_TRACK_NAME =
|
||||
"Swimming across the pacific.ext";
|
||||
|
||||
private Track track;
|
||||
private TrackFormatWriter formatWriter;
|
||||
private TrackWriterImpl writer;
|
||||
private IMocksControl mocksControl;
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
private Factory oldProviderUtilsFactory;
|
||||
|
||||
// State used in specific tests
|
||||
private int writeDocumentCalls;
|
||||
private int openFileCalls;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
MockContentResolver mockContentResolver = new MockContentResolver();
|
||||
RenamingDelegatingContext targetContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
Context context = new MockContext(mockContentResolver, targetContext);
|
||||
MyTracksProvider provider = new MyTracksProvider();
|
||||
provider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, provider);
|
||||
setContext(context);
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
oldProviderUtilsFactory = TestingProviderUtilsFactory.installWithInstance(providerUtils);
|
||||
|
||||
mocksControl = EasyMock.createStrictControl();
|
||||
formatWriter = mocksControl.createMock(TrackFormatWriter.class);
|
||||
expect(formatWriter.getExtension()).andStubReturn(EXTENSION);
|
||||
|
||||
track = new Track();
|
||||
track.setName(TRACK_NAME);
|
||||
track.setId(TRACK_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
TestingProviderUtilsFactory.restoreOldFactory(oldProviderUtilsFactory);
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testWriteTrack() {
|
||||
writer = new WriteTracksTrackWriter(getContext(), providerUtils, track,
|
||||
formatWriter, true);
|
||||
|
||||
mocksControl.replay();
|
||||
writer.writeTrack();
|
||||
|
||||
assertEquals(1, writeDocumentCalls);
|
||||
assertEquals(1, openFileCalls);
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
public void testWriteTrack_openFails() {
|
||||
writer = new WriteTracksTrackWriter(getContext(), providerUtils, track,
|
||||
formatWriter, false);
|
||||
|
||||
mocksControl.replay();
|
||||
writer.writeTrack();
|
||||
|
||||
assertEquals(0, writeDocumentCalls);
|
||||
assertEquals(1, openFileCalls);
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
public void testOpenFile() {
|
||||
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
writer = new OpenFileTrackWriter(
|
||||
getContext(), providerUtils, track, formatWriter, stream, true);
|
||||
|
||||
formatWriter.prepare(track, stream);
|
||||
|
||||
mocksControl.replay();
|
||||
assertTrue(writer.openFile());
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
public void testOpenFile_cantWrite() {
|
||||
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
writer = new OpenFileTrackWriter(
|
||||
getContext(), providerUtils, track, formatWriter, stream, false);
|
||||
|
||||
mocksControl.replay();
|
||||
assertFalse(writer.openFile());
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
public void testOpenFile_streamError() {
|
||||
writer = new OpenFileTrackWriter(
|
||||
getContext(), providerUtils, track, formatWriter, null, true);
|
||||
|
||||
mocksControl.replay();
|
||||
assertFalse(writer.openFile());
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
public void testWriteDocument_emptyTrack() throws Exception {
|
||||
writer = new TrackWriterImpl(getContext(), providerUtils, track, formatWriter);
|
||||
|
||||
// Set expected mock behavior
|
||||
formatWriter.writeHeader();
|
||||
formatWriter.writeBeginTrack(null);
|
||||
formatWriter.writeEndTrack(null);
|
||||
formatWriter.writeFooter();
|
||||
formatWriter.close();
|
||||
|
||||
mocksControl.replay();
|
||||
writer.writeDocument();
|
||||
|
||||
assertTrue(writer.wasSuccess());
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
public void testWriteDocument() throws Exception {
|
||||
writer = new TrackWriterImpl(getContext(), providerUtils, track, formatWriter);
|
||||
|
||||
final Location[] locs = {
|
||||
new Location("fake0"),
|
||||
new Location("fake1"),
|
||||
new Location("fake2"),
|
||||
new Location("fake3"),
|
||||
new Location("fake4"),
|
||||
new Location("fake5")
|
||||
};
|
||||
Waypoint[] wps = { new Waypoint(), new Waypoint(), new Waypoint() };
|
||||
|
||||
// Fill locations with valid values
|
||||
fillLocations(locs);
|
||||
|
||||
// Make location 3 invalid
|
||||
locs[2].setLatitude(100);
|
||||
|
||||
assertEquals(locs.length, providerUtils.bulkInsertTrackPoints(locs, locs.length, TRACK_ID));
|
||||
for (int i = 0; i < wps.length; ++i) {
|
||||
Waypoint wpt = wps[i];
|
||||
wpt.setTrackId(TRACK_ID);
|
||||
assertNotNull(providerUtils.insertWaypoint(wpt));
|
||||
wpt.setId(i + 1);
|
||||
}
|
||||
|
||||
formatWriter.writeHeader();
|
||||
|
||||
// Expect reading/writing of the waypoints (except the first)
|
||||
formatWriter.writeBeginWaypoints();
|
||||
formatWriter.writeWaypoint(wptEq(wps[1]));
|
||||
formatWriter.writeWaypoint(wptEq(wps[2]));
|
||||
formatWriter.writeEndWaypoints();
|
||||
|
||||
// Begin the track
|
||||
formatWriter.writeBeginTrack(locEq(locs[0]));
|
||||
|
||||
// Write locations 1-2
|
||||
formatWriter.writeOpenSegment();
|
||||
formatWriter.writeLocation(locEq(locs[0]));
|
||||
formatWriter.writeLocation(locEq(locs[1]));
|
||||
formatWriter.writeCloseSegment();
|
||||
|
||||
// Location 3 is not written - it's invalid
|
||||
|
||||
// Write locations 4-6
|
||||
formatWriter.writeOpenSegment();
|
||||
formatWriter.writeLocation(locEq(locs[3]));
|
||||
formatWriter.writeLocation(locEq(locs[4]));
|
||||
formatWriter.writeLocation(locEq(locs[5]));
|
||||
formatWriter.writeCloseSegment();
|
||||
|
||||
// End the track
|
||||
formatWriter.writeEndTrack(locEq(locs[5]));
|
||||
|
||||
formatWriter.writeFooter();
|
||||
formatWriter.close();
|
||||
|
||||
mocksControl.replay();
|
||||
writer.writeDocument();
|
||||
|
||||
assertTrue(writer.wasSuccess());
|
||||
mocksControl.verify();
|
||||
}
|
||||
|
||||
private static Waypoint wptEq(final Waypoint wpt) {
|
||||
EasyMock.reportMatcher(new IArgumentMatcher() {
|
||||
@Override
|
||||
public boolean matches(Object wptObj2) {
|
||||
if (wptObj2 == null || wpt == null) return wpt == wptObj2;
|
||||
Waypoint wpt2 = (Waypoint) wptObj2;
|
||||
|
||||
return wpt.getId() == wpt2.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendTo(StringBuffer buffer) {
|
||||
buffer.append("wptEq(");
|
||||
buffer.append(wpt);
|
||||
buffer.append(")");
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Location locEq(final Location loc) {
|
||||
EasyMock.reportMatcher(new IArgumentMatcher() {
|
||||
@Override
|
||||
public boolean matches(Object locObj2) {
|
||||
if (locObj2 == null || loc == null) return loc == locObj2;
|
||||
Location loc2 = (Location) locObj2;
|
||||
|
||||
return loc.hasAccuracy() == loc2.hasAccuracy()
|
||||
&& (!loc.hasAccuracy() || loc.getAccuracy() == loc2.getAccuracy())
|
||||
&& loc.hasAltitude() == loc2.hasAltitude()
|
||||
&& (!loc.hasAltitude() || loc.getAltitude() == loc2.getAltitude())
|
||||
&& loc.hasBearing() == loc2.hasBearing()
|
||||
&& (!loc.hasBearing() || loc.getBearing() == loc2.getBearing())
|
||||
&& loc.hasSpeed() == loc2.hasSpeed()
|
||||
&& (!loc.hasSpeed() || loc.getSpeed() == loc2.getSpeed())
|
||||
&& loc.getLatitude() == loc2.getLatitude()
|
||||
&& loc.getLongitude() == loc2.getLongitude()
|
||||
&& loc.getTime() == loc2.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendTo(StringBuffer buffer) {
|
||||
buffer.append("locEq(");
|
||||
buffer.append(loc);
|
||||
buffer.append(")");
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
private void fillLocations(Location... locs) {
|
||||
assertTrue(locs.length < 90);
|
||||
for (int i = 0; i < locs.length; i++) {
|
||||
Location location = locs[i];
|
||||
location.setLatitude(i + 1);
|
||||
location.setLongitude(i + 1);
|
||||
location.setTime(i + 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.fusiontables;
|
||||
|
||||
import com.google.android.apps.mytracks.io.docs.SendDocsActivity;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.UploadResultActivity;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests the {@link SendFusionTablesActivity}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class SendFusionTablesActivityTest extends AndroidTestCase {
|
||||
|
||||
private SendFusionTablesActivity sendFusionTablesActivity;
|
||||
private SendRequest sendRequest;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
sendRequest = new SendRequest(1L);
|
||||
sendFusionTablesActivity = new SendFusionTablesActivity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendFusionTablesActivity#getNextClass(SendRequest, boolean)}. Sets
|
||||
* the flags of "sendDocs" and "cancel" to false and false.
|
||||
*/
|
||||
public void testGetNextClass_notCancelNotSendDocs() {
|
||||
sendRequest.setSendDocs(false);
|
||||
Class<?> next = sendFusionTablesActivity.getNextClass(sendRequest, false);
|
||||
assertEquals(UploadResultActivity.class, next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendFusionTablesActivity#getNextClass(SendRequest, boolean)}. Sets
|
||||
* the flags of "sendDocs" and "cancel" to true and false.
|
||||
*/
|
||||
public void testGetNextClass_notCancelSendDocs() {
|
||||
sendRequest.setSendDocs(true);
|
||||
Class<?> next = sendFusionTablesActivity.getNextClass(sendRequest, false);
|
||||
assertEquals(SendDocsActivity.class, next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendFusionTablesActivity#getNextClass(SendRequest,boolean)}. Sets
|
||||
* the flags of "sendDocs" and "cancel" to true and true.
|
||||
*/
|
||||
public void testGetNextClass_cancelSendDocs() {
|
||||
sendRequest.setSendDocs(true);
|
||||
Class<?> next = sendFusionTablesActivity.getNextClass(sendRequest, true);
|
||||
assertEquals(UploadResultActivity.class, next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendFusionTablesActivity#getNextClass(SendRequest,boolean)}. Sets
|
||||
* the flags of "sendDocs" and "cancel" to false and true.
|
||||
*/
|
||||
public void testGetNextClass_cancelNotSendDocs() {
|
||||
sendRequest.setSendDocs(false);
|
||||
Class<?> next = sendFusionTablesActivity.getNextClass(sendRequest, true);
|
||||
assertEquals(UploadResultActivity.class, next);
|
||||
}
|
||||
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.fusiontables;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils}.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class SendFusionTablesUtilsTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getMapUrl(Track)} with null track.
|
||||
*/
|
||||
public void testGetMapUrl_null_track() {
|
||||
assertEquals(null, SendFusionTablesUtils.getMapUrl(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getMapUrl(Track)} with null table id.
|
||||
*/
|
||||
public void testGetMapUrl_null_table_id() {
|
||||
Track track = new Track();
|
||||
TripStatistics stats = new TripStatistics();
|
||||
stats.setBounds((int) 100.E6, (int) 10.E6, (int) 50.E6, (int) 5.E6);
|
||||
track.setTripStatistics(stats);
|
||||
track.setTableId(null);
|
||||
assertEquals(null, SendFusionTablesUtils.getMapUrl(track));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getMapUrl(Track)} with null stats.
|
||||
*/
|
||||
public void testGetMapUrl_null_stats() {
|
||||
Track track = new Track();
|
||||
track.setTripStatistics(null);
|
||||
track.setTableId("123");
|
||||
assertEquals(null, SendFusionTablesUtils.getMapUrl(track));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getMapUrl(Track)} with a valid track.
|
||||
*/
|
||||
public void testGetMapUrl_valid_track() {
|
||||
Track track = new Track();
|
||||
track.setNumberOfPoints(2);
|
||||
TripStatistics stats = new TripStatistics();
|
||||
stats.setBounds((int) 100.E6, (int) 10.E6, (int) 50.E6, (int) 5.E6);
|
||||
track.setTripStatistics(stats);
|
||||
track.setTableId("123");
|
||||
assertEquals(
|
||||
"https://www.google.com/fusiontables/embedviz?"
|
||||
+ "viz=MAP&q=select+col0,+col1,+col2,+col3+from+123+&h=false&lat=7.500000&lng=75.000000"
|
||||
+ "&z=15&t=1&l=col2", SendFusionTablesUtils.getMapUrl(track));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests (@link {@link SendFusionTablesUtils#formatSqlValues(String...)} with
|
||||
* no value.
|
||||
*/
|
||||
public void testFormatSqlValues_no_value() {
|
||||
assertEquals("()", SendFusionTablesUtils.formatSqlValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests (@link {@link SendFusionTablesUtils#formatSqlValues(String...)} with
|
||||
* an empty string.
|
||||
*/
|
||||
public void testFormatSqlValues_empty_string() {
|
||||
assertEquals("(\'\')", SendFusionTablesUtils.formatSqlValues(""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests (@link {@link SendFusionTablesUtils#formatSqlValues(String...)} with
|
||||
* one value.
|
||||
*/
|
||||
public void testFormatSqlValues_one_value() {
|
||||
assertEquals("(\'first\')", SendFusionTablesUtils.formatSqlValues("first"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests (@link {@link SendFusionTablesUtils#formatSqlValues(String...)} with
|
||||
* two values.
|
||||
*/
|
||||
public void testFormatSqlValues_two_values() {
|
||||
assertEquals(
|
||||
"(\'first\',\'second\')", SendFusionTablesUtils.formatSqlValues("first", "second"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#escapeSqlString(String)} with a value
|
||||
* containing several single quotes.
|
||||
*/
|
||||
public void testEscapeSqValuel() {
|
||||
String value = "let's'";
|
||||
assertEquals("let''s''", SendFusionTablesUtils.escapeSqlString(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getKmlPoint(Location)} with a null
|
||||
* point.
|
||||
*/
|
||||
public void testGetKmlPoint_null_point() {
|
||||
assertEquals(
|
||||
"<Point><coordinates></coordinates></Point>", SendFusionTablesUtils.getKmlPoint(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getKmlPoint(Location)} with a valid
|
||||
* point.
|
||||
*/
|
||||
public void testGetKmlPoint_valid_point() {
|
||||
Location location = new Location("test");
|
||||
location.setLongitude(10.1);
|
||||
location.setLatitude(20.2);
|
||||
location.setAltitude(30.3);
|
||||
assertEquals("<Point><coordinates>10.1,20.2,30.3</coordinates></Point>",
|
||||
SendFusionTablesUtils.getKmlPoint(location));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getKmlLineString(ArrayList)} with a null
|
||||
* locations.
|
||||
*/
|
||||
public void testKmlLineString_null_locations() {
|
||||
assertEquals("<LineString><coordinates></coordinates></LineString>",
|
||||
SendFusionTablesUtils.getKmlLineString(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getKmlLineString(ArrayList)} with no
|
||||
* location.
|
||||
*/
|
||||
public void testKmlLineString_no_location() {
|
||||
ArrayList<Location> locations = new ArrayList<Location>();
|
||||
assertEquals("<LineString><coordinates></coordinates></LineString>",
|
||||
SendFusionTablesUtils.getKmlLineString(locations));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getKmlLineString(ArrayList)} with one
|
||||
* location.
|
||||
*/
|
||||
public void testKmlLineString_one_location() {
|
||||
ArrayList<Location> locations = new ArrayList<Location>();
|
||||
Location location = new Location("test");
|
||||
location.setLongitude(10.1);
|
||||
location.setLatitude(20.2);
|
||||
location.setAltitude(30.3);
|
||||
locations.add(location);
|
||||
assertEquals("<LineString><coordinates>10.1,20.2,30.3</coordinates></LineString>",
|
||||
SendFusionTablesUtils.getKmlLineString(locations));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getKmlLineString(ArrayList)} with two
|
||||
* locations.
|
||||
*/
|
||||
public void testKmlLineString_two_locations() {
|
||||
ArrayList<Location> locations = new ArrayList<Location>();
|
||||
Location location1 = new Location("test");
|
||||
location1.setLongitude(10.1);
|
||||
location1.setLatitude(20.2);
|
||||
location1.setAltitude(30.3);
|
||||
locations.add(location1);
|
||||
|
||||
Location location2 = new Location("test");
|
||||
location2.setLongitude(1.1);
|
||||
location2.setLatitude(2.2);
|
||||
location2.removeAltitude();
|
||||
locations.add(location2);
|
||||
|
||||
assertEquals("<LineString><coordinates>10.1,20.2,30.3 1.1,2.2</coordinates></LineString>",
|
||||
SendFusionTablesUtils.getKmlLineString(locations));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#appendLocation(Location, StringBuilder)}
|
||||
* with no altitude.
|
||||
*/
|
||||
public void testAppendLocation_no_altitude() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Location location = new Location("test");
|
||||
location.setLongitude(10.1);
|
||||
location.setLatitude(20.2);
|
||||
location.removeAltitude();
|
||||
SendFusionTablesUtils.appendLocation(location, builder);
|
||||
assertEquals("10.1,20.2", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#appendLocation(Location, StringBuilder)}
|
||||
* with altitude.
|
||||
*/
|
||||
public void testAppendLocation_has_altitude() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Location location = new Location("test");
|
||||
location.setLongitude(10.1);
|
||||
location.setLatitude(20.2);
|
||||
location.setAltitude(30.3);
|
||||
SendFusionTablesUtils.appendLocation(location, builder);
|
||||
assertEquals("10.1,20.2,30.3", builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with a null
|
||||
* inputstream.
|
||||
*/
|
||||
public void testGetTableId_null() {
|
||||
assertEquals(null, SendFusionTablesUtils.getTableId(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with an
|
||||
* inputstream containing no data.
|
||||
*/
|
||||
public void testGetTableId_no_data() {
|
||||
InputStream inputStream = new ByteArrayInputStream(new byte[0]);
|
||||
assertEquals(null, SendFusionTablesUtils.getTableId(inputStream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with an empty
|
||||
* inputstream.
|
||||
*/
|
||||
public void testGetTableId_empty() {
|
||||
String string = "";
|
||||
InputStream inputStream = new ByteArrayInputStream(string.getBytes());
|
||||
assertEquals(null, SendFusionTablesUtils.getTableId(inputStream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with an one
|
||||
* line inputstream.
|
||||
*/
|
||||
public void testGetTableId_one_line() {
|
||||
String string = "tableid";
|
||||
InputStream inputStream = new ByteArrayInputStream(string.getBytes());
|
||||
assertEquals(null, SendFusionTablesUtils.getTableId(inputStream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with an
|
||||
* inputstream not containing "tableid".
|
||||
*/
|
||||
public void testGetTableId_no_table_id() {
|
||||
String string = "error\n123";
|
||||
InputStream inputStream = new ByteArrayInputStream(string.getBytes());
|
||||
assertEquals(null, SendFusionTablesUtils.getTableId(inputStream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendFusionTablesUtils#getTableId(InputStream)} with a valid
|
||||
* inputstream.
|
||||
*/
|
||||
public void testGetTableId() {
|
||||
String string = "tableid\n123";
|
||||
InputStream inputStream = null;
|
||||
inputStream = new ByteArrayInputStream(string.getBytes());
|
||||
assertEquals("123", SendFusionTablesUtils.getTableId(inputStream));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.io.gdata.maps.MapsMapMetadata;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Intent;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests the {@link ChooseMapActivity}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class ChooseMapActivityTest extends AndroidTestCase {
|
||||
|
||||
private static final String MAP_ID = "mapid";
|
||||
private static final String MAP_TITLE = "title";
|
||||
private static final String MAP_DESC = "desc";
|
||||
|
||||
private ArrayList<String> mapIds = new ArrayList<String>();
|
||||
private ArrayList<MapsMapMetadata> mapDatas = new ArrayList<MapsMapMetadata>();
|
||||
private boolean errorDialogShown = false;
|
||||
private boolean progressDialogRemoved = false;
|
||||
|
||||
/**
|
||||
* Creates a class to override some methods of {@link ChooseMapActivity} to
|
||||
* makes it testable.
|
||||
*
|
||||
* @author youtaol
|
||||
*/
|
||||
@TargetApi(11)
|
||||
public class ChooseMapActivityMock extends ChooseMapActivity {
|
||||
/**
|
||||
* By overriding this method, avoids to start next activity.
|
||||
*/
|
||||
@Override
|
||||
public void startActivity(Intent intent) {}
|
||||
|
||||
/**
|
||||
* By overriding this method, avoids to show an error dialog and set the
|
||||
* show flag to true.
|
||||
*/
|
||||
@Override
|
||||
public void showErrorDialog() {
|
||||
errorDialogShown = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* By overriding this method, avoids to show an error dialog and set the
|
||||
* show flag to true.
|
||||
*/
|
||||
@Override
|
||||
public void removeProgressDialog() {
|
||||
progressDialogRemoved = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
|
||||
* . An alert dialog should be shown when there is no map.
|
||||
*/
|
||||
public void testOnAsyncTaskCompleted_fail() {
|
||||
ChooseMapActivityMock chooseMapActivityMock = new ChooseMapActivityMock();
|
||||
errorDialogShown = false;
|
||||
progressDialogRemoved = false;
|
||||
chooseMapActivityMock.onAsyncTaskCompleted(false, null, null);
|
||||
assertTrue(progressDialogRemoved);
|
||||
assertTrue(errorDialogShown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
|
||||
* . Check the logic when there is only map.
|
||||
*/
|
||||
public void testOnAsyncTaskCompleted_success_oneMap() {
|
||||
ChooseMapActivityMock chooseMapActivityMock = new ChooseMapActivityMock();
|
||||
chooseMapActivityMock.arrayAdapter = new ArrayAdapter<ChooseMapActivity.ListItem>(getContext(),
|
||||
R.layout.choose_map_item);
|
||||
simulateMaps(1);
|
||||
chooseMapActivityMock.onAsyncTaskCompleted(true, mapIds, mapDatas);
|
||||
assertEquals(1, chooseMapActivityMock.arrayAdapter.getCount());
|
||||
assertEquals(MAP_ID + "0", chooseMapActivityMock.arrayAdapter.getItem(0).getMapId());
|
||||
assertEquals(MAP_TITLE + "0", chooseMapActivityMock.arrayAdapter.getItem(0).getMapData()
|
||||
.getTitle());
|
||||
assertEquals(MAP_DESC + "0", chooseMapActivityMock.arrayAdapter.getItem(0).getMapData()
|
||||
.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
|
||||
* . Check the logic when there are 10 maps.
|
||||
*/
|
||||
public void testOnAsyncTaskCompleted_success_twoMaps() {
|
||||
ChooseMapActivityMock chooseMapActivityMock = new ChooseMapActivityMock();
|
||||
chooseMapActivityMock.arrayAdapter = new ArrayAdapter<ChooseMapActivity.ListItem>(getContext(),
|
||||
R.layout.choose_map_item);
|
||||
simulateMaps(10);
|
||||
chooseMapActivityMock.onAsyncTaskCompleted(true, mapIds, mapDatas);
|
||||
assertEquals(10, chooseMapActivityMock.arrayAdapter.getCount());
|
||||
assertEquals(MAP_ID + "9", chooseMapActivityMock.arrayAdapter.getItem(9).getMapId());
|
||||
assertEquals(MAP_TITLE + "9", chooseMapActivityMock.arrayAdapter.getItem(9).getMapData()
|
||||
.getTitle());
|
||||
assertEquals(MAP_DESC + "9", chooseMapActivityMock.arrayAdapter.getItem(9).getMapData()
|
||||
.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates map data for the test.
|
||||
*
|
||||
* @param number of data should be simulated.
|
||||
*/
|
||||
private void simulateMaps(int number) {
|
||||
mapIds = new ArrayList<String>();
|
||||
mapDatas = new ArrayList<MapsMapMetadata>();
|
||||
for (int i = 0; i < number; i++) {
|
||||
mapIds.add(MAP_ID + i);
|
||||
MapsMapMetadata metaData = new MapsMapMetadata();
|
||||
metaData.setTitle(MAP_TITLE + i);
|
||||
metaData.setDescription(MAP_DESC + i);
|
||||
metaData.setSearchable(true);
|
||||
mapDatas.add(metaData);
|
||||
}
|
||||
}
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.maps;
|
||||
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Tests {@link ChooseMapAsyncTask}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class ChooseMapAsyncTaskTest extends AndroidTestCase {
|
||||
|
||||
private ChooseMapActivity chooseMapActivityMock;
|
||||
private Account account;
|
||||
private static final String ACCOUNT_NAME = "AccountName";
|
||||
private static final String ACCOUNT_TYPE = "AccountType";
|
||||
private boolean getMapsStatus = false;
|
||||
|
||||
public class ChooseMapAsyncTaskMock extends ChooseMapAsyncTask {
|
||||
|
||||
public ChooseMapAsyncTaskMock(ChooseMapActivity activity, Account account) {
|
||||
super(activity, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates this method to override {@link ChooseMapAsyncTask#getMaps()}.
|
||||
*
|
||||
* @return mock the return value of getMaps().
|
||||
*/
|
||||
@Override
|
||||
boolean getMaps() {
|
||||
return getMapsStatus;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link ChooseMapAsyncTask#setActivity(ChooseMapActivity)} when the
|
||||
* task is completed. Makes sure it calls
|
||||
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
|
||||
* .
|
||||
*/
|
||||
public void testSetActivity_completed() {
|
||||
setup();
|
||||
chooseMapActivityMock.onAsyncTaskCompleted(false, null, null);
|
||||
AndroidMock.replay(chooseMapActivityMock);
|
||||
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
|
||||
chooseMapAsyncTask.setCompleted(true);
|
||||
chooseMapAsyncTask.setActivity(chooseMapActivityMock);
|
||||
AndroidMock.verify(chooseMapActivityMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link ChooseMapAsyncTask#setActivity(ChooseMapActivity)} when the
|
||||
* task is not completed. Makes sure
|
||||
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
|
||||
* is not invoked.
|
||||
*/
|
||||
public void testSetActivity_notCompleted() {
|
||||
setup();
|
||||
AndroidMock.replay(chooseMapActivityMock);
|
||||
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
|
||||
chooseMapAsyncTask.setCompleted(false);
|
||||
chooseMapAsyncTask.setActivity(chooseMapActivityMock);
|
||||
AndroidMock.verify(chooseMapActivityMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link ChooseMapAsyncTask#setActivity(ChooseMapActivity)} when the
|
||||
* activity is null. Makes sure
|
||||
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
|
||||
* is not invoked.
|
||||
*/
|
||||
public void testSetActivity_nullActivity() {
|
||||
setup();
|
||||
AndroidMock.replay(chooseMapActivityMock);
|
||||
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
|
||||
chooseMapAsyncTask.setCompleted(true);
|
||||
chooseMapAsyncTask.setActivity(null);
|
||||
AndroidMock.verify(chooseMapActivityMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ChooseMapAsyncTask#onPostExecute(Boolean)} when the
|
||||
* result is true. Makes sure
|
||||
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
|
||||
* is invoked.
|
||||
*/
|
||||
public void testOnPostExecute_trueResult() {
|
||||
setup();
|
||||
chooseMapActivityMock.onAsyncTaskCompleted(true, null, null);
|
||||
AndroidMock.replay(chooseMapActivityMock);
|
||||
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
|
||||
chooseMapAsyncTask.onPostExecute(true);
|
||||
AndroidMock.verify(chooseMapActivityMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ChooseMapAsyncTask#onPostExecute(Boolean)} when the
|
||||
* result is false. Makes sure
|
||||
* {@link ChooseMapActivity#onAsyncTaskCompleted(boolean, ArrayList, ArrayList)}
|
||||
* is invoked.
|
||||
*/
|
||||
public void testOnPostExecute_falseResult() {
|
||||
setup();
|
||||
chooseMapActivityMock.onAsyncTaskCompleted(false, null, null);
|
||||
AndroidMock.replay(chooseMapActivityMock);
|
||||
ChooseMapAsyncTask chooseMapAsyncTask = new ChooseMapAsyncTask(chooseMapActivityMock, account);
|
||||
chooseMapAsyncTask.onPostExecute(false);
|
||||
AndroidMock.verify(chooseMapActivityMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ChooseMapAsyncTask#retryUpload()}. Make sure can
|
||||
* not retry again after have retried once and failed.
|
||||
*/
|
||||
public void testRetryUpload() throws Exception {
|
||||
setup();
|
||||
AndroidMock.replay(chooseMapActivityMock);
|
||||
ChooseMapAsyncTaskMock chooseMapAsyncTaskTMock = new ChooseMapAsyncTaskMock(
|
||||
chooseMapActivityMock, account);
|
||||
chooseMapAsyncTaskTMock.setCanRetry(false);
|
||||
getMapsStatus = true;
|
||||
assertFalse(chooseMapAsyncTaskTMock.retryUpload());
|
||||
AndroidMock.verify(chooseMapActivityMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ChooseMapAsyncTask#retryUpload()}. Make sure can
|
||||
* retry after get maps failed and never retry before.
|
||||
*/
|
||||
public void testRetryUpload_retryOnce() throws Exception {
|
||||
setup();
|
||||
AndroidMock.replay(chooseMapActivityMock);
|
||||
ChooseMapAsyncTaskMock chooseMapAsyncTaskTMock = new ChooseMapAsyncTaskMock(
|
||||
chooseMapActivityMock, account);
|
||||
chooseMapAsyncTaskTMock.setCanRetry(true);
|
||||
getMapsStatus = false;
|
||||
assertFalse(chooseMapAsyncTaskTMock.retryUpload());
|
||||
// Can only retry once.
|
||||
assertFalse(chooseMapAsyncTaskTMock.getCanRetry());
|
||||
AndroidMock.verify(chooseMapActivityMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link ChooseMapAsyncTask#retryUpload()}. Make sure will
|
||||
* not retry after get maps successfully.
|
||||
*/
|
||||
public void testRetryUpload_successGetMaps() throws Exception {
|
||||
setup();
|
||||
AndroidMock.replay(chooseMapActivityMock);
|
||||
ChooseMapAsyncTaskMock chooseMapAsyncTaskTMock = new ChooseMapAsyncTaskMock(
|
||||
chooseMapActivityMock, account);
|
||||
chooseMapAsyncTaskTMock.setCanRetry(true);
|
||||
getMapsStatus = true;
|
||||
assertTrue(chooseMapAsyncTaskTMock.retryUpload());
|
||||
// Can only retry once.
|
||||
assertFalse(chooseMapAsyncTaskTMock.getCanRetry());
|
||||
AndroidMock.verify(chooseMapActivityMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initials setup for test.
|
||||
*/
|
||||
void setup() {
|
||||
setupChooseMapActivityMock();
|
||||
account = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock object of ChooseMapActivity.
|
||||
*/
|
||||
@UsesMocks(ChooseMapActivity.class)
|
||||
private void setupChooseMapActivityMock() {
|
||||
chooseMapActivityMock = AndroidMock.createMock(ChooseMapActivity.class);
|
||||
// This is used in the constructor of ChooseMapAsyncTask.
|
||||
AndroidMock.expect(chooseMapActivityMock.getApplicationContext()).andReturn(getContext()).anyTimes();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.io.docs.SendDocsActivity;
|
||||
import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesActivity;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.UploadResultActivity;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests the {@link SendMapsActivity}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class SendMapsActivityTest extends AndroidTestCase {
|
||||
|
||||
private SendMapsActivity sendMapsActivity;
|
||||
private SendRequest sendRequest;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
sendRequest = new SendRequest(1L);
|
||||
sendMapsActivity = new SendMapsActivity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendMapsActivity#getNextClass(SendRequest, boolean)}. Sets the flags
|
||||
* of "sendFusionTables","sendDocs" and "cancel" to true, true and false.
|
||||
*/
|
||||
public void testGetNextClass_notCancelSendFusionTables() {
|
||||
sendRequest.setSendFusionTables(true);
|
||||
sendRequest.setSendDocs(true);
|
||||
Class<?> next = sendMapsActivity.getNextClass(sendRequest, false);
|
||||
assertEquals(SendFusionTablesActivity.class, next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendMapsActivity#getNextClass(SendRequest, boolean)}. Sets the flags
|
||||
* of "sendFusionTables","sendDocs" and "cancel" to false, true and false.
|
||||
*/
|
||||
public void testGetNextClass_notCancelSendDocs() {
|
||||
sendRequest.setSendFusionTables(false);
|
||||
sendRequest.setSendDocs(true);
|
||||
Class<?> next = sendMapsActivity.getNextClass(sendRequest, false);
|
||||
assertEquals(SendDocsActivity.class, next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendMapsActivity#getNextClass(SendRequest, boolean)}. Sets the flags
|
||||
* of "sendFusionTables","sendDocs" and "cancel" to false, false and false.
|
||||
*/
|
||||
public void testGetNextClass_notCancelNotSend() {
|
||||
sendRequest.setSendFusionTables(false);
|
||||
sendRequest.setSendDocs(false);
|
||||
Class<?> next = sendMapsActivity.getNextClass(sendRequest, false);
|
||||
assertEquals(UploadResultActivity.class, next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendMapsActivity#getNextClass(SendRequest, boolean)}. Sets the flags
|
||||
* of "sendFusionTables","sendDocs" and "cancel" to true, true and true.
|
||||
*/
|
||||
public void testGetNextClass_cancelSendDocs() {
|
||||
sendRequest.setSendFusionTables(true);
|
||||
sendRequest.setSendDocs(true);
|
||||
Class<?> next = sendMapsActivity.getNextClass(sendRequest, true);
|
||||
assertEquals(UploadResultActivity.class, next);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.TrackStubUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.io.gdata.maps.MapsGDataConverter;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
/**
|
||||
* Tests {@link SendMapsAsyncTask}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class SendMapsAsyncTaskTest extends AndroidTestCase {
|
||||
|
||||
private static final long TRACK_ID = 1;
|
||||
private static final String MAP_ID = "MapID_1";
|
||||
// Records the run times of {@link SendMapsAsyncTaskMock#uploadMarker(String,
|
||||
// String, String, Location)}
|
||||
private int uploadMarkerCounter = 0;
|
||||
// Records the run times of {@link
|
||||
// SendMapsAsyncTaskMock#prepareAndUploadPoints(Track, List<Location>,
|
||||
// boolean)}
|
||||
private int prepareAndUploadPointsCounter = 0;
|
||||
|
||||
private SendMapsActivity sendMapsActivityMock;
|
||||
private MyTracksProviderUtils myTracksProviderUtilsMock;
|
||||
private SendRequest sendRequest;
|
||||
|
||||
private class SendMapsAsyncTaskMock extends SendMapsAsyncTask {
|
||||
|
||||
private boolean[] uploadMarkerResult = { false, false };
|
||||
private boolean prepareAndUploadPointsResult = false;
|
||||
|
||||
private SendMapsAsyncTaskMock(SendMapsActivity activity, long trackId, Account account,
|
||||
String chooseMapId, MyTracksProviderUtils myTracksProviderUtils) {
|
||||
super(activity, trackId, account, chooseMapId, myTracksProviderUtils);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean uploadMarker(String title, String description, String iconUrl, Location location) {
|
||||
int runTimes = uploadMarkerCounter++;
|
||||
return uploadMarkerResult[runTimes];
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean prepareAndUploadPoints(Track track, List<Location> locations, boolean lastBatch) {
|
||||
prepareAndUploadPointsCounter++;
|
||||
return prepareAndUploadPointsResult;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@UsesMocks({ SendMapsActivity.class, MyTracksProviderUtils.class })
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
uploadMarkerCounter = 0;
|
||||
prepareAndUploadPointsCounter = 0;
|
||||
sendMapsActivityMock = AndroidMock.createMock(SendMapsActivity.class);
|
||||
myTracksProviderUtilsMock = AndroidMock.createMock(MyTracksProviderUtils.class);
|
||||
sendRequest = new SendRequest(TRACK_ID);
|
||||
AndroidMock.expect(sendMapsActivityMock.getApplicationContext()).andReturn(getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#saveResult()}and makes sure the
|
||||
* track is updated.
|
||||
*/
|
||||
public void testSaveResult() {
|
||||
Track track = TrackStubUtils.createTrack(1);
|
||||
track.setMapId(null);
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.getTrack(TRACK_ID)).andReturn(track);
|
||||
myTracksProviderUtilsMock.updateTrack(track);
|
||||
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), sendRequest.getMapId(),
|
||||
myTracksProviderUtilsMock);
|
||||
sendMapsAsyncTask.saveResult();
|
||||
assertEquals(sendRequest.getMapId(), track.getMapId());
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendMapsAsyncTask#fetchSendMapId(Track)} when chooseMapId is
|
||||
* null and makes sure it returns false.
|
||||
*/
|
||||
public void testFetchSendMapId_nullMapID() {
|
||||
Track track = TrackStubUtils.createTrack(1);
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
// Makes chooseMapId to null.
|
||||
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), null, myTracksProviderUtilsMock);
|
||||
// Returns false for an exception would be thrown.
|
||||
assertFalse(sendMapsAsyncTask.fetchSendMapId(track));
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#fetchSendMapId(Track)} when
|
||||
* chooseMapId is not null. And makes sure it returns false.
|
||||
*/
|
||||
public void testFetchSendMapId_notNullMapID() {
|
||||
Track track = TrackStubUtils.createTrack(1);
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
assertTrue(sendMapsAsyncTask.fetchSendMapId(track));
|
||||
assertEquals(MAP_ID, sendMapsAsyncTask.getMapId());
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
|
||||
* cursor is null. And makes sure it returns false.
|
||||
*/
|
||||
public void testUploadAllTrackPoints_nullCursor() {
|
||||
Track track = TrackStubUtils.createTrack(1);
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
|
||||
.andReturn(null);
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
assertFalse(sendMapsAsyncTask.uploadAllTrackPoints(track));
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
|
||||
* uploads the first marker is failed.
|
||||
*/
|
||||
@UsesMocks(Cursor.class)
|
||||
public void testUploadAllTrackPoints_uploadFirstMarkerFailed() {
|
||||
Track track = TrackStubUtils.createTrack(1);
|
||||
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
|
||||
AndroidMock.expect(cursorMock.getCount()).andReturn(2);
|
||||
AndroidMock.expect(cursorMock.moveToPosition(0)).andReturn(true);
|
||||
cursorMock.close();
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.createLocation(cursorMock)).andReturn(
|
||||
new Location("1"));
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
|
||||
.andReturn(cursorMock);
|
||||
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
SendMapsAsyncTaskMock sendMapsAsyncTask = new SendMapsAsyncTaskMock(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
sendMapsAsyncTask.uploadMarkerResult[0] = false;
|
||||
assertFalse(sendMapsAsyncTask.uploadAllTrackPoints(track));
|
||||
assertEquals(1, uploadMarkerCounter);
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
|
||||
* uploads the two markers is successful but failed when
|
||||
* prepareAndUploadPoints.
|
||||
*/
|
||||
@UsesMocks(Cursor.class)
|
||||
public void testUploadAllTrackPoints_prepareAndUploadPointsFailed() {
|
||||
Track track = TrackStubUtils.createTrack(1);
|
||||
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
|
||||
AndroidMock.expect(cursorMock.getCount()).andReturn(2);
|
||||
AndroidMock.expect(cursorMock.moveToPosition(0)).andReturn(true);
|
||||
AndroidMock.expect(cursorMock.moveToPosition(1)).andReturn(true);
|
||||
cursorMock.close();
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.createLocation(cursorMock))
|
||||
.andReturn(new Location("1")).times(2);
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
|
||||
.andReturn(cursorMock);
|
||||
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
SendMapsAsyncTaskMock sendMapsAsyncTask = new SendMapsAsyncTaskMock(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
// For will be failed when run prepareAndUploadPoints, it no require to
|
||||
// set uploadMarkerResult[1].
|
||||
sendMapsAsyncTask.uploadMarkerResult[0] = true;
|
||||
sendMapsAsyncTask.prepareAndUploadPointsResult = false;
|
||||
assertFalse(sendMapsAsyncTask.uploadAllTrackPoints(track));
|
||||
assertEquals(1, uploadMarkerCounter);
|
||||
assertEquals(1, prepareAndUploadPointsCounter);
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
|
||||
* uploads the last marker is failed.
|
||||
*/
|
||||
@UsesMocks(Cursor.class)
|
||||
public void testUploadAllTrackPoints_uploadLastMarkerFailed() {
|
||||
Track track = TrackStubUtils.createTrack(1);
|
||||
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
|
||||
AndroidMock.expect(cursorMock.getCount()).andReturn(2);
|
||||
AndroidMock.expect(cursorMock.moveToPosition(0)).andReturn(true);
|
||||
AndroidMock.expect(cursorMock.moveToPosition(1)).andReturn(true);
|
||||
cursorMock.close();
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.createLocation(cursorMock))
|
||||
.andReturn(new Location("1")).times(2);
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
|
||||
.andReturn(cursorMock);
|
||||
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
SendMapsAsyncTaskMock sendMapsAsyncTask = new SendMapsAsyncTaskMock(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
sendMapsAsyncTask.uploadMarkerResult[0] = true;
|
||||
sendMapsAsyncTask.uploadMarkerResult[1] = false;
|
||||
sendMapsAsyncTask.prepareAndUploadPointsResult = true;
|
||||
assertFalse(sendMapsAsyncTask.uploadAllTrackPoints(track));
|
||||
assertEquals(2, uploadMarkerCounter);
|
||||
assertEquals(1, prepareAndUploadPointsCounter);
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#uploadAllTrackPoints(Track)} when
|
||||
* return true.
|
||||
*/
|
||||
@UsesMocks(Cursor.class)
|
||||
public void testUploadAllTrackPoints_success() {
|
||||
Track track = TrackStubUtils.createTrack(1);
|
||||
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
|
||||
AndroidMock.expect(cursorMock.getCount()).andReturn(2);
|
||||
AndroidMock.expect(cursorMock.moveToPosition(0)).andReturn(true);
|
||||
AndroidMock.expect(cursorMock.moveToPosition(1)).andReturn(true);
|
||||
cursorMock.close();
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.createLocation(cursorMock))
|
||||
.andReturn(new Location("1")).times(2);
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.getLocationsCursor(TRACK_ID, 0, -1, false))
|
||||
.andReturn(cursorMock);
|
||||
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
SendMapsAsyncTaskMock sendMapsAsyncTask = new SendMapsAsyncTaskMock(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
sendMapsAsyncTask.uploadMarkerResult[0] = true;
|
||||
sendMapsAsyncTask.uploadMarkerResult[1] = true;
|
||||
sendMapsAsyncTask.prepareAndUploadPointsResult = true;
|
||||
assertTrue(sendMapsAsyncTask.uploadAllTrackPoints(track));
|
||||
assertEquals(2, uploadMarkerCounter);
|
||||
assertEquals(1, prepareAndUploadPointsCounter);
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#uploadWaypoints()} when cursor is
|
||||
* null.
|
||||
*/
|
||||
@UsesMocks(Cursor.class)
|
||||
public void testUploadWaypoints_nullCursor() {
|
||||
AndroidMock.expect(
|
||||
myTracksProviderUtilsMock.getWaypointsCursor(TRACK_ID, 0,
|
||||
Constants.MAX_LOADED_WAYPOINTS_POINTS)).andReturn(null);
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
assertTrue(sendMapsAsyncTask.uploadWaypoints());
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#uploadWaypoints()} when there is
|
||||
* only one point.
|
||||
*/
|
||||
@UsesMocks(Cursor.class)
|
||||
public void testUploadWaypoints_onePoint() {
|
||||
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
|
||||
AndroidMock.expect(cursorMock.moveToFirst()).andReturn(true);
|
||||
// Only one point, so next is null.
|
||||
AndroidMock.expect(cursorMock.moveToNext()).andReturn(false);
|
||||
cursorMock.close();
|
||||
|
||||
AndroidMock.expect(
|
||||
myTracksProviderUtilsMock.getWaypointsCursor(TRACK_ID, 0,
|
||||
Constants.MAX_LOADED_WAYPOINTS_POINTS)).andReturn(cursorMock);
|
||||
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
|
||||
assertTrue(sendMapsAsyncTask.uploadWaypoints());
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#uploadWaypoints()}. Makes sure a cursor is created and
|
||||
* a way point is created with such cursor.
|
||||
*
|
||||
* @throws XmlPullParserException
|
||||
*/
|
||||
@UsesMocks(Cursor.class)
|
||||
public void testUploadWaypoints() throws XmlPullParserException {
|
||||
Cursor cursorMock = AndroidMock.createMock(Cursor.class);
|
||||
MapsGDataConverter mapsGDataConverterMock = new MapsGDataConverter();
|
||||
|
||||
AndroidMock.expect(cursorMock.moveToFirst()).andReturn(true);
|
||||
AndroidMock.expect(cursorMock.moveToNext()).andReturn(true);
|
||||
cursorMock.close();
|
||||
|
||||
AndroidMock.expect(
|
||||
myTracksProviderUtilsMock.getWaypointsCursor(TRACK_ID, 0,
|
||||
Constants.MAX_LOADED_WAYPOINTS_POINTS)).andReturn(cursorMock);
|
||||
Waypoint waypoint = new Waypoint();
|
||||
waypoint.setLocation(TrackStubUtils.createMyTracksLocation());
|
||||
AndroidMock.expect(myTracksProviderUtilsMock.createWaypoint(cursorMock)).andReturn(waypoint)
|
||||
.times(1);
|
||||
|
||||
AndroidMock.replay(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
SendMapsAsyncTask sendMapsAsyncTask = new SendMapsAsyncTask(sendMapsActivityMock,
|
||||
sendRequest.getTrackId(), sendRequest.getAccount(), MAP_ID, myTracksProviderUtilsMock);
|
||||
sendMapsAsyncTask.setMapsGDataConverter(mapsGDataConverterMock);
|
||||
// Would be failed for there is no source for uploading.
|
||||
assertFalse(sendMapsAsyncTask.uploadWaypoints());
|
||||
AndroidMock.verify(sendMapsActivityMock, myTracksProviderUtilsMock, cursorMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendMapsAsyncTask#getPercentage(int, int)}.
|
||||
*/
|
||||
public void testCountPercentage() {
|
||||
assertEquals(SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MIN, SendMapsAsyncTask.getPercentage(0, 5));
|
||||
assertEquals(SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MAX,
|
||||
SendMapsAsyncTask.getPercentage(50, 50));
|
||||
assertEquals(
|
||||
(int) ((double) 5
|
||||
/ 11
|
||||
* (SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MAX - SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MIN) + SendMapsAsyncTask.PROGRESS_UPLOAD_DATA_MIN),
|
||||
SendMapsAsyncTask.getPercentage(5, 11));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.io.gdata.maps.MapsFeature;
|
||||
import com.google.android.maps.GeoPoint;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests {@link SendMapsUtils}.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class SendMapsUtilsTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Tests {@link SendMapsUtils#getMapUrl(Track)} with null track.
|
||||
*/
|
||||
public void testGetMapUrl_null_track() {
|
||||
assertEquals(null, SendMapsUtils.getMapUrl(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendMapsUtils#getMapUrl(Track)} with null map id.
|
||||
*/
|
||||
public void testGetMapUrl_null_map_id() {
|
||||
Track track = new Track();
|
||||
track.setMapId(null);
|
||||
assertEquals(null, SendMapsUtils.getMapUrl(track));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendMapsUtils#getMapUrl(Track)} with a valid track.
|
||||
*/
|
||||
public void testGetMapUrl_valid_track() {
|
||||
Track track = new Track();
|
||||
track.setMapId("123");
|
||||
assertEquals("https://maps.google.com/maps/ms?msa=0&msid=123", SendMapsUtils.getMapUrl(track));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link SendMapsUtils#buildMapsMarkerFeature(String, String, String,
|
||||
* GeoPoint)} with a title.
|
||||
*/
|
||||
public void testBuildMapsMarkerFeature_with_title() {
|
||||
MapsFeature mapFeature = SendMapsUtils.buildMapsMarkerFeature(
|
||||
"name", "this\nmap\ndescription", "url", new GeoPoint(123, 456));
|
||||
assertEquals(MapsFeature.MARKER, mapFeature.getType());
|
||||
assertNotNull(mapFeature.getAndroidId());
|
||||
assertEquals("name", mapFeature.getTitle());
|
||||
assertEquals("this<br>map<br>description", mapFeature.getDescription());
|
||||
assertEquals("url", mapFeature.getIconUrl());
|
||||
assertEquals(123, mapFeature.getPoint(0).getLatitudeE6());
|
||||
assertEquals(456, mapFeature.getPoint(0).getLongitudeE6());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link SendMapsUtils#buildMapsMarkerFeature(String, String, String,
|
||||
* GeoPoint)} with an empty title.
|
||||
*/
|
||||
public void testBuildMapsMarkerFeature_empty_title() {
|
||||
MapsFeature mapFeature = SendMapsUtils.buildMapsMarkerFeature(
|
||||
"", "description", "url", new GeoPoint(123, 456));
|
||||
assertEquals(MapsFeature.MARKER, mapFeature.getType());
|
||||
assertNotNull(mapFeature.getAndroidId());
|
||||
assertEquals("-", mapFeature.getTitle());
|
||||
assertEquals("description", mapFeature.getDescription());
|
||||
assertEquals("url", mapFeature.getIconUrl());
|
||||
assertEquals(123, mapFeature.getPoint(0).getLatitudeE6());
|
||||
assertEquals(456, mapFeature.getPoint(0).getLongitudeE6());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link SendMapsUtils#buildMapsMarkerFeature(String, String, String,
|
||||
* GeoPoint)} with a null title.
|
||||
*/
|
||||
public void testBuildMapsMarkerFeature_null_title() {
|
||||
MapsFeature mapFeature = SendMapsUtils.buildMapsMarkerFeature(
|
||||
null, "description", "url", new GeoPoint(123, 456));
|
||||
assertEquals(MapsFeature.MARKER, mapFeature.getType());
|
||||
assertNotNull(mapFeature.getAndroidId());
|
||||
assertEquals("-", mapFeature.getTitle());
|
||||
assertEquals("description", mapFeature.getDescription());
|
||||
assertEquals("url", mapFeature.getIconUrl());
|
||||
assertEquals(123, mapFeature.getPoint(0).getLatitudeE6());
|
||||
assertEquals(456, mapFeature.getPoint(0).getLongitudeE6());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link SendMapsUtils#buildMapsLineFeature(String, ArrayList)} with a
|
||||
* title.
|
||||
*/
|
||||
public void testBuildMapsLineFeature_with_title() {
|
||||
ArrayList<Location> locations = new ArrayList<Location>();
|
||||
Location location = new Location("test");
|
||||
location.setLatitude(50);
|
||||
location.setLongitude(100);
|
||||
locations.add(location);
|
||||
MapsFeature mapFeature = SendMapsUtils.buildMapsLineFeature("name", locations);
|
||||
|
||||
assertEquals(MapsFeature.LINE, mapFeature.getType());
|
||||
assertNotNull(mapFeature.getAndroidId());
|
||||
assertEquals("name", mapFeature.getTitle());
|
||||
assertEquals(0x80FF0000, mapFeature.getColor());
|
||||
assertEquals(50000000, mapFeature.getPoint(0).getLatitudeE6());
|
||||
assertEquals(100000000, mapFeature.getPoint(0).getLongitudeE6());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link SendMapsUtils#buildMapsLineFeature(String, ArrayList)} with an
|
||||
* empty title.
|
||||
*/
|
||||
public void testBuildMapsLineFeature_empty_title() {
|
||||
ArrayList<Location> locations = new ArrayList<Location>();
|
||||
Location location = new Location("test");
|
||||
location.setLatitude(50);
|
||||
location.setLongitude(100);
|
||||
locations.add(location);
|
||||
MapsFeature mapFeature = SendMapsUtils.buildMapsLineFeature("", locations);
|
||||
|
||||
assertEquals(MapsFeature.LINE, mapFeature.getType());
|
||||
assertNotNull(mapFeature.getAndroidId());
|
||||
assertEquals("-", mapFeature.getTitle());
|
||||
assertEquals(0x80FF0000, mapFeature.getColor());
|
||||
assertEquals(50000000, mapFeature.getPoint(0).getLatitudeE6());
|
||||
assertEquals(100000000, mapFeature.getPoint(0).getLongitudeE6());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link SendMapsUtils#buildMapsLineFeature(String, ArrayList)} with a
|
||||
* null title.
|
||||
*/
|
||||
public void testBuildMapsLineFeature_null_title() {
|
||||
ArrayList<Location> locations = new ArrayList<Location>();
|
||||
Location location = new Location("test");
|
||||
location.setLatitude(50);
|
||||
location.setLongitude(100);
|
||||
locations.add(location);
|
||||
MapsFeature mapFeature = SendMapsUtils.buildMapsLineFeature(null, locations);
|
||||
|
||||
assertEquals(MapsFeature.LINE, mapFeature.getType());
|
||||
assertNotNull(mapFeature.getAndroidId());
|
||||
assertEquals("-", mapFeature.getTitle());
|
||||
assertEquals(0x80FF0000, mapFeature.getColor());
|
||||
assertEquals(50000000, mapFeature.getPoint(0).getLatitudeE6());
|
||||
assertEquals(100000000, mapFeature.getPoint(0).getLongitudeE6());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link SendMapsUtils#getGeoPoint(Location)}.
|
||||
*/
|
||||
public void testGeoPoint() {
|
||||
Location location = new Location("test");
|
||||
location.setLatitude(50);
|
||||
location.setLongitude(100);
|
||||
GeoPoint geoPoint = SendMapsUtils.getGeoPoint(location);
|
||||
assertEquals(50000000, geoPoint.getLatitudeE6());
|
||||
assertEquals(100000000, geoPoint.getLongitudeE6());
|
||||
}
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.sendtogoogle;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests the {@link SendRequest}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class SendRequestTest extends AndroidTestCase {
|
||||
private SendRequest sendRequest;
|
||||
|
||||
final static private String ACCOUNTNAME = "testAccount1";
|
||||
final static private String ACCOUNTYPE = "testType1";
|
||||
final static private String MAPID = "mapId1";
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
sendRequest = new SendRequest(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendRequest#getTrackId()}. The value should be set
|
||||
* to 1 when it is initialed in setup method.
|
||||
*/
|
||||
public void testGetTrackId() {
|
||||
assertEquals(1, sendRequest.getTrackId());
|
||||
}
|
||||
|
||||
public void testIsSendMaps() {
|
||||
assertEquals(false, sendRequest.isSendMaps());
|
||||
sendRequest.setSendMaps(true);
|
||||
assertEquals(true, sendRequest.isSendMaps());
|
||||
}
|
||||
|
||||
public void testIsSendFusionTables() {
|
||||
assertEquals(false, sendRequest.isSendFusionTables());
|
||||
sendRequest.setSendFusionTables(true);
|
||||
assertEquals(true, sendRequest.isSendFusionTables());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendRequest#isSendDocs()}. The value should be set
|
||||
* to false which is its default value when it is initialed in setup method.
|
||||
*/
|
||||
public void testIsSendDocs() {
|
||||
assertEquals(false, sendRequest.isSendDocs());
|
||||
sendRequest.setSendDocs(true);
|
||||
assertEquals(true, sendRequest.isSendDocs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendRequest#isNewMap()}. The value should be set to
|
||||
* false which is its default value when it is initialed in setup method.
|
||||
*/
|
||||
public void testIsNewMap() {
|
||||
assertEquals(false, sendRequest.isNewMap());
|
||||
sendRequest.setNewMap(true);
|
||||
assertEquals(true, sendRequest.isNewMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendRequest#getAccount()}. The value should be set
|
||||
* to null which is its default value when it is initialed in setup method.
|
||||
*/
|
||||
public void testGetAccount() {
|
||||
assertEquals(null, sendRequest.getAccount());
|
||||
Account account = new Account(ACCOUNTNAME, ACCOUNTYPE);
|
||||
sendRequest.setAccount(account);
|
||||
assertEquals(account, sendRequest.getAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendRequest#getMapId()}. The value should be set to
|
||||
* null which is its default value when it is initialed in setup method.
|
||||
*/
|
||||
public void testGetMapId() {
|
||||
assertEquals(null, sendRequest.getMapId());
|
||||
sendRequest.setMapId("1");
|
||||
assertEquals("1", "1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendRequest#isMapsSuccess()}. The value should be
|
||||
* set to false which is its default value when it is initialed in setup
|
||||
* method.
|
||||
*/
|
||||
public void testIsMapsSuccess() {
|
||||
assertEquals(false, sendRequest.isMapsSuccess());
|
||||
sendRequest.setMapsSuccess(true);
|
||||
assertEquals(true, sendRequest.isMapsSuccess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendRequest#isFusionTablesSuccess()}. The value
|
||||
* should be set to false which is its default value when it is initialed in
|
||||
* setup method.
|
||||
*/
|
||||
public void testIsFusionTablesSuccess() {
|
||||
assertEquals(false, sendRequest.isFusionTablesSuccess());
|
||||
sendRequest.setFusionTablesSuccess(true);
|
||||
assertEquals(true, sendRequest.isFusionTablesSuccess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link SendRequest#isDocsSuccess()}. The value should be
|
||||
* set to false which is its default value when it is initialed in setup
|
||||
* method.
|
||||
*/
|
||||
public void testIsDocsSuccess() {
|
||||
assertEquals(false, sendRequest.isDocsSuccess());
|
||||
sendRequest.setDocsSuccess(true);
|
||||
assertEquals(true, sendRequest.isDocsSuccess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SendRequest.CREATOR.createFromParcel when all values are true.
|
||||
*/
|
||||
public void testCreateFromParcel_true() {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.setDataPosition(0);
|
||||
parcel.writeLong(2);
|
||||
parcel.writeString("");
|
||||
parcel.writeString("");
|
||||
parcel.writeByte((byte) 1);
|
||||
parcel.writeByte((byte) 1);
|
||||
parcel.writeByte((byte) 1);
|
||||
parcel.writeByte((byte) 1);
|
||||
Account account = new Account(ACCOUNTNAME, ACCOUNTYPE);
|
||||
parcel.writeParcelable(account, 0);
|
||||
parcel.writeString(MAPID);
|
||||
parcel.writeByte((byte) 1);
|
||||
parcel.writeByte((byte) 1);
|
||||
parcel.writeByte((byte) 1);
|
||||
parcel.setDataPosition(0);
|
||||
sendRequest = SendRequest.CREATOR.createFromParcel(parcel);
|
||||
assertEquals(2, sendRequest.getTrackId());
|
||||
assertEquals("", sendRequest.getSharingAppPackageName());
|
||||
assertEquals("", sendRequest.getSharingAppClassName());
|
||||
assertTrue(sendRequest.isSendMaps());
|
||||
assertTrue(sendRequest.isSendFusionTables());
|
||||
assertTrue(sendRequest.isSendDocs());
|
||||
assertTrue(sendRequest.isNewMap());
|
||||
assertEquals(account, sendRequest.getAccount());
|
||||
assertEquals(MAPID, sendRequest.getMapId());
|
||||
assertTrue(sendRequest.isMapsSuccess());
|
||||
assertTrue(sendRequest.isFusionTablesSuccess());
|
||||
assertTrue(sendRequest.isDocsSuccess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests SendRequest.CREATOR.createFromParcel when all values are false.
|
||||
*/
|
||||
public void testCreateFromParcel_false() {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.setDataPosition(0);
|
||||
parcel.writeLong(4);
|
||||
parcel.writeString(null);
|
||||
parcel.writeString(null);
|
||||
parcel.writeByte((byte) 0);
|
||||
parcel.writeByte((byte) 0);
|
||||
parcel.writeByte((byte) 0);
|
||||
parcel.writeByte((byte) 0);
|
||||
Account account = new Account(ACCOUNTNAME, ACCOUNTYPE);
|
||||
parcel.writeParcelable(account, 0);
|
||||
parcel.writeString(MAPID);
|
||||
parcel.writeByte((byte) 0);
|
||||
parcel.writeByte((byte) 0);
|
||||
parcel.writeByte((byte) 0);
|
||||
parcel.setDataPosition(0);
|
||||
sendRequest = SendRequest.CREATOR.createFromParcel(parcel);
|
||||
assertEquals(4, sendRequest.getTrackId());
|
||||
assertNull(sendRequest.getSharingAppPackageName());
|
||||
assertNull(sendRequest.getSharingAppClassName());
|
||||
assertFalse(sendRequest.isSendMaps());
|
||||
assertFalse(sendRequest.isSendFusionTables());
|
||||
assertFalse(sendRequest.isSendDocs());
|
||||
assertFalse(sendRequest.isNewMap());
|
||||
assertEquals(account, sendRequest.getAccount());
|
||||
assertEquals(MAPID, sendRequest.getMapId());
|
||||
assertFalse(sendRequest.isMapsSuccess());
|
||||
assertFalse(sendRequest.isFusionTablesSuccess());
|
||||
assertFalse(sendRequest.isDocsSuccess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendRequest#writeToParcel(Parcel, int)} with default values.
|
||||
*/
|
||||
public void testWriteToParcel_default() {
|
||||
sendRequest = new SendRequest(1);
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.setDataPosition(0);
|
||||
sendRequest.writeToParcel(parcel, 1);
|
||||
parcel.setDataPosition(0);
|
||||
long trackId = parcel.readLong();
|
||||
String sharingAppPackageName = parcel.readString();
|
||||
String sharingAppClassName = parcel.readString();
|
||||
boolean sendMaps = parcel.readByte() == 1;
|
||||
boolean sendFusionTables = parcel.readByte() == 1;
|
||||
boolean sendDocs = parcel.readByte() == 1;
|
||||
boolean newMap = parcel.readByte() == 1;
|
||||
Parcelable account = parcel.readParcelable(null);
|
||||
String mapId = parcel.readString();
|
||||
boolean mapsSuccess = parcel.readByte() == 1;
|
||||
boolean fusionTablesSuccess = parcel.readByte() == 1;
|
||||
boolean docsSuccess = parcel.readByte() == 1;
|
||||
assertEquals(1, trackId);
|
||||
assertNull(sharingAppPackageName);
|
||||
assertNull(sharingAppClassName);
|
||||
assertFalse(sendMaps);
|
||||
assertFalse(sendFusionTables);
|
||||
assertFalse(sendDocs);
|
||||
assertFalse(newMap);
|
||||
assertNull(account);
|
||||
assertNull(mapId);
|
||||
assertFalse(mapsSuccess);
|
||||
assertFalse(fusionTablesSuccess);
|
||||
assertFalse(docsSuccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SendRequest#writeToParcel(Parcel, int)}.
|
||||
*/
|
||||
public void testWriteToParcel() {
|
||||
sendRequest = new SendRequest(4);
|
||||
sendRequest.setSharingAppPackageName("package");
|
||||
sendRequest.setSharingAppClassName("class");
|
||||
sendRequest.setSendMaps(true);
|
||||
sendRequest.setSendFusionTables(true);
|
||||
sendRequest.setSendDocs(true);
|
||||
sendRequest.setNewMap(true);
|
||||
Account accountNew = new Account(ACCOUNTNAME + "2", ACCOUNTYPE + "2");
|
||||
sendRequest.setAccount(accountNew);
|
||||
sendRequest.setMapId(MAPID);
|
||||
sendRequest.setMapsSuccess(true);
|
||||
sendRequest.setFusionTablesSuccess(true);
|
||||
sendRequest.setDocsSuccess(true);
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.setDataPosition(0);
|
||||
sendRequest.writeToParcel(parcel, 1);
|
||||
parcel.setDataPosition(0);
|
||||
long trackId = parcel.readLong();
|
||||
String sharingAppPackageName = parcel.readString();
|
||||
String sharingAppClassName = parcel.readString();
|
||||
boolean sendMaps = parcel.readByte() == 1;
|
||||
boolean sendFusionTables = parcel.readByte() == 1;
|
||||
boolean sendDocs = parcel.readByte() == 1;
|
||||
boolean newMap = parcel.readByte() == 1;
|
||||
Parcelable account = parcel.readParcelable(null);
|
||||
String mapId = parcel.readString();
|
||||
boolean mapsSuccess = parcel.readByte() == 1;
|
||||
boolean fusionTablesSuccess = parcel.readByte() == 1;
|
||||
boolean docsSuccess = parcel.readByte() == 1;
|
||||
assertEquals(4, trackId);
|
||||
assertEquals("package", sharingAppPackageName);
|
||||
assertEquals("class", sharingAppClassName);
|
||||
assertTrue(sendMaps);
|
||||
assertTrue(sendFusionTables);
|
||||
assertTrue(sendDocs);
|
||||
assertTrue(newMap);
|
||||
assertEquals(accountNew, account);
|
||||
assertEquals(MAPID, mapId);
|
||||
assertTrue(mapsSuccess);
|
||||
assertTrue(fusionTablesSuccess);
|
||||
assertTrue(docsSuccess);
|
||||
}
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.sendtogoogle;
|
||||
|
||||
/**
|
||||
* Tests the {@link SendToGoogleUtils}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
import com.google.android.apps.mytracks.TrackStubUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SendToGoogleUtilsTest extends TestCase {
|
||||
|
||||
private final static long TRACK_ID = 1L;
|
||||
private final static String TRACK_CATEGORY = "trackCategory";
|
||||
private final static String TRACK_NAME = "trackName";
|
||||
private final static double DIFFERENCE = 0.02;
|
||||
private final static double INVALID_LATITUDE = 91;
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
|
||||
* when there is only one location in a segment.
|
||||
*/
|
||||
public void testPrepareTrackSegment_onlyOneLocation() {
|
||||
Track trackStub = TrackStubUtils.createTrack(1);
|
||||
assertFalse(SendToGoogleUtils.prepareTrackSegment(trackStub, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendToGoogleUtils#prepareTrackSegment(Track, ArrayList)} when there
|
||||
* is no stop time.
|
||||
*/
|
||||
public void testPrepareTrackSegment_noStopTime() {
|
||||
Track trackStub = TrackStubUtils.createTrack(2);
|
||||
assertEquals(-1L, trackStub.getTripStatistics().getStopTime());
|
||||
|
||||
ArrayList<Track> tracksArray = new ArrayList<Track>();
|
||||
assertTrue(SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray));
|
||||
assertEquals(trackStub, tracksArray.get(0));
|
||||
// The stop time should be the time of last location
|
||||
assertEquals(
|
||||
trackStub.getLocations().get(1).getTime(), trackStub.getTripStatistics().getStopTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
|
||||
* when there is stop time.
|
||||
*/
|
||||
public void testPrepareTrackSegment_hasStopTime() {
|
||||
Track trackStub = TrackStubUtils.createTrack(2);
|
||||
// Gives a margin to make sure the this time will be not same with the last
|
||||
// location in the track.
|
||||
long stopTime = System.currentTimeMillis() + 1000;
|
||||
trackStub.getTripStatistics().setStopTime(stopTime);
|
||||
|
||||
ArrayList<Track> tracksArray = new ArrayList<Track>();
|
||||
SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray);
|
||||
assertEquals(trackStub, tracksArray.get(0));
|
||||
assertEquals(stopTime, trackStub.getTripStatistics().getStopTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendToGoogleUtils#prepareLocations(Track, java.util.List)} .
|
||||
*/
|
||||
public void testPrepareLocations() {
|
||||
Track trackStub = TrackStubUtils.createTrack(2);
|
||||
trackStub.setId(TRACK_ID);
|
||||
trackStub.setName(TRACK_NAME);
|
||||
trackStub.setCategory(TRACK_CATEGORY);
|
||||
|
||||
List<Location> locationsArray = new ArrayList<Location>();
|
||||
// Adds 100 location to List.
|
||||
for (int i = 0; i < 100; i++) {
|
||||
// Use this variable as a flag to make all points in the track can be kept
|
||||
// after run the LocationUtils#decimate(Track, double) with
|
||||
// Ramer–Douglas–Peucker algorithm.
|
||||
double latitude = TrackStubUtils.INITIAL_LATITUDE;
|
||||
if (i % 2 == 0) {
|
||||
latitude -= DIFFERENCE * (i % 10);
|
||||
}
|
||||
// Inserts 9 points which have wrong latitude, so would have 10 segments.
|
||||
if (i % 10 == 0 && i > 0) {
|
||||
MyTracksLocation location = TrackStubUtils.createMyTracksLocation();
|
||||
location.setLatitude(INVALID_LATITUDE);
|
||||
locationsArray.add(location);
|
||||
} else {
|
||||
locationsArray.add(TrackStubUtils.createMyTracksLocation(latitude,
|
||||
TrackStubUtils.INITIAL_LONGITUDE + DIFFERENCE * (i % 10),
|
||||
TrackStubUtils.INITIAL_ALTITUDE + DIFFERENCE * (i % 10)));
|
||||
}
|
||||
}
|
||||
ArrayList<Track> result = SendToGoogleUtils.prepareLocations(trackStub, locationsArray);
|
||||
assertEquals(10, result.size());
|
||||
// Checks all segments.
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Track segmentOne = result.get(i);
|
||||
assertEquals(TRACK_ID, segmentOne.getId());
|
||||
assertEquals(TRACK_NAME, segmentOne.getName());
|
||||
assertEquals(TRACK_CATEGORY, segmentOne.getCategory());
|
||||
}
|
||||
// Checks all locations in the first segment.
|
||||
for (int j = 0; j < 9; j++) {
|
||||
double latitude = TrackStubUtils.INITIAL_LATITUDE;
|
||||
if (j % 2 == 0) {
|
||||
latitude -= DIFFERENCE * (j % 10);
|
||||
}
|
||||
Location oneLocation = result.get(0).getLocations().get(j);
|
||||
assertEquals(TrackStubUtils.createMyTracksLocation().getAltitude() + DIFFERENCE * (j % 10),
|
||||
oneLocation.getAltitude());
|
||||
assertEquals(latitude, oneLocation.getLatitude());
|
||||
assertEquals(TrackStubUtils.createMyTracksLocation().getLongitude() + DIFFERENCE * (j % 10),
|
||||
oneLocation.getLongitude());
|
||||
}
|
||||
}
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.io.sendtogoogle;
|
||||
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Intent;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Tests the {@link UploadResultActivity}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class UploadResultActivityTest extends
|
||||
ActivityInstrumentationTestCase2<UploadResultActivity> {
|
||||
|
||||
private UploadResultActivity uploadResultActivity;
|
||||
private TextView errorFooter;
|
||||
private TextView successFooter;
|
||||
private LinearLayout mapsResult;
|
||||
private LinearLayout fusionTablesResult;
|
||||
private LinearLayout docsResult;
|
||||
private ImageView mapsResultIcon;
|
||||
private ImageView fusionTablesResultIcon;
|
||||
private ImageView docsResultIcon;
|
||||
|
||||
private String successTitle;
|
||||
private String errorTitle;
|
||||
|
||||
/**
|
||||
* This method is necessary for ActivityInstrumentationTestCase2.
|
||||
*/
|
||||
@TargetApi(8)
|
||||
public UploadResultActivityTest() {
|
||||
super(UploadResultActivity.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the display of dialog when send to all and all sends are successful.
|
||||
*/
|
||||
public void testAllSuccess() {
|
||||
initialActivity(true, true, true, true, true, true);
|
||||
createDialogAndGetViews();
|
||||
assertEquals(View.VISIBLE, successFooter.getVisibility());
|
||||
assertEquals(View.GONE, errorFooter.getVisibility());
|
||||
|
||||
assertEquals(View.VISIBLE, mapsResult.getVisibility());
|
||||
assertEquals(View.VISIBLE, fusionTablesResult.getVisibility());
|
||||
assertEquals(View.VISIBLE, docsResult.getVisibility());
|
||||
|
||||
assertEquals(successTitle, mapsResultIcon.getContentDescription());
|
||||
assertEquals(successTitle, fusionTablesResultIcon.getContentDescription());
|
||||
assertEquals(successTitle, docsResultIcon.getContentDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the display of dialog when send to all and all sends are failed.
|
||||
*/
|
||||
public void testAllFailed() {
|
||||
// Send all kinds but all failed.
|
||||
initialActivity(true, true, true, false, false, false);
|
||||
createDialogAndGetViews();
|
||||
assertEquals(View.GONE, successFooter.getVisibility());
|
||||
assertEquals(View.VISIBLE, errorFooter.getVisibility());
|
||||
|
||||
assertEquals(View.VISIBLE, mapsResult.getVisibility());
|
||||
assertEquals(View.VISIBLE, fusionTablesResult.getVisibility());
|
||||
assertEquals(View.VISIBLE, docsResult.getVisibility());
|
||||
|
||||
assertEquals(errorTitle, mapsResultIcon.getContentDescription());
|
||||
assertEquals(errorTitle, fusionTablesResultIcon.getContentDescription());
|
||||
assertEquals(errorTitle, docsResultIcon.getContentDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the display of dialog when match following items:
|
||||
* <ul>
|
||||
* <li>Only send to Maps and Docs.</li>
|
||||
* <li>Send to Maps successful.</li>
|
||||
* <li>Send to Docs failed.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void testPartialSuccess() {
|
||||
initialActivity(true, false, true, true, false, false);
|
||||
createDialogAndGetViews();
|
||||
assertEquals(View.VISIBLE, errorFooter.getVisibility());
|
||||
|
||||
assertEquals(View.VISIBLE, mapsResult.getVisibility());
|
||||
assertEquals(View.GONE, fusionTablesResult.getVisibility());
|
||||
assertEquals(View.VISIBLE, docsResult.getVisibility());
|
||||
|
||||
assertEquals(successTitle, mapsResultIcon.getContentDescription());
|
||||
assertEquals(errorTitle, docsResultIcon.getContentDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initials a {@link SendRequest} and then initials a activity to be tested.
|
||||
*
|
||||
* @param isSendMaps
|
||||
* @param isSendFusionTables
|
||||
* @param isSendDocs
|
||||
* @param isMapsSuccess
|
||||
* @param isFusionTablesSuccess
|
||||
* @param isDocsSuccess
|
||||
*/
|
||||
private void initialActivity(boolean isSendMaps, boolean isSendFusionTables, boolean isSendDocs,
|
||||
boolean isMapsSuccess, boolean isFusionTablesSuccess, boolean isDocsSuccess) {
|
||||
Intent intent = new Intent();
|
||||
SendRequest sendRequest = new SendRequest(1L);
|
||||
sendRequest.setSendMaps(isSendMaps);
|
||||
sendRequest.setSendFusionTables(isSendFusionTables);
|
||||
sendRequest.setSendDocs(isSendDocs);
|
||||
sendRequest.setMapsSuccess(isMapsSuccess);
|
||||
sendRequest.setFusionTablesSuccess(isFusionTablesSuccess);
|
||||
sendRequest.setDocsSuccess(isDocsSuccess);
|
||||
intent.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
|
||||
setActivityIntent(intent);
|
||||
uploadResultActivity = this.getActivity();
|
||||
successTitle = uploadResultActivity.getString(R.string.generic_success_title);
|
||||
errorTitle = uploadResultActivity.getString(R.string.generic_error_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates result dialog and gets views in the dialog.
|
||||
*/
|
||||
private void createDialogAndGetViews() {
|
||||
uploadResultActivity.onCreateDialog(UploadResultActivity.DIALOG_RESULT_ID);
|
||||
View view = uploadResultActivity.view;
|
||||
errorFooter = (TextView) view.findViewById(R.id.upload_result_error_footer);
|
||||
successFooter = (TextView) view.findViewById(R.id.upload_result_success_footer);
|
||||
|
||||
mapsResult = (LinearLayout) view.findViewById(R.id.upload_result_maps_result);
|
||||
fusionTablesResult = (LinearLayout) view.findViewById(R.id.upload_result_fusion_tables_result);
|
||||
docsResult = (LinearLayout) view.findViewById(R.id.upload_result_docs_result);
|
||||
|
||||
mapsResultIcon = (ImageView) view.findViewById(R.id.upload_result_maps_result_icon);
|
||||
fusionTablesResultIcon = (ImageView) view
|
||||
.findViewById(R.id.upload_result_fusion_tables_result_icon);
|
||||
docsResultIcon = (ImageView) view.findViewById(R.id.upload_result_docs_result_icon);
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests for the {@link DynamicSpeedTrackPathDescriptor}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class DynamicSpeedTrackPathDescriptorTest extends AndroidTestCase {
|
||||
|
||||
private Context context;
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
context = getContext();
|
||||
sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link DynamicSpeedTrackPathDescriptor#getSpeedMargin()}
|
||||
* with zero, normal and illegal value.
|
||||
*/
|
||||
public void testGetSpeedMargin() {
|
||||
// The default value of speedMargin is 25.
|
||||
int[] expectations = { 0, 50, 99, 25 };
|
||||
// Test
|
||||
for (int i = 0; i < expectations.length; i++) {
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_percentage_key, expectations[i]);
|
||||
DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor(
|
||||
context);
|
||||
assertEquals(expectations[i], dynamicSpeedTrackPathDescriptor.getSpeedMargin());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the key is null.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_nullKey() {
|
||||
DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor(
|
||||
context);
|
||||
int speedMargin = dynamicSpeedTrackPathDescriptor.getSpeedMargin();
|
||||
// Change value in shared preferences.
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_percentage_key, speedMargin + 2);
|
||||
|
||||
dynamicSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, null);
|
||||
assertEquals(speedMargin, dynamicSpeedTrackPathDescriptor.getSpeedMargin());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the key is not null, and not trackColorModeDynamicVariation.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_otherKey() {
|
||||
DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor(
|
||||
context);
|
||||
int speedMargin = dynamicSpeedTrackPathDescriptor.getSpeedMargin();
|
||||
// Change value in shared preferences.
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_percentage_key, speedMargin + 2);
|
||||
dynamicSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, "anyKey");
|
||||
assertEquals(speedMargin, dynamicSpeedTrackPathDescriptor.getSpeedMargin());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the key is trackColorModeDynamicVariation.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_trackColorModeDynamicVariationKey() {
|
||||
DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor(
|
||||
context);
|
||||
int speedMargin = dynamicSpeedTrackPathDescriptor.getSpeedMargin();
|
||||
// Change value in shared preferences.
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_percentage_key, speedMargin + 2);
|
||||
|
||||
dynamicSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences,
|
||||
PreferencesUtils.getKey(context, R.string.track_color_mode_percentage_key));
|
||||
assertEquals(speedMargin + 2, dynamicSpeedTrackPathDescriptor.getSpeedMargin());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the values of speedMargin is the default value.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_defaultValue() {
|
||||
DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor(
|
||||
context);
|
||||
// Change value in shared preferences
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_percentage_key,
|
||||
PreferencesUtils.TRACK_COLOR_MODE_PERCENTAGE_DEFAULT);
|
||||
dynamicSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences,
|
||||
PreferencesUtils.getKey(context, R.string.track_color_mode_percentage_key));
|
||||
// The default value of speedMargin is 25.
|
||||
assertEquals(PreferencesUtils.TRACK_COLOR_MODE_PERCENTAGE_DEFAULT,
|
||||
dynamicSpeedTrackPathDescriptor.getSpeedMargin());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#needsRedraw()} by wrong track
|
||||
* id.
|
||||
*/
|
||||
public void testNeedsRedraw_WrongTrackId() {
|
||||
PreferencesUtils.setLong(
|
||||
context, R.string.selected_track_id_key, PreferencesUtils.SELECTED_TRACK_ID_DEFAULT);
|
||||
DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor(
|
||||
context);
|
||||
assertEquals(false, dynamicSpeedTrackPathDescriptor.needsRedraw());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#needsRedraw()} by different
|
||||
* averageMovingSpeed.
|
||||
*/
|
||||
public void testIsDiffereceSignificant() {
|
||||
DynamicSpeedTrackPathDescriptor dynamicSpeedTrackPathDescriptor = new DynamicSpeedTrackPathDescriptor(
|
||||
context);
|
||||
double[] averageMovingSpeeds = { 0, 30, 30, 30 };
|
||||
double[] newAverageMovingSpeed = { 20, 30,
|
||||
// Difference is less than CRITICAL_DIFFERENCE_PERCENTAGE
|
||||
30 * (1 + (DynamicSpeedTrackPathDescriptor.CRITICAL_DIFFERENCE_PERCENTAGE / 100) / 2),
|
||||
// Difference is more than CRITICAL_DIFFERENCE_PERCENTAGE
|
||||
30 * (1 + (DynamicSpeedTrackPathDescriptor.CRITICAL_DIFFERENCE_PERCENTAGE / 100.00) * 2) };
|
||||
boolean[] expectedValues = { true, false, false, true };
|
||||
double[] expectedAverageMovingSpeed = { 20, 30, 30,
|
||||
30 * (1 + (DynamicSpeedTrackPathDescriptor.CRITICAL_DIFFERENCE_PERCENTAGE / 100.00) * 2) };
|
||||
// Test
|
||||
for (int i = 0; i < newAverageMovingSpeed.length; i++) {
|
||||
dynamicSpeedTrackPathDescriptor.setAverageMovingSpeed(averageMovingSpeeds[i]);
|
||||
assertEquals(expectedValues[i], dynamicSpeedTrackPathDescriptor.isDifferenceSignificant(
|
||||
averageMovingSpeeds[i], newAverageMovingSpeed[i]));
|
||||
assertEquals(
|
||||
expectedAverageMovingSpeed[i], dynamicSpeedTrackPathDescriptor.getAverageMovingSpeed());
|
||||
}
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.ColoredPath;
|
||||
import com.google.android.apps.mytracks.MapOverlay.CachedLocation;
|
||||
import com.google.android.apps.mytracks.TrackStubUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for the {@link DynamicSpeedTrackPathPainter}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class DynamicSpeedTrackPathPainterTest extends TrackPathPainterTestCase {
|
||||
|
||||
private DynamicSpeedTrackPathPainter dynamicSpeedTrackPathPainter;
|
||||
private TrackPathDescriptor trackPathDescriptor;
|
||||
// This number must bigger than 10 to meet the requirement of test.
|
||||
private static final int NUMBER_OF_LOCATIONS = 100;
|
||||
private static final int LOCATIONS_PER_SEGMENT = 25;
|
||||
// The maximum speed(KM/H) which is considered slow.
|
||||
private static final int SLOW_SPEED_KMH = 30;
|
||||
// The maximum speed(KM/H) which is considered normal.
|
||||
private static final int NORMAL_SPEED_KMH = 50;
|
||||
|
||||
// Convert from kilometers per hour to meters per second
|
||||
private static final double KMH_TO_MS = 1 / 3.6;
|
||||
private static final int SLOW_SPEED_MS = (int) (SLOW_SPEED_KMH * KMH_TO_MS);
|
||||
private static final int NORMAL_SPEED_MS = (int) (NORMAL_SPEED_KMH * KMH_TO_MS);
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
initialTrackPathDescriptorMock();
|
||||
dynamicSpeedTrackPathPainter = new DynamicSpeedTrackPathPainter(getContext(),
|
||||
trackPathDescriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link DynamicSpeedTrackPathPainter#updatePath(com.google.android.maps.Projection, android.graphics.Rect, int, Boolean, java.util.List)}
|
||||
* when all locations are invalid.
|
||||
*/
|
||||
public void testUpdatePath_AllInvalidLocation() {
|
||||
List<CachedLocation> points = createCachedLocations(NUMBER_OF_LOCATIONS, INVALID_LATITUDE, -1);
|
||||
dynamicSpeedTrackPathPainter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), 1, true, points);
|
||||
AndroidMock.verify(trackPathDescriptor);
|
||||
// Should be zero for there is no valid locations.
|
||||
assertEquals(0, dynamicSpeedTrackPathPainter.getColoredPaths().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the
|
||||
* {@link DynamicSpeedTrackPathPainter#updatePath(com.google.android.maps.Projection, android.graphics.Rect, int, Boolean, java.util.List)}
|
||||
* when all locations are valid.
|
||||
*/
|
||||
public void testUpdatePath_AllValidLocation() {
|
||||
List<CachedLocation> points = createCachedLocations(NUMBER_OF_LOCATIONS,
|
||||
TrackStubUtils.INITIAL_LATITUDE, -1);
|
||||
|
||||
// Gets a number as the start index of points.
|
||||
int startLocationIdx = NUMBER_OF_LOCATIONS / 2;
|
||||
dynamicSpeedTrackPathPainter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, true, points);
|
||||
|
||||
AndroidMock.verify(trackPathDescriptor);
|
||||
assertEquals(NUMBER_OF_LOCATIONS - startLocationIdx, dynamicSpeedTrackPathPainter
|
||||
.getColoredPaths().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the
|
||||
* {@link DynamicSpeedTrackPathPainter#updatePath(com.google.android.maps.Projection, android.graphics.Rect, int, Boolean, java.util.List)}
|
||||
* when all locations are valid. This test setups 4 segments with 25 points
|
||||
* each. The first segment has slow speed, the second segment has normal
|
||||
* speed, the third segment has fast speed, and the fourth segment has slow
|
||||
* speed.
|
||||
*/
|
||||
public void testUpdatePath_CheckColoredPath() {
|
||||
// Gets the slow speed. Divide SLOW_SPEED by 2 to make it smaller than
|
||||
// SLOW_SPEED. Speed in MyTracksLocation use MS, but speed in CachedLocation
|
||||
// use KMH.
|
||||
int slowSpeed = SLOW_SPEED_MS / 2;
|
||||
// Gets the normal speed. Makes it smaller than SLOW_SPEED and bigger than
|
||||
// NORMAL_SPEED. Speed in MyTracksLocation use MS, but speed in
|
||||
// CachedLocation use KMH.
|
||||
int normalSpeed = (SLOW_SPEED_MS + NORMAL_SPEED_MS) / 2;
|
||||
// Gets the fast speed. Multiply it by 2 to make it bigger than
|
||||
// NORMAL_SPEED. Speed in MyTracksLocation use MS, but speed in
|
||||
// CachedLocation use KMH.
|
||||
int fastSpeed = NORMAL_SPEED_MS * 2;
|
||||
|
||||
// Get a number of startLocationIdx. And divide NUMBER_OF_LOCATIONS by 8 to
|
||||
// make sure it is less than numberOfFirstThreeSegments.
|
||||
int startLocationIdx = LOCATIONS_PER_SEGMENT / 2;
|
||||
|
||||
List<CachedLocation> points = createCachedLocations(LOCATIONS_PER_SEGMENT,
|
||||
TrackStubUtils.INITIAL_LATITUDE, slowSpeed);
|
||||
points.addAll(createCachedLocations(LOCATIONS_PER_SEGMENT, TrackStubUtils.INITIAL_LATITUDE,
|
||||
normalSpeed));
|
||||
points.addAll(createCachedLocations(LOCATIONS_PER_SEGMENT, TrackStubUtils.INITIAL_LATITUDE,
|
||||
fastSpeed));
|
||||
points.addAll(createCachedLocations(LOCATIONS_PER_SEGMENT, TrackStubUtils.INITIAL_LATITUDE,
|
||||
slowSpeed));
|
||||
|
||||
dynamicSpeedTrackPathPainter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, true, points);
|
||||
|
||||
AndroidMock.verify(trackPathDescriptor);
|
||||
List<ColoredPath> coloredPath = dynamicSpeedTrackPathPainter.getColoredPaths();
|
||||
assertEquals(NUMBER_OF_LOCATIONS - startLocationIdx, coloredPath.size());
|
||||
|
||||
// Checks different speeds with different color in the coloredPath.
|
||||
for (int i = 0; i < NUMBER_OF_LOCATIONS - startLocationIdx; i++) {
|
||||
if (i < LOCATIONS_PER_SEGMENT - startLocationIdx) {
|
||||
// Slow.
|
||||
assertEquals(getContext().getResources().getColor(R.color.slow_path), coloredPath.get(i)
|
||||
.getPathPaint().getColor());
|
||||
} else if (i < LOCATIONS_PER_SEGMENT * 2 - startLocationIdx) {
|
||||
// Normal.
|
||||
assertEquals(getContext().getResources().getColor(R.color.normal_path), coloredPath.get(i)
|
||||
.getPathPaint().getColor());
|
||||
} else if (i < LOCATIONS_PER_SEGMENT * 3 - startLocationIdx) {
|
||||
// Fast.
|
||||
assertEquals(getContext().getResources().getColor(R.color.fast_path), coloredPath.get(i)
|
||||
.getPathPaint().getColor());
|
||||
} else {
|
||||
// Slow.
|
||||
assertEquals(getContext().getResources().getColor(R.color.slow_path), coloredPath.get(i)
|
||||
.getPathPaint().getColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initials a mocked TrackPathDescriptor object.
|
||||
*/
|
||||
@UsesMocks(TrackPathDescriptor.class)
|
||||
private void initialTrackPathDescriptorMock() {
|
||||
trackPathDescriptor = AndroidMock.createMock(TrackPathDescriptor.class);
|
||||
AndroidMock.expect(trackPathDescriptor.getSlowSpeed()).andReturn(SLOW_SPEED_KMH);
|
||||
AndroidMock.expect(trackPathDescriptor.getNormalSpeed()).andReturn(NORMAL_SPEED_KMH);
|
||||
AndroidMock.replay(trackPathDescriptor);
|
||||
}
|
||||
|
||||
}
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests for the {@link DynamicSpeedTrackPathDescriptor}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class FixedSpeedTrackPathDescriptorTest extends AndroidTestCase {
|
||||
|
||||
private Context context;
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
context = getContext();
|
||||
sharedPreferences = context.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the initialization of slowSpeed and normalSpeed in {@link DynamicSpeedTrackPathDescriptor#DynamicSpeedTrackPathDescriptor(Context)}
|
||||
* .
|
||||
*/
|
||||
public void testConstructor() {
|
||||
int[] slowSpeedExpectations = { 0, 1, 99, PreferencesUtils.TRACK_COLOR_MODE_SLOW_DEFAULT };
|
||||
int[] normalSpeedExpectations = { 0, 1, 99, PreferencesUtils.TRACK_COLOR_MODE_MEDIUM_DEFAULT };
|
||||
for (int i = 0; i < slowSpeedExpectations.length; i++) {
|
||||
PreferencesUtils.setInt(
|
||||
context, R.string.track_color_mode_slow_key, slowSpeedExpectations[i]);
|
||||
PreferencesUtils.setInt(
|
||||
context, R.string.track_color_mode_medium_key, normalSpeedExpectations[i]);
|
||||
FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor(
|
||||
context);
|
||||
assertEquals(slowSpeedExpectations[i], fixedSpeedTrackPathDescriptor.getSlowSpeed());
|
||||
assertEquals(normalSpeedExpectations[i], fixedSpeedTrackPathDescriptor.getNormalSpeed());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the key is null.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_null_key() {
|
||||
FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor(
|
||||
context);
|
||||
int slowSpeed = fixedSpeedTrackPathDescriptor.getSlowSpeed();
|
||||
int normalSpeed = fixedSpeedTrackPathDescriptor.getNormalSpeed();
|
||||
// Change value in shared preferences
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_slow_key, slowSpeed + 2);
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_medium_key, normalSpeed + 2);
|
||||
fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, null);
|
||||
assertEquals(slowSpeed, fixedSpeedTrackPathDescriptor.getSlowSpeed());
|
||||
assertEquals(normalSpeed, fixedSpeedTrackPathDescriptor.getNormalSpeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the key is not null, and not slowSpeed and not normalSpeed.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_other_key() {
|
||||
FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor(
|
||||
context);
|
||||
int slowSpeed = fixedSpeedTrackPathDescriptor.getSlowSpeed();
|
||||
int normalSpeed = fixedSpeedTrackPathDescriptor.getNormalSpeed();
|
||||
// Change value in shared preferences
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_slow_key, slowSpeed + 2);
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_medium_key, normalSpeed + 2);
|
||||
fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(sharedPreferences, "anyKey");
|
||||
assertEquals(slowSpeed, fixedSpeedTrackPathDescriptor.getSlowSpeed());
|
||||
assertEquals(normalSpeed, fixedSpeedTrackPathDescriptor.getNormalSpeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the key is slowSpeed.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_slowSpeedKey() {
|
||||
FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor(
|
||||
context);
|
||||
int slowSpeed = fixedSpeedTrackPathDescriptor.getSlowSpeed();
|
||||
// Change value in shared preferences
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_slow_key, slowSpeed + 2);
|
||||
fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(
|
||||
sharedPreferences, context.getString(R.string.track_color_mode_slow_key));
|
||||
assertEquals(slowSpeed + 2, fixedSpeedTrackPathDescriptor.getSlowSpeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the key is normalSpeed.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_normalSpeedKey() {
|
||||
FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor(
|
||||
context);
|
||||
int normalSpeed = fixedSpeedTrackPathDescriptor.getNormalSpeed();
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_medium_key, normalSpeed + 4);
|
||||
fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(
|
||||
sharedPreferences, context.getString(R.string.track_color_mode_medium_key));
|
||||
assertEquals(normalSpeed + 4, fixedSpeedTrackPathDescriptor.getNormalSpeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link DynamicSpeedTrackPathDescriptor#onSharedPreferenceChanged(SharedPreferences,
|
||||
* String)} when the values of slowSpeed and normalSpeed in SharedPreference
|
||||
* are the default values.
|
||||
*/
|
||||
public void testOnSharedPreferenceChanged_defaultValue() {
|
||||
FixedSpeedTrackPathDescriptor fixedSpeedTrackPathDescriptor = new FixedSpeedTrackPathDescriptor(
|
||||
context);
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_slow_key,
|
||||
PreferencesUtils.TRACK_COLOR_MODE_SLOW_DEFAULT);
|
||||
PreferencesUtils.setInt(context, R.string.track_color_mode_medium_key,
|
||||
PreferencesUtils.TRACK_COLOR_MODE_MEDIUM_DEFAULT);
|
||||
fixedSpeedTrackPathDescriptor.onSharedPreferenceChanged(
|
||||
sharedPreferences, context.getString(R.string.track_color_mode_medium_key));
|
||||
assertEquals(PreferencesUtils.TRACK_COLOR_MODE_SLOW_DEFAULT,
|
||||
fixedSpeedTrackPathDescriptor.getSlowSpeed());
|
||||
assertEquals(PreferencesUtils.TRACK_COLOR_MODE_MEDIUM_DEFAULT,
|
||||
fixedSpeedTrackPathDescriptor.getNormalSpeed());
|
||||
}
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.MapOverlay.CachedLocation;
|
||||
import com.google.android.apps.mytracks.TrackStubUtils;
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
|
||||
import android.graphics.Path;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for the {@link SingleColorTrackPathPainter}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class SingleColorTrackPathPainterTest extends TrackPathPainterTestCase {
|
||||
|
||||
private SingleColorTrackPathPainter singleColorTrackPathPainter;
|
||||
private Path pathMock;
|
||||
private static final int NUMBER_OF_LOCATIONS = 100;
|
||||
|
||||
/**
|
||||
* Initials a mocked TrackPathDescriptor object and
|
||||
* singleColorTrackPathPainter.
|
||||
*/
|
||||
@Override
|
||||
@UsesMocks(Path.class)
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
pathMock = AndroidMock.createStrictMock(Path.class);
|
||||
singleColorTrackPathPainter = new SingleColorTrackPathPainter(getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the
|
||||
* {@link SingleColorTrackPathPainter#updatePath(com.google.android.maps.Projection, android.graphics.Rect, int, Boolean, List, Path)}
|
||||
* method when all locations are valid.
|
||||
*/
|
||||
public void testUpdatePath_AllValidLocation() {
|
||||
pathMock.incReserve(NUMBER_OF_LOCATIONS);
|
||||
List<CachedLocation> points = createCachedLocations(NUMBER_OF_LOCATIONS,
|
||||
TrackStubUtils.INITIAL_LATITUDE, -1);
|
||||
// Gets a number as the start index of points.
|
||||
int startLocationIdx = NUMBER_OF_LOCATIONS / 2;
|
||||
|
||||
for (int i = startLocationIdx; i < NUMBER_OF_LOCATIONS; i++) {
|
||||
pathMock.lineTo(0, 0);
|
||||
}
|
||||
|
||||
AndroidMock.replay(pathMock);
|
||||
singleColorTrackPathPainter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, true, points, pathMock);
|
||||
AndroidMock.verify(pathMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the
|
||||
* {@link SingleColorTrackPathPainter#updatePath(com.google.android.maps.Projection, android.graphics.Rect, int, Boolean, List, Path)}
|
||||
* method when all locations are invalid.
|
||||
*/
|
||||
public void testUpdatePath_AllInvalidLocation() {
|
||||
pathMock.incReserve(NUMBER_OF_LOCATIONS);
|
||||
List<CachedLocation> points = createCachedLocations(NUMBER_OF_LOCATIONS, INVALID_LATITUDE, -1);
|
||||
// Gets a random number from 1 to numberOfLocations.
|
||||
int startLocationIdx = NUMBER_OF_LOCATIONS / 2;
|
||||
AndroidMock.replay(pathMock);
|
||||
singleColorTrackPathPainter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, true, points, pathMock);
|
||||
AndroidMock.verify(pathMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the
|
||||
* {@link SingleColorTrackPathPainter#updatePath(com.google.android.maps.Projection, android.graphics.Rect, int, Boolean, List, Path)}
|
||||
* method when there are three segments.
|
||||
*/
|
||||
public void testUpdatePath_ThreeSegments() {
|
||||
// First segment.
|
||||
List<CachedLocation> points = createCachedLocations(NUMBER_OF_LOCATIONS,
|
||||
TrackStubUtils.INITIAL_LATITUDE, -1);
|
||||
points.addAll(createCachedLocations(1, INVALID_LATITUDE, -1));
|
||||
// Second segment.
|
||||
points.addAll(createCachedLocations(NUMBER_OF_LOCATIONS, TrackStubUtils.INITIAL_LATITUDE, -1));
|
||||
points.addAll(createCachedLocations(1, INVALID_LATITUDE, -1));
|
||||
// Third segment.
|
||||
points.addAll(createCachedLocations(NUMBER_OF_LOCATIONS, TrackStubUtils.INITIAL_LATITUDE, -1));
|
||||
// Gets a random number from 1 to numberOfLocations.
|
||||
int startLocationIdx = NUMBER_OF_LOCATIONS / 2;
|
||||
pathMock.incReserve(NUMBER_OF_LOCATIONS *3 + 1 +1);
|
||||
for (int i = 0; i < NUMBER_OF_LOCATIONS - startLocationIdx; i++) {
|
||||
pathMock.lineTo(0, 0);
|
||||
}
|
||||
pathMock.moveTo(0, 0);
|
||||
for (int i = 0; i < NUMBER_OF_LOCATIONS - 1; i++) {
|
||||
pathMock.lineTo(0, 0);
|
||||
}
|
||||
pathMock.moveTo(0, 0);
|
||||
for (int i = 0; i < NUMBER_OF_LOCATIONS - 1; i++) {
|
||||
pathMock.lineTo(0, 0);
|
||||
}
|
||||
|
||||
AndroidMock.replay(pathMock);
|
||||
singleColorTrackPathPainter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, true, points, pathMock);
|
||||
AndroidMock.verify(pathMock);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* Tests for the MyTracks track path descriptors and painters.
|
||||
*
|
||||
* @author Vangelis S.
|
||||
*/
|
||||
public class TrackPathDescriptorDynamicSpeedTest extends TrackPathPainterTestCase {
|
||||
|
||||
public void testDynamicSpeedTrackPathDescriptor() throws Exception {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
location = new Location("gps");
|
||||
location.setLatitude(20 + i / 2);
|
||||
location.setLongitude(150 - i);
|
||||
myTracksOverlay.addLocation(location);
|
||||
}
|
||||
|
||||
TrackPathPainter painter = new DynamicSpeedTrackPathPainter(
|
||||
getContext(), new DynamicSpeedTrackPathDescriptor(getContext()));
|
||||
myTracksOverlay.setTrackPathPainter(painter);
|
||||
|
||||
int startLocationIdx = 0;
|
||||
Boolean alwaysVisible = true;
|
||||
|
||||
assertNotNull(painter);
|
||||
painter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible,
|
||||
myTracksOverlay.getPoints());
|
||||
assertNotNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
painter.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* Tests for the MyTracks track path descriptors and painters.
|
||||
*
|
||||
* @author Vangelis S.
|
||||
*/
|
||||
public class TrackPathDescriptorFixedSpeedTest extends TrackPathPainterTestCase {
|
||||
|
||||
public void testFixedSpeedTrackPathDescriptor() throws Exception {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
location = new Location("gps");
|
||||
location.setLatitude(20 + i / 2);
|
||||
location.setLongitude(150 - i);
|
||||
myTracksOverlay.addLocation(location);
|
||||
}
|
||||
|
||||
TrackPathPainter painter = new DynamicSpeedTrackPathPainter(
|
||||
getContext(), new FixedSpeedTrackPathDescriptor(getContext()));
|
||||
myTracksOverlay.setTrackPathPainter(painter);
|
||||
|
||||
int startLocationIdx = 0;
|
||||
Boolean alwaysVisible = true;
|
||||
|
||||
assertNotNull(painter);
|
||||
painter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible,
|
||||
myTracksOverlay.getPoints());
|
||||
assertNotNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
painter.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* Tests for the MyTracks track path painter factory.
|
||||
*
|
||||
* @author Vangelis S.
|
||||
*/
|
||||
public class TrackPathPainterFactoryTest extends TrackPathPainterTestCase {
|
||||
|
||||
public void testTrackPathPainterFactory() throws Exception {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
location = new Location("gps");
|
||||
location.setLatitude(20 + i / 2);
|
||||
location.setLongitude(150 - i);
|
||||
myTracksOverlay.addLocation(location);
|
||||
}
|
||||
|
||||
Context context = getContext();
|
||||
|
||||
testTrackPathPainterFactorySpecific(context,
|
||||
R.string.settings_map_track_color_mode_single_value, SingleColorTrackPathPainter.class);
|
||||
testTrackPathPainterFactorySpecific(context, R.string.settings_map_track_color_mode_fixed_value,
|
||||
DynamicSpeedTrackPathPainter.class);
|
||||
testTrackPathPainterFactorySpecific(context,
|
||||
R.string.settings_map_track_color_mode_dynamic_value, DynamicSpeedTrackPathPainter.class);
|
||||
}
|
||||
|
||||
private <T> void testTrackPathPainterFactorySpecific(
|
||||
Context context, int track_color_mode, Class<?> c) {
|
||||
PreferencesUtils.setString(
|
||||
context, R.string.track_color_mode_key, context.getString(track_color_mode));
|
||||
|
||||
int startLocationIdx = 0;
|
||||
Boolean alwaysVisible = true;
|
||||
|
||||
TrackPathPainter painter = TrackPathPainterFactory.getTrackPathPainter(context);
|
||||
myTracksOverlay.setTrackPathPainter(painter);
|
||||
|
||||
assertNotNull(painter);
|
||||
assertTrue(c.isInstance(painter));
|
||||
|
||||
painter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible,
|
||||
myTracksOverlay.getPoints());
|
||||
assertNotNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
painter.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* Tests for the MyTracks track path descriptors and painters.
|
||||
*
|
||||
* @author Vangelis S.
|
||||
*/
|
||||
public class TrackPathPainterSingleColorTest extends TrackPathPainterTestCase {
|
||||
|
||||
public void testSimpeColorTrackPathPainter() throws Exception {
|
||||
Location location = new Location("gps");
|
||||
location.setLatitude(10);
|
||||
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
location = new Location("gps");
|
||||
location.setLatitude(20 + i / 2);
|
||||
location.setLongitude(150 - i);
|
||||
myTracksOverlay.addLocation(location);
|
||||
}
|
||||
|
||||
TrackPathPainter painter = new SingleColorTrackPathPainter(getContext());
|
||||
myTracksOverlay.setTrackPathPainter(painter);
|
||||
|
||||
int startLocationIdx = 0;
|
||||
Boolean alwaysVisible = true;
|
||||
|
||||
assertNotNull(painter);
|
||||
painter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible,
|
||||
myTracksOverlay.getPoints());
|
||||
assertNotNull(myTracksOverlay.getTrackPathPainter().getLastPath());
|
||||
painter.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.MapOverlay;
|
||||
import com.google.android.apps.mytracks.MapOverlay.CachedLocation;
|
||||
import com.google.android.apps.mytracks.MockMyTracksOverlay;
|
||||
import com.google.android.apps.mytracks.TrackStubUtils;
|
||||
import com.google.android.maps.MapView;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.location.Location;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for the MyTracks track path descriptors and painters.
|
||||
*
|
||||
* @author Vangelis S.
|
||||
*/
|
||||
public class TrackPathPainterTestCase extends AndroidTestCase {
|
||||
|
||||
protected Canvas canvas;
|
||||
protected MockMyTracksOverlay myTracksOverlay;
|
||||
protected MapView mockView;
|
||||
|
||||
final int INVALID_LATITUDE = 100;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
canvas = new Canvas();
|
||||
myTracksOverlay = new MockMyTracksOverlay(getContext());
|
||||
// Enable drawing.
|
||||
myTracksOverlay.setTrackDrawingEnabled(true);
|
||||
mockView = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list of CachedLocations.
|
||||
*
|
||||
* @param number the number of locations
|
||||
* @param latitude the latitude value of locations.
|
||||
* @param speed the speed(meter per second) of locations, and will give a default valid value if
|
||||
* less than zero
|
||||
* @return the simulated locations
|
||||
*/
|
||||
List<CachedLocation> createCachedLocations(int number, double latitude, float speed) {
|
||||
List<CachedLocation> points = new ArrayList<MapOverlay.CachedLocation>();
|
||||
for (int i = 0; i < number; ++i) {
|
||||
Location location = TrackStubUtils.createMyTracksLocation(latitude,
|
||||
TrackStubUtils.INITIAL_LONGITUDE, TrackStubUtils.INITIAL_ALTITUDE);
|
||||
if (speed > 0) {
|
||||
location.setSpeed(speed);
|
||||
}
|
||||
CachedLocation cachedLocation = new CachedLocation(location);
|
||||
points.add(cachedLocation);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests the {@link AdaptiveLocationListenerPolicy}.
|
||||
*
|
||||
* @author youtaol
|
||||
*/
|
||||
public class AdaptiveLocationListenerPolicyTest extends TestCase {
|
||||
|
||||
private AdaptiveLocationListenerPolicy adocationListenerPolicy;
|
||||
private static final long MIN = 1000;
|
||||
private static final long MAX = 3000;
|
||||
private static final int MIN_DISTANCE = 10;
|
||||
private static final long NEW_IDLE_TIME_BIG = 10000;
|
||||
private static final long NEW_IDLE_TIME_NORMAL = 5000;
|
||||
private static final long NEW_IDLE_TIME_SMALL = 2000;
|
||||
private static final long NEW_IDLE_TIME_LESS_THAN_MIN = 500;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
adocationListenerPolicy = new AdaptiveLocationListenerPolicy(MIN, MAX, MIN_DISTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the
|
||||
* {@link AdaptiveLocationListenerPolicy#getDesiredPollingInterval()} in four
|
||||
* situations.
|
||||
* <ul>
|
||||
* <li>The newIdleTime is bigger than max interval.</li>
|
||||
* <li>The newIdleTime is between min and max interval.</li>
|
||||
* <li>The newIdleTime is smaller than max interval.</li>
|
||||
* <li>The newIdleTime is smaller than the smallest interval unit.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void testGetDesiredPollingInterval() {
|
||||
adocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_BIG);
|
||||
assertEquals(MAX, adocationListenerPolicy.getDesiredPollingInterval());
|
||||
|
||||
adocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_NORMAL);
|
||||
// First get the half of NEW_IDLE_TIME_NORMAL, and then round it to the
|
||||
// nearest second.
|
||||
assertEquals((NEW_IDLE_TIME_NORMAL / 2 / 1000) * 1000,
|
||||
adocationListenerPolicy.getDesiredPollingInterval());
|
||||
|
||||
adocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_SMALL);
|
||||
assertEquals(MIN, adocationListenerPolicy.getDesiredPollingInterval());
|
||||
|
||||
adocationListenerPolicy.updateIdleTime(NEW_IDLE_TIME_LESS_THAN_MIN);
|
||||
assertEquals(MIN, adocationListenerPolicy.getDesiredPollingInterval());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method {@link AdaptiveLocationListenerPolicy#getMinDistance()}.
|
||||
*/
|
||||
public void testGetMinDistance() {
|
||||
assertEquals(MIN_DISTANCE, adocationListenerPolicy.getMinDistance());
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.maps.mytracks.R;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.RemoteException;
|
||||
import android.test.ServiceTestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
|
||||
/**
|
||||
* Tests {@link ControlRecordingService}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class ControlRecordingServiceTest extends ServiceTestCase<ControlRecordingService> {
|
||||
|
||||
private Context context;
|
||||
private ControlRecordingService controlRecordingService;
|
||||
|
||||
public ControlRecordingServiceTest() {
|
||||
super(ControlRecordingService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
context = getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the start of {@link ControlRecordingService} and tests the method
|
||||
* {@link ControlRecordingService#onHandleIntent(Intent, ITrackRecordingService)}
|
||||
* to start a track recording.
|
||||
*/
|
||||
@UsesMocks(ITrackRecordingService.class)
|
||||
public void testStartRecording() {
|
||||
assertNull(controlRecordingService);
|
||||
Intent intent = startControlRecordingService(context.getString(R.string.track_action_start));
|
||||
assertNotNull(controlRecordingService);
|
||||
|
||||
ITrackRecordingService iTrackRecordingServiceMock = EasyMock
|
||||
.createStrictMock(ITrackRecordingService.class);
|
||||
try {
|
||||
EasyMock.expect(iTrackRecordingServiceMock.startNewTrack()).andReturn(1L);
|
||||
EasyMock.replay(iTrackRecordingServiceMock);
|
||||
controlRecordingService.onHandleIntent(intent, iTrackRecordingServiceMock);
|
||||
EasyMock.verify(iTrackRecordingServiceMock);
|
||||
} catch (RemoteException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link ControlRecordingService#onHandleIntent(Intent, ITrackRecordingService)}
|
||||
* to stop a track recording.
|
||||
*/
|
||||
@UsesMocks(ITrackRecordingService.class)
|
||||
public void testStopRecording() {
|
||||
Intent intent = startControlRecordingService(context.getString(R.string.track_action_end));
|
||||
|
||||
ITrackRecordingService iTrackRecordingServiceMock = EasyMock
|
||||
.createStrictMock(ITrackRecordingService.class);
|
||||
try {
|
||||
iTrackRecordingServiceMock.endCurrentTrack();
|
||||
EasyMock.replay(iTrackRecordingServiceMock);
|
||||
controlRecordingService.onHandleIntent(intent, iTrackRecordingServiceMock);
|
||||
EasyMock.verify(iTrackRecordingServiceMock);
|
||||
} catch (RemoteException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a ControlRecordingService with a specified action.
|
||||
*
|
||||
* @param action the action string in the start intent
|
||||
*/
|
||||
private Intent startControlRecordingService(String action) {
|
||||
Intent intent = new Intent(context, ControlRecordingService.class);
|
||||
intent.setAction(action);
|
||||
startService(intent);
|
||||
controlRecordingService = getService();
|
||||
return intent;
|
||||
}
|
||||
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import static com.google.android.testing.mocking.AndroidMock.expect;
|
||||
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Tests {@link RemoveTempFilesService}.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class RemoveTempFilesServiceTest extends AndroidTestCase {
|
||||
|
||||
private static final String DIR_NAME = "/tmp";
|
||||
private static final String FILE_NAME = "foo";
|
||||
|
||||
private RemoveTempFilesService service;
|
||||
|
||||
@UsesMocks({ File.class, })
|
||||
protected void setUp() throws Exception {
|
||||
service = new RemoveTempFilesService();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests when the directory doesn't exists.
|
||||
*/
|
||||
public void test_noDir() {
|
||||
File dir = AndroidMock.createMock(File.class, DIR_NAME);
|
||||
expect(dir.exists()).andStubReturn(false);
|
||||
AndroidMock.replay(dir);
|
||||
|
||||
assertEquals(0, service.cleanTempDirectory(dir));
|
||||
AndroidMock.verify(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests when the directory is empty.
|
||||
*/
|
||||
public void test_emptyDir() {
|
||||
File dir = AndroidMock.createMock(File.class, DIR_NAME);
|
||||
expect(dir.exists()).andStubReturn(true);
|
||||
expect(dir.listFiles()).andStubReturn(new File[0]);
|
||||
AndroidMock.replay(dir);
|
||||
|
||||
assertEquals(0, service.cleanTempDirectory(dir));
|
||||
AndroidMock.verify(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests when there is a new file and it shouldn't get deleted.
|
||||
*/
|
||||
public void test_newFile() {
|
||||
File file = AndroidMock.createMock(File.class, DIR_NAME + FILE_NAME);
|
||||
expect(file.lastModified()).andStubReturn(System.currentTimeMillis());
|
||||
|
||||
File dir = AndroidMock.createMock(File.class, DIR_NAME);
|
||||
expect(dir.exists()).andStubReturn(true);
|
||||
expect(dir.listFiles()).andStubReturn(new File[] { file });
|
||||
AndroidMock.replay(dir, file);
|
||||
|
||||
assertEquals(0, service.cleanTempDirectory(dir));
|
||||
AndroidMock.verify(dir, file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests when there is an old file and it should get deleted.
|
||||
*/
|
||||
public void test_oldFile() {
|
||||
File file = AndroidMock.createMock(File.class, DIR_NAME + FILE_NAME);
|
||||
// qSet to one hour and 1 millisecond later than the current time
|
||||
expect(file.lastModified()).andStubReturn(System.currentTimeMillis() - 3600001);
|
||||
expect(file.delete()).andStubReturn(true);
|
||||
|
||||
File dir = AndroidMock.createMock(File.class, DIR_NAME);
|
||||
expect(dir.exists()).andStubReturn(true);
|
||||
expect(dir.listFiles()).andStubReturn(new File[] { file });
|
||||
AndroidMock.replay(dir, file);
|
||||
|
||||
assertEquals(1, service.cleanTempDirectory(dir));
|
||||
AndroidMock.verify(dir, file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright 2012 Google Inc. All Rights Reserved.
|
||||
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.Service;
|
||||
import android.test.ServiceTestCase;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* A {@link TrackRecordingService} that can be used with {@link ServiceTestCase}.
|
||||
* {@link ServiceTestCase} throws a null pointer exception when the service
|
||||
* calls {@link Service#startForeground(int, android.app.Notification)} and
|
||||
* {@link Service#stopForeground(boolean)}.
|
||||
* <p>
|
||||
* See http://code.google.com/p/android/issues/detail?id=12122
|
||||
* <p>
|
||||
* Wrap these two methods in wrappers and override them.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class TestRecordingService extends TrackRecordingService {
|
||||
|
||||
private static final String TAG = TestRecordingService.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
protected void startForegroundService(Notification notification) {
|
||||
try {
|
||||
Method setForegroundMethod = Service.class.getMethod("setForeground", boolean.class);
|
||||
setForegroundMethod.invoke(this, true);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stopForegroundService() {
|
||||
try {
|
||||
Method setForegroundMethod = Service.class.getMethod("setForeground", boolean.class);
|
||||
setForegroundMethod.invoke(this, false);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e(TAG, "Unable to start a service in foreground", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+768
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import static com.google.android.apps.mytracks.Constants.RESUME_TRACK_EXTRA_NAME;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProvider;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
import android.test.ServiceTestCase;
|
||||
import android.test.mock.MockContentProvider;
|
||||
import android.test.mock.MockContentResolver;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for the MyTracks track recording service.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
*
|
||||
* TODO: The original class, ServiceTestCase, has a few limitations, e.g.
|
||||
* it's not possible to properly shutdown the service, unless tearDown()
|
||||
* is called, which prevents from testing multiple scenarios in a single
|
||||
* test (see runFunctionTest for more details).
|
||||
*/
|
||||
public class TrackRecordingServiceTest extends ServiceTestCase<TestRecordingService> {
|
||||
|
||||
private Context context;
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
|
||||
/*
|
||||
* In order to support starting and binding to the service in the same
|
||||
* unit test, we provide a workaround, as the original class doesn't allow
|
||||
* to bind after the service has been previously started.
|
||||
*/
|
||||
|
||||
private boolean bound;
|
||||
private Intent serviceIntent;
|
||||
|
||||
public TrackRecordingServiceTest() {
|
||||
super(TestRecordingService.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* A context wrapper with the user provided {@link ContentResolver}.
|
||||
*
|
||||
* TODO: Move to test utils package.
|
||||
*/
|
||||
public static class MockContext extends ContextWrapper {
|
||||
private final ContentResolver contentResolver;
|
||||
|
||||
public MockContext(ContentResolver contentResolver, Context base) {
|
||||
super(base);
|
||||
this.contentResolver = contentResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentResolver getContentResolver() {
|
||||
return contentResolver;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IBinder bindService(Intent intent) {
|
||||
if (getService() != null) {
|
||||
if (bound) {
|
||||
throw new IllegalStateException(
|
||||
"Service: " + getService() + " is already bound");
|
||||
}
|
||||
bound = true;
|
||||
serviceIntent = intent.cloneFilter();
|
||||
return getService().onBind(intent);
|
||||
} else {
|
||||
return super.bindService(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutdownService() {
|
||||
if (bound) {
|
||||
assertNotNull(getService());
|
||||
getService().onUnbind(serviceIntent);
|
||||
bound = false;
|
||||
}
|
||||
super.shutdownService();
|
||||
}
|
||||
|
||||
@TargetApi(9)
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
/*
|
||||
* Create a mock context that uses a mock content resolver and a renaming
|
||||
* delegating context.
|
||||
*/
|
||||
MockContentResolver mockContentResolver = new MockContentResolver();
|
||||
RenamingDelegatingContext renamingDelegatingContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
context = new MockContext(mockContentResolver, renamingDelegatingContext);
|
||||
|
||||
// Set up the mock content resolver
|
||||
MyTracksProvider myTracksProvider = new MyTracksProvider();
|
||||
myTracksProvider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, myTracksProvider);
|
||||
MockContentProvider settingsProvider = new MockContentProvider(context) {
|
||||
@Override
|
||||
public Bundle call(String method, String arg, Bundle extras) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
||||
String sortOrder) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
mockContentResolver.addProvider(Settings.AUTHORITY, settingsProvider);
|
||||
|
||||
// Set the context
|
||||
setContext(context);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(
|
||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
// Let's use default values.
|
||||
sharedPreferences.edit().clear().apply();
|
||||
|
||||
// Disable auto resume by default.
|
||||
updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, 0);
|
||||
// No recording track.
|
||||
PreferencesUtils.setLong(
|
||||
context, R.string.recording_track_id_key, PreferencesUtils.RECORDING_TRACK_ID_DEFAULT);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testStartable() {
|
||||
startService(createStartIntent());
|
||||
assertNotNull(getService());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testBindable() {
|
||||
IBinder service = bindService(createStartIntent());
|
||||
assertNotNull(service);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testResumeAfterReboot_shouldResume() throws Exception {
|
||||
// Insert a dummy track and mark it as recording track.
|
||||
createDummyTrack(123L, System.currentTimeMillis(), true);
|
||||
|
||||
// Clear the number of attempts and set the timeout to 10 min.
|
||||
updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT,
|
||||
PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT);
|
||||
|
||||
// Start the service in "resume" mode (simulates the on-reboot action).
|
||||
Intent startIntent = createStartIntent();
|
||||
startIntent.putExtra(RESUME_TRACK_EXTRA_NAME, true);
|
||||
startService(startIntent);
|
||||
assertNotNull(getService());
|
||||
|
||||
// We expect to resume the previous track.
|
||||
assertTrue(getService().isRecording());
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertEquals(123L, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
// TODO: shutdownService() has a bug and doesn't set mServiceCreated
|
||||
// to false, thus preventing from a second call to onCreate().
|
||||
// Report the bug to Android team. Until then, the following tests
|
||||
// and checks must be commented out.
|
||||
//
|
||||
// TODO: If fixed, remove "disabled" prefix from the test name.
|
||||
@MediumTest
|
||||
public void disabledTestResumeAfterReboot_simulateReboot() throws Exception {
|
||||
updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT,
|
||||
PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT);
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
// Simulate recording a track.
|
||||
long id = service.startNewTrack();
|
||||
assertTrue(service.isRecording());
|
||||
assertEquals(id, service.getRecordingTrackId());
|
||||
shutdownService();
|
||||
assertEquals(id, PreferencesUtils.getLong(context, R.string.recording_track_id_key));
|
||||
|
||||
// Start the service in "resume" mode (simulates the on-reboot action).
|
||||
Intent startIntent = createStartIntent();
|
||||
startIntent.putExtra(RESUME_TRACK_EXTRA_NAME, true);
|
||||
startService(startIntent);
|
||||
assertNotNull(getService());
|
||||
|
||||
assertTrue(getService().isRecording());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testResumeAfterReboot_noRecordingTrack() throws Exception {
|
||||
// Insert a dummy track and mark it as recording track.
|
||||
createDummyTrack(123L, System.currentTimeMillis(), false);
|
||||
|
||||
// Clear the number of attempts and set the timeout to 10 min.
|
||||
updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT,
|
||||
PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT);
|
||||
|
||||
// Start the service in "resume" mode (simulates the on-reboot action).
|
||||
Intent startIntent = createStartIntent();
|
||||
startIntent.putExtra(RESUME_TRACK_EXTRA_NAME, true);
|
||||
startService(startIntent);
|
||||
assertNotNull(getService());
|
||||
|
||||
// We don't expect to resume the previous track, because it was stopped.
|
||||
assertFalse(getService().isRecording());
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertEquals(-1L, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testResumeAfterReboot_expiredTrack() throws Exception {
|
||||
// Insert a dummy track last updated 20 min ago.
|
||||
createDummyTrack(123L, System.currentTimeMillis() - 20 * 60 * 1000, true);
|
||||
|
||||
// Clear the number of attempts and set the timeout to 10 min.
|
||||
updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT,
|
||||
PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT);
|
||||
|
||||
// Start the service in "resume" mode (simulates the on-reboot action).
|
||||
Intent startIntent = createStartIntent();
|
||||
startIntent.putExtra(RESUME_TRACK_EXTRA_NAME, true);
|
||||
startService(startIntent);
|
||||
assertNotNull(getService());
|
||||
|
||||
// We don't expect to resume the previous track, because it has expired.
|
||||
assertFalse(getService().isRecording());
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertEquals(-1L, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testResumeAfterReboot_tooManyAttempts() throws Exception {
|
||||
// Insert a dummy track.
|
||||
createDummyTrack(123L, System.currentTimeMillis(), true);
|
||||
|
||||
// Set the number of attempts to max.
|
||||
updateAutoResumePrefs(TrackRecordingService.MAX_AUTO_RESUME_TRACK_RETRY_ATTEMPTS,
|
||||
PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT);
|
||||
|
||||
// Start the service in "resume" mode (simulates the on-reboot action).
|
||||
Intent startIntent = createStartIntent();
|
||||
startIntent.putExtra(RESUME_TRACK_EXTRA_NAME, true);
|
||||
startService(startIntent);
|
||||
assertNotNull(getService());
|
||||
|
||||
// We don't expect to resume the previous track, because there were already
|
||||
// too many attempts.
|
||||
assertFalse(getService().isRecording());
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertEquals(-1L, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testRecording_noTracks() throws Exception {
|
||||
List<Track> tracks = providerUtils.getAllTracks();
|
||||
assertTrue(tracks.isEmpty());
|
||||
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
// Test if we start in no-recording mode by default.
|
||||
assertFalse(service.isRecording());
|
||||
assertEquals(-1L, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testRecording_oldTracks() throws Exception {
|
||||
createDummyTrack(123L, -1L, false);
|
||||
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
assertEquals(-1L, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testRecording_orphanedRecordingTrack() throws Exception {
|
||||
// Just set recording track to a bogus value.
|
||||
PreferencesUtils.setLong(context, R.string.recording_track_id_key, 256L);
|
||||
|
||||
// Make sure that the service will not start recording and will clear
|
||||
// the bogus track.
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
assertEquals(-1L, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronous/waitable broadcast receiver to be used in testing.
|
||||
*/
|
||||
private class BlockingBroadcastReceiver extends BroadcastReceiver {
|
||||
private static final long MAX_WAIT_TIME_MS = 10000;
|
||||
private List<Intent> receivedIntents = new ArrayList<Intent>();
|
||||
|
||||
public List<Intent> getReceivedIntents() {
|
||||
return receivedIntents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context ctx, Intent intent) {
|
||||
Log.d("MyTracksTest", "Got broadcast: " + intent);
|
||||
synchronized (receivedIntents) {
|
||||
receivedIntents.add(intent);
|
||||
receivedIntents.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean waitUntilReceived(int receiveCount) {
|
||||
long deadline = System.currentTimeMillis() + MAX_WAIT_TIME_MS;
|
||||
synchronized (receivedIntents) {
|
||||
while (receivedIntents.size() < receiveCount) {
|
||||
try {
|
||||
// Wait releases synchronized lock until it returns
|
||||
receivedIntents.wait(500);
|
||||
} catch (InterruptedException e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() > deadline) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testStartNewTrack_noRecording() throws Exception {
|
||||
// NOTICE: due to the way Android permissions work, if this fails,
|
||||
// uninstall the test apk then retry - the test must be installed *after*
|
||||
// My Tracks (go figure).
|
||||
// Reference: http://code.google.com/p/android/issues/detail?id=5521
|
||||
BlockingBroadcastReceiver startReceiver = new BlockingBroadcastReceiver();
|
||||
String startAction = context.getString(R.string.track_started_broadcast_action);
|
||||
context.registerReceiver(startReceiver, new IntentFilter(startAction));
|
||||
|
||||
List<Track> tracks = providerUtils.getAllTracks();
|
||||
assertTrue(tracks.isEmpty());
|
||||
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
long id = service.startNewTrack();
|
||||
assertTrue(id >= 0);
|
||||
assertTrue(service.isRecording());
|
||||
Track track = providerUtils.getTrack(id);
|
||||
assertNotNull(track);
|
||||
assertEquals(id, track.getId());
|
||||
assertEquals(PreferencesUtils.getString(
|
||||
context, R.string.default_activity_key, PreferencesUtils.DEFAULT_ACTIVITY_DEFAULT),
|
||||
track.getCategory());
|
||||
assertEquals(id, PreferencesUtils.getLong(context, R.string.recording_track_id_key));
|
||||
assertEquals(id, service.getRecordingTrackId());
|
||||
|
||||
// Verify that the start broadcast was received.
|
||||
assertTrue(startReceiver.waitUntilReceived(1));
|
||||
List<Intent> receivedIntents = startReceiver.getReceivedIntents();
|
||||
assertEquals(1, receivedIntents.size());
|
||||
Intent broadcastIntent = receivedIntents.get(0);
|
||||
assertEquals(startAction, broadcastIntent.getAction());
|
||||
assertEquals(id, broadcastIntent.getLongExtra(
|
||||
context.getString(R.string.track_id_broadcast_extra), -1L));
|
||||
|
||||
context.unregisterReceiver(startReceiver);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testStartNewTrack_alreadyRecording() throws Exception {
|
||||
createDummyTrack(123L, -1L, true);
|
||||
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertTrue(service.isRecording());
|
||||
|
||||
// Starting a new track when there is a recording should just return -1L.
|
||||
long newTrack = service.startNewTrack();
|
||||
assertEquals(-1L, newTrack);
|
||||
|
||||
assertEquals(123L, PreferencesUtils.getLong(context, R.string.recording_track_id_key));
|
||||
assertEquals(123L, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testEndCurrentTrack_alreadyRecording() throws Exception {
|
||||
// See comment above if this fails randomly.
|
||||
BlockingBroadcastReceiver stopReceiver = new BlockingBroadcastReceiver();
|
||||
String stopAction = context.getString(R.string.track_stopped_broadcast_action);
|
||||
context.registerReceiver(stopReceiver, new IntentFilter(stopAction));
|
||||
|
||||
createDummyTrack(123L, -1L, true);
|
||||
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertTrue(service.isRecording());
|
||||
|
||||
// End the current track.
|
||||
service.endCurrentTrack();
|
||||
assertFalse(service.isRecording());
|
||||
assertEquals(PreferencesUtils.RECORDING_TRACK_ID_DEFAULT,
|
||||
PreferencesUtils.getLong(context, R.string.recording_track_id_key));
|
||||
assertEquals(PreferencesUtils.RECORDING_TRACK_ID_DEFAULT, service.getRecordingTrackId());
|
||||
|
||||
// Verify that the stop broadcast was received.
|
||||
assertTrue(stopReceiver.waitUntilReceived(1));
|
||||
List<Intent> receivedIntents = stopReceiver.getReceivedIntents();
|
||||
assertEquals(1, receivedIntents.size());
|
||||
Intent broadcastIntent = receivedIntents.get(0);
|
||||
assertEquals(stopAction, broadcastIntent.getAction());
|
||||
assertEquals(123L, broadcastIntent.getLongExtra(
|
||||
context.getString(R.string.track_id_broadcast_extra), -1L));
|
||||
|
||||
context.unregisterReceiver(stopReceiver);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testEndCurrentTrack_noRecording() throws Exception {
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
// Ending the current track when there is no recording should not result in any error.
|
||||
service.endCurrentTrack();
|
||||
|
||||
assertEquals(PreferencesUtils.RECORDING_TRACK_ID_DEFAULT,
|
||||
PreferencesUtils.getLong(context, R.string.recording_track_id_key));
|
||||
assertEquals(PreferencesUtils.RECORDING_TRACK_ID_DEFAULT, service.getRecordingTrackId());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testIntegration_completeRecordingSession() throws Exception {
|
||||
List<Track> tracks = providerUtils.getAllTracks();
|
||||
assertTrue(tracks.isEmpty());
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testInsertStatisticsMarker_noRecordingTrack() throws Exception {
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
try {
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
fail("Expecting IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// Expected.
|
||||
}
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testInsertStatisticsMarker_validLocation() throws Exception {
|
||||
createDummyTrack(123L, -1L, true);
|
||||
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertTrue(service.isRecording());
|
||||
insertLocation(service);
|
||||
|
||||
assertEquals(1, service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS));
|
||||
assertEquals(2, service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS));
|
||||
|
||||
Waypoint wpt = providerUtils.getWaypoint(2);
|
||||
assertEquals(getContext().getString(R.string.marker_statistics_icon_url), wpt.getIcon());
|
||||
assertEquals(getContext().getString(R.string.marker_split_name_format, 1), wpt.getName());
|
||||
assertEquals(Waypoint.TYPE_STATISTICS, wpt.getType());
|
||||
assertEquals(123L, wpt.getTrackId());
|
||||
assertEquals(0.0, wpt.getLength());
|
||||
assertNotNull(wpt.getLocation());
|
||||
assertNotNull(wpt.getTripStatistics());
|
||||
// TODO check the rest of the params.
|
||||
|
||||
// TODO: Check waypoint 2.
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testInsertWaypointMarker_noRecordingTrack() throws Exception {
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
try {
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT);
|
||||
fail("Expecting IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// Expected.
|
||||
}
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testInsertWaypointMarker_validWaypoint() throws Exception {
|
||||
createDummyTrack(123L, -1L, true);
|
||||
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertTrue(service.isRecording());
|
||||
insertLocation(service);
|
||||
|
||||
assertEquals(1, service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT));
|
||||
Waypoint wpt = providerUtils.getWaypoint(1);
|
||||
assertEquals(getContext().getString(R.string.marker_waypoint_icon_url),
|
||||
wpt.getIcon());
|
||||
assertEquals(getContext().getString(R.string.marker_name_format, 1), wpt.getName());
|
||||
assertEquals(Waypoint.TYPE_WAYPOINT, wpt.getType());
|
||||
assertEquals(123L, wpt.getTrackId());
|
||||
assertEquals(0.0, wpt.getLength());
|
||||
assertNotNull(wpt.getLocation());
|
||||
assertNull(wpt.getTripStatistics());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_announcementFrequencyDefault() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.announcement_frequency_key,
|
||||
PreferencesUtils.ANNOUNCEMENT_FREQUENCY_DEFAULT);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_announcementFrequencyByDistance() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.announcement_frequency_key, -1);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_announcementFrequencyByTime() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.announcement_frequency_key, 1);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_maxRecordingDistanceDefault() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.max_recording_distance_key,
|
||||
PreferencesUtils.MAX_RECORDING_DISTANCE_DEFAULT);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_maxRecordingDistance() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.max_recording_distance_key, 50);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_minRecordingDistanceDefault() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.min_recording_distance_key,
|
||||
PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_minRecordingDistance() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.min_recording_distance_key, 2);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_splitFrequencyDefault() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.split_frequency_key,
|
||||
PreferencesUtils.SPLIT_FREQUENCY_DEFAULT);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_splitFrequencyByDistance() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.split_frequency_key, -1);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_splitFrequencyByTime() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.split_frequency_key, 1);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_metricUnitsDefault() throws Exception {
|
||||
PreferencesUtils.setBoolean(
|
||||
context, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_metricUnitsDisabled() throws Exception {
|
||||
PreferencesUtils.setBoolean(context, R.string.metric_units_key, false);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_minRecordingIntervalDefault() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.min_recording_interval_key,
|
||||
PreferencesUtils.MIN_RECORDING_INTERVAL_DEFAULT);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_minRecordingInterval() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.min_recording_interval_key, 2);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_minRequiredAccuracyDefault() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.min_required_accuracy_key,
|
||||
PreferencesUtils.MIN_REQUIRED_ACCURACY_DEFAULT);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_minRequiredAccuracy() throws Exception {
|
||||
PreferencesUtils.setInt(context, R.string.min_required_accuracy_key, 500);
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_sensorTypeDefault() throws Exception {
|
||||
PreferencesUtils.setString(
|
||||
context, R.string.sensor_type_key, context.getString(R.string.sensor_type_value_none));
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWithProperties_sensorTypeZephyr() throws Exception {
|
||||
PreferencesUtils.setString(
|
||||
context, R.string.sensor_type_key, context.getString(R.string.sensor_type_value_zephyr));
|
||||
fullRecordingSession();
|
||||
}
|
||||
|
||||
private ITrackRecordingService bindAndGetService(Intent intent) {
|
||||
ITrackRecordingService service = ITrackRecordingService.Stub.asInterface(
|
||||
bindService(intent));
|
||||
assertNotNull(service);
|
||||
return service;
|
||||
}
|
||||
|
||||
private Track createDummyTrack(long id, long stopTime, boolean isRecording) {
|
||||
Track dummyTrack = new Track();
|
||||
dummyTrack.setId(id);
|
||||
dummyTrack.setName("Dummy Track");
|
||||
TripStatistics tripStatistics = new TripStatistics();
|
||||
tripStatistics.setStopTime(stopTime);
|
||||
dummyTrack.setTripStatistics(tripStatistics);
|
||||
addTrack(dummyTrack, isRecording);
|
||||
return dummyTrack;
|
||||
}
|
||||
|
||||
private void updateAutoResumePrefs(int attempts, int timeoutMins) {
|
||||
PreferencesUtils.setInt(context, R.string.auto_resume_track_current_retry_key, attempts);
|
||||
PreferencesUtils.setInt(context, R.string.auto_resume_track_timeout_key, timeoutMins);
|
||||
}
|
||||
|
||||
private Intent createStartIntent() {
|
||||
Intent startIntent = new Intent();
|
||||
startIntent.setClass(context, TrackRecordingService.class);
|
||||
return startIntent;
|
||||
}
|
||||
|
||||
private void addTrack(Track track, boolean isRecording) {
|
||||
assertTrue(track.getId() >= 0);
|
||||
providerUtils.insertTrack(track);
|
||||
assertEquals(track.getId(), providerUtils.getTrack(track.getId()).getId());
|
||||
PreferencesUtils.setLong(context, R.string.recording_track_id_key, isRecording ? track.getId()
|
||||
: PreferencesUtils.RECORDING_TRACK_ID_DEFAULT);
|
||||
}
|
||||
|
||||
private void fullRecordingSession() throws Exception {
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
// Start a track.
|
||||
long id = service.startNewTrack();
|
||||
assertTrue(id >= 0);
|
||||
assertTrue(service.isRecording());
|
||||
Track track = providerUtils.getTrack(id);
|
||||
assertNotNull(track);
|
||||
assertEquals(id, track.getId());
|
||||
assertEquals(id, PreferencesUtils.getLong(context, R.string.recording_track_id_key));
|
||||
assertEquals(id, service.getRecordingTrackId());
|
||||
|
||||
// Insert a few points, markers and statistics.
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (int i = 0; i < 30; i++) {
|
||||
Location loc = new Location("gps");
|
||||
loc.setLongitude(35.0f + i / 10.0f);
|
||||
loc.setLatitude(45.0f - i / 5.0f);
|
||||
loc.setAccuracy(5);
|
||||
loc.setSpeed(10);
|
||||
loc.setTime(startTime + i * 10000);
|
||||
loc.setBearing(3.0f);
|
||||
service.recordLocation(loc);
|
||||
|
||||
if (i % 10 == 0) {
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
} else if (i % 7 == 0) {
|
||||
service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the track. Validate if it has correct data.
|
||||
service.endCurrentTrack();
|
||||
assertFalse(service.isRecording());
|
||||
assertEquals(-1L, service.getRecordingTrackId());
|
||||
track = providerUtils.getTrack(id);
|
||||
assertNotNull(track);
|
||||
assertEquals(id, track.getId());
|
||||
TripStatistics tripStatistics = track.getTripStatistics();
|
||||
assertNotNull(tripStatistics);
|
||||
assertTrue(tripStatistics.getStartTime() > 0);
|
||||
assertTrue(tripStatistics.getStopTime() >= tripStatistics.getStartTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a location and waits for 100ms.
|
||||
*
|
||||
* @param trackRecordingService the track recording service
|
||||
*/
|
||||
private void insertLocation(ITrackRecordingService trackRecordingService)
|
||||
throws RemoteException, InterruptedException {
|
||||
Location location = new Location("gps");
|
||||
location.setLongitude(35.0f);
|
||||
location.setLatitude(45.0f);
|
||||
location.setAccuracy(5);
|
||||
location.setSpeed(10);
|
||||
location.setTime(System.currentTimeMillis());
|
||||
location.setBearing(3.0f);
|
||||
trackRecordingService.recordLocation(location);
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class PolarMessageParserTest extends TestCase {
|
||||
|
||||
PolarMessageParser parser = new PolarMessageParser();
|
||||
// A complete and valid Polar HxM packet
|
||||
// FE08F701D1001104FE08F702D1001104
|
||||
private final byte[] originalBuf =
|
||||
{(byte) 0xFE, 0x08, (byte) 0xF7, 0x01, (byte) 0xD1, 0x00, 0x11, 0x04, (byte) 0xFE, 0x08,
|
||||
(byte) 0xF7, 0x02, (byte) 0xD1, 0x00, 0x11, 0x04};
|
||||
private byte[] buf;
|
||||
|
||||
@TargetApi(9)
|
||||
public void setUp() {
|
||||
buf = Arrays.copyOf(originalBuf, originalBuf.length);
|
||||
}
|
||||
|
||||
public void testIsValid() {
|
||||
assertTrue(parser.isValid(buf));
|
||||
}
|
||||
|
||||
public void testIsValid_invalidHeader() {
|
||||
// Invalidate header.
|
||||
buf[0] = 0x03;
|
||||
assertFalse(parser.isValid(buf));
|
||||
}
|
||||
|
||||
public void testIsValid_invalidCheckbyte() {
|
||||
// Invalidate checkbyte.
|
||||
buf[2] = 0x03;
|
||||
assertFalse(parser.isValid(buf));
|
||||
}
|
||||
|
||||
public void testIsValid_invalidSequence() {
|
||||
// Invalidate sequence.
|
||||
buf[3] = 0x11;
|
||||
assertFalse(parser.isValid(buf));
|
||||
}
|
||||
|
||||
public void testParseBuffer() {
|
||||
buf[5] = 70;
|
||||
Sensor.SensorDataSet sds = parser.parseBuffer(buf);
|
||||
assertTrue(sds.hasHeartRate());
|
||||
assertTrue(sds.getHeartRate().getState() == Sensor.SensorState.SENDING);
|
||||
assertEquals(70, sds.getHeartRate().getValue());
|
||||
}
|
||||
|
||||
public void testFindNextAlignment_offset() {
|
||||
// The first 4 bytes are garbage
|
||||
buf = new byte[originalBuf.length + 4];
|
||||
buf[0] = 4;
|
||||
buf[1] = 2;
|
||||
buf[2] = 4;
|
||||
buf[3] = 2;
|
||||
|
||||
// Then the valid message.
|
||||
System.arraycopy(originalBuf, 0, buf, 4, originalBuf.length);
|
||||
assertEquals(4, parser.findNextAlignment(buf));
|
||||
}
|
||||
|
||||
public void testFindNextAlignment_invalid() {
|
||||
buf[0] = 0;
|
||||
assertEquals(-1, parser.findNextAlignment(buf));
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
public class SensorManagerFactoryTest extends AndroidTestCase {
|
||||
|
||||
@TargetApi(9)
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
SharedPreferences sharedPreferences = getContext().getSharedPreferences(
|
||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
// Let's use default values.
|
||||
sharedPreferences.edit().clear().apply();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testDefaultSettings() throws Exception {
|
||||
assertNull(SensorManagerFactory.getSystemSensorManager(getContext()));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCreateZephyr() throws Exception {
|
||||
assertClassForName(ZephyrSensorManager.class, R.string.sensor_type_value_zephyr);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCreatePolar() throws Exception {
|
||||
assertClassForName(PolarSensorManager.class, R.string.sensor_type_value_polar);
|
||||
}
|
||||
|
||||
private void assertClassForName(Class<?> c, int i) {
|
||||
PreferencesUtils.setString(getContext(), R.string.sensor_type_key, getContext().getString(i));
|
||||
SensorManager sm = SensorManagerFactory.getSystemSensorManager(getContext());
|
||||
assertNotNull(sm);
|
||||
assertTrue(c.isInstance(sm));
|
||||
SensorManagerFactory.releaseSystemSensorManager();
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Dominik Ršttsches
|
||||
*/
|
||||
public class StrideReadingsTest extends TestCase {
|
||||
|
||||
public void testNoReadingOnStartup() {
|
||||
StrideReadings strideReadings = new StrideReadings();
|
||||
assertEquals(StrideReadings.CADENCE_NOT_AVAILABLE, strideReadings.getCadence());
|
||||
}
|
||||
|
||||
public void testAverageCadenceAvailable() {
|
||||
StrideReadings strideReadings = new StrideReadings();
|
||||
// 2 steps / second => Cadence is 120 / minute
|
||||
for (int i = 1; i <= 30; i++) {
|
||||
strideReadings.updateStrideReading(i*2);
|
||||
if (i >= StrideReadings.MIN_READINGS_FOR_AVERAGE) {
|
||||
assertEquals(120, strideReadings.getCadence());
|
||||
} else {
|
||||
assertEquals(StrideReadings.CADENCE_NOT_AVAILABLE, strideReadings.getCadence());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for correct calculation after rolling over at 128 strides,
|
||||
* just like the HxM seems to do it.
|
||||
*/
|
||||
public void testRollover() {
|
||||
StrideReadings strideReadings = new StrideReadings();
|
||||
// 1 step per second => Cadence is 60 / minute
|
||||
// Updating readings counting upwards from initialStrides -
|
||||
// initialStrides set to a value below 128 to ensure rollover.
|
||||
int initialStrides = 128 - StrideReadings.NUM_READINGS_FOR_AVERAGE - 5;
|
||||
|
||||
for (int i = 1; i <= StrideReadings.NUM_READINGS_FOR_AVERAGE + 10; i++) {
|
||||
strideReadings.updateStrideReading((initialStrides + i) % 128);
|
||||
if (i >= StrideReadings.MIN_READINGS_FOR_AVERAGE) {
|
||||
assertEquals(60, strideReadings.getCadence());
|
||||
} else {
|
||||
assertEquals(StrideReadings.CADENCE_NOT_AVAILABLE, strideReadings.getCadence());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.google.android.apps.mytracks.services.sensors;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class ZephyrMessageParserTest extends TestCase {
|
||||
|
||||
ZephyrMessageParser parser = new ZephyrMessageParser();
|
||||
|
||||
public void testIsValid() {
|
||||
byte[] smallBuf = new byte[59];
|
||||
assertFalse(parser.isValid(smallBuf));
|
||||
// A complete and valid Zephyr HxM packet
|
||||
byte[] buf = { 2,38,55,26,0,49,101,80,0,49,98,100,42,113,120,-53,-24,-60,-123,-61,117,-69,42,-75,74,-78,51,-79,27,-83,28,-88,28,-93,29,-98,25,-103,26,-108,26,-113,59,-118,0,0,0,0,0,0,-22,3,125,1,48,0,96,4,30,0 };
|
||||
// Make buffer invalid
|
||||
buf[0] = buf[58] = buf[59] = 0;
|
||||
assertFalse(parser.isValid(buf));
|
||||
buf[0] = 0x02;
|
||||
assertFalse(parser.isValid(buf));
|
||||
buf[58] = 0x1E;
|
||||
assertFalse(parser.isValid(buf));
|
||||
buf[59] = 0x03;
|
||||
assertTrue(parser.isValid(buf));
|
||||
}
|
||||
|
||||
public void testParseBuffer() {
|
||||
byte[] buf = new byte[60];
|
||||
// Heart Rate (-1 =^ 255 unsigned byte)
|
||||
buf[12] = -1;
|
||||
// Battery Level
|
||||
buf[11] = 51;
|
||||
// Cadence (=^ 255*16 strides/min)
|
||||
buf[56] = -1;
|
||||
buf[57] = 15;
|
||||
Sensor.SensorDataSet sds = parser.parseBuffer(buf);
|
||||
assertTrue(sds.hasHeartRate());
|
||||
assertTrue(sds.getHeartRate().getState() == Sensor.SensorState.SENDING);
|
||||
assertEquals(255, sds.getHeartRate().getValue());
|
||||
assertTrue(sds.hasBatteryLevel());
|
||||
assertTrue(sds.getBatteryLevel().getState() == Sensor.SensorState.SENDING);
|
||||
assertEquals(51, sds.getBatteryLevel().getValue());
|
||||
assertTrue(sds.hasCadence());
|
||||
assertTrue(sds.getCadence().getState() == Sensor.SensorState.SENDING);
|
||||
assertEquals(255, sds.getCadence().getValue());
|
||||
}
|
||||
|
||||
public void testFindNextAlignment() {
|
||||
byte[] buf = new byte[60];
|
||||
assertEquals(-1, parser.findNextAlignment(buf));
|
||||
buf[10] = 0x03;
|
||||
buf[11] = 0x02;
|
||||
assertEquals(10, parser.findNextAlignment(buf));
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.tasks;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link StatusAnnouncerFactory}.
|
||||
* These tests require Donut+ to run.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class StatusAnnouncerFactoryTest extends AndroidTestCase {
|
||||
public void testCreate() {
|
||||
PeriodicTaskFactory factory = new StatusAnnouncerFactory();
|
||||
PeriodicTask task = factory.create(getContext());
|
||||
assertTrue(task instanceof StatusAnnouncerTask);
|
||||
}
|
||||
}
|
||||
+552
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.services.tasks;
|
||||
|
||||
import static com.google.android.testing.mocking.AndroidMock.capture;
|
||||
import static com.google.android.testing.mocking.AndroidMock.eq;
|
||||
import static com.google.android.testing.mocking.AndroidMock.expect;
|
||||
import static com.google.android.testing.mocking.AndroidMock.same;
|
||||
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.TextToSpeech.OnInitListener;
|
||||
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.easymock.Capture;
|
||||
|
||||
/**
|
||||
* Tests for {@link StatusAnnouncerTask}.
|
||||
* WARNING: I'm not responsible if your eyes start bleeding while reading this
|
||||
* code. You have been warned. It's still better than no test, though.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class StatusAnnouncerTaskTest extends AndroidTestCase {
|
||||
|
||||
// Use something other than our hardcoded value
|
||||
private static final Locale DEFAULT_LOCALE = Locale.KOREAN;
|
||||
private static final String ANNOUNCEMENT = "I can haz cheeseburger?";
|
||||
private Locale oldDefaultLocale;
|
||||
|
||||
private StatusAnnouncerTask task;
|
||||
private StatusAnnouncerTask mockTask;
|
||||
private Capture<OnInitListener> initListenerCapture;
|
||||
private Capture<PhoneStateListener> phoneListenerCapture;
|
||||
private TextToSpeechDelegate ttsDelegate;
|
||||
private TextToSpeechInterface tts;
|
||||
|
||||
/**
|
||||
* Mockable interface that we delegate TTS calls to.
|
||||
*/
|
||||
interface TextToSpeechInterface {
|
||||
int addEarcon(String earcon, String packagename, int resourceId);
|
||||
int addEarcon(String earcon, String filename);
|
||||
int addSpeech(String text, String packagename, int resourceId);
|
||||
int addSpeech(String text, String filename);
|
||||
boolean areDefaultsEnforced();
|
||||
String getDefaultEngine();
|
||||
Locale getLanguage();
|
||||
int isLanguageAvailable(Locale loc);
|
||||
boolean isSpeaking();
|
||||
int playEarcon(String earcon, int queueMode,
|
||||
HashMap<String, String> params);
|
||||
int playSilence(long durationInMs, int queueMode,
|
||||
HashMap<String, String> params);
|
||||
int setEngineByPackageName(String enginePackageName);
|
||||
int setLanguage(Locale loc);
|
||||
int setOnUtteranceCompletedListener(OnUtteranceCompletedListener listener);
|
||||
int setPitch(float pitch);
|
||||
int setSpeechRate(float speechRate);
|
||||
void shutdown();
|
||||
int speak(String text, int queueMode, HashMap<String, String> params);
|
||||
int stop();
|
||||
int synthesizeToFile(String text, HashMap<String, String> params,
|
||||
String filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclass of {@link TextToSpeech} which delegates calls to the interface
|
||||
* above.
|
||||
* The logic here is stupid and the author is ashamed of having to write it
|
||||
* like this, but basically the issue is that TextToSpeech cannot be mocked
|
||||
* without running its constructor, its constructor runs async operations
|
||||
* which call other methods (and then if the methods are part of a mock we'd
|
||||
* have to set a behavior, but we can't 'cause the object hasn't been fully
|
||||
* built yet).
|
||||
* The logic is that calls made during the constructor (when tts is not yet
|
||||
* set) will go up to the original class, but after tts is set we'll forward
|
||||
* them all to the mock.
|
||||
*/
|
||||
private class TextToSpeechDelegate
|
||||
extends TextToSpeech implements TextToSpeechInterface {
|
||||
public TextToSpeechDelegate(Context context, OnInitListener listener) {
|
||||
super(context, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addEarcon(String earcon, String packagename, int resourceId) {
|
||||
if (tts == null) {
|
||||
return super.addEarcon(earcon, packagename, resourceId);
|
||||
}
|
||||
return tts.addEarcon(earcon, packagename, resourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addEarcon(String earcon, String filename) {
|
||||
if (tts == null) {
|
||||
return super.addEarcon(earcon, filename);
|
||||
}
|
||||
return tts.addEarcon(earcon, filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addSpeech(String text, String packagename, int resourceId) {
|
||||
if (tts == null) {
|
||||
return super.addSpeech(text, packagename, resourceId);
|
||||
}
|
||||
return tts.addSpeech(text, packagename, resourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addSpeech(String text, String filename) {
|
||||
if (tts == null) {
|
||||
return super.addSpeech(text, filename);
|
||||
}
|
||||
return tts.addSpeech(text, filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLanguage() {
|
||||
if (tts == null) {
|
||||
return super.getLanguage();
|
||||
}
|
||||
return tts.getLanguage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isLanguageAvailable(Locale loc) {
|
||||
if (tts == null) {
|
||||
return super.isLanguageAvailable(loc);
|
||||
}
|
||||
return tts.isLanguageAvailable(loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpeaking() {
|
||||
if (tts == null) {
|
||||
return super.isSpeaking();
|
||||
}
|
||||
return tts.isSpeaking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int playEarcon(String earcon, int queueMode,
|
||||
HashMap<String, String> params) {
|
||||
if (tts == null) {
|
||||
return super.playEarcon(earcon, queueMode, params);
|
||||
}
|
||||
return tts.playEarcon(earcon, queueMode, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int playSilence(long durationInMs, int queueMode,
|
||||
HashMap<String, String> params) {
|
||||
if (tts == null) {
|
||||
return super.playSilence(durationInMs, queueMode, params);
|
||||
}
|
||||
return tts.playSilence(durationInMs, queueMode, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLanguage(Locale loc) {
|
||||
if (tts == null) {
|
||||
return super.setLanguage(loc);
|
||||
}
|
||||
return tts.setLanguage(loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setOnUtteranceCompletedListener(
|
||||
OnUtteranceCompletedListener listener) {
|
||||
if (tts == null) {
|
||||
return super.setOnUtteranceCompletedListener(listener);
|
||||
}
|
||||
return tts.setOnUtteranceCompletedListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setPitch(float pitch) {
|
||||
if (tts == null) {
|
||||
return super.setPitch(pitch);
|
||||
}
|
||||
return tts.setPitch(pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setSpeechRate(float speechRate) {
|
||||
if (tts == null) {
|
||||
return super.setSpeechRate(speechRate);
|
||||
}
|
||||
return tts.setSpeechRate(speechRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
if (tts == null) {
|
||||
super.shutdown();
|
||||
return;
|
||||
}
|
||||
tts.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int speak(
|
||||
String text, int queueMode, HashMap<String, String> params) {
|
||||
if (tts == null) {
|
||||
return super.speak(text, queueMode, params);
|
||||
}
|
||||
return tts.speak(text, queueMode, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stop() {
|
||||
if (tts == null) {
|
||||
return super.stop();
|
||||
}
|
||||
return tts.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int synthesizeToFile(String text, HashMap<String, String> params,
|
||||
String filename) {
|
||||
if (tts == null) {
|
||||
return super.synthesizeToFile(text, params, filename);
|
||||
}
|
||||
return tts.synthesizeToFile(text, params, filename);
|
||||
}
|
||||
}
|
||||
|
||||
@UsesMocks({
|
||||
StatusAnnouncerTask.class,
|
||||
StringUtils.class,
|
||||
})
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
oldDefaultLocale = Locale.getDefault();
|
||||
Locale.setDefault(DEFAULT_LOCALE);
|
||||
|
||||
// Eww, the effort required just to mock TextToSpeech is insane
|
||||
final AtomicBoolean listenerCalled = new AtomicBoolean();
|
||||
OnInitListener blockingListener = new OnInitListener() {
|
||||
@Override
|
||||
public void onInit(int status) {
|
||||
synchronized (this) {
|
||||
listenerCalled.set(true);
|
||||
notify();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ttsDelegate = new TextToSpeechDelegate(getContext(), blockingListener);
|
||||
|
||||
// Wait for all async operations done in the constructor to finish.
|
||||
synchronized (blockingListener) {
|
||||
while (!listenerCalled.get()) {
|
||||
// Releases the synchronized lock until we're woken up.
|
||||
blockingListener.wait();
|
||||
}
|
||||
}
|
||||
|
||||
// Phew, done, now we can start forwarding calls
|
||||
tts = AndroidMock.createMock(TextToSpeechInterface.class);
|
||||
|
||||
initListenerCapture = new Capture<OnInitListener>();
|
||||
phoneListenerCapture = new Capture<PhoneStateListener>();
|
||||
|
||||
// Create a partial forwarding mock
|
||||
mockTask = AndroidMock.createMock(StatusAnnouncerTask.class, getContext());
|
||||
task = new StatusAnnouncerTask(getContext()) {
|
||||
@Override
|
||||
protected TextToSpeech newTextToSpeech(Context ctx,
|
||||
OnInitListener onInitListener) {
|
||||
return mockTask.newTextToSpeech(ctx, onInitListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAnnouncement(TripStatistics stats) {
|
||||
return mockTask.getAnnouncement(stats);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void listenToPhoneState(
|
||||
PhoneStateListener listener, int events) {
|
||||
mockTask.listenToPhoneState(listener, events);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() {
|
||||
Locale.setDefault(oldDefaultLocale);
|
||||
}
|
||||
|
||||
public void testStart() {
|
||||
doStart();
|
||||
OnInitListener ttsInitListener = initListenerCapture.getValue();
|
||||
assertNotNull(ttsInitListener);
|
||||
|
||||
expect(tts.isLanguageAvailable(DEFAULT_LOCALE))
|
||||
.andStubReturn(TextToSpeech.LANG_AVAILABLE);
|
||||
expect(tts.setLanguage(DEFAULT_LOCALE))
|
||||
.andReturn(TextToSpeech.LANG_AVAILABLE);
|
||||
expect(tts.setSpeechRate(StatusAnnouncerTask.TTS_SPEECH_RATE))
|
||||
.andReturn(TextToSpeech.SUCCESS);
|
||||
|
||||
AndroidMock.replay(tts);
|
||||
|
||||
ttsInitListener.onInit(TextToSpeech.SUCCESS);
|
||||
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testStart_languageNotSupported() {
|
||||
doStart();
|
||||
OnInitListener ttsInitListener = initListenerCapture.getValue();
|
||||
assertNotNull(ttsInitListener);
|
||||
|
||||
expect(tts.isLanguageAvailable(DEFAULT_LOCALE))
|
||||
.andStubReturn(TextToSpeech.LANG_NOT_SUPPORTED);
|
||||
expect(tts.setLanguage(Locale.ENGLISH))
|
||||
.andReturn(TextToSpeech.LANG_AVAILABLE);
|
||||
expect(tts.setSpeechRate(StatusAnnouncerTask.TTS_SPEECH_RATE))
|
||||
.andReturn(TextToSpeech.SUCCESS);
|
||||
|
||||
AndroidMock.replay(tts);
|
||||
|
||||
ttsInitListener.onInit(TextToSpeech.SUCCESS);
|
||||
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testStart_notReady() {
|
||||
doStart();
|
||||
OnInitListener ttsInitListener = initListenerCapture.getValue();
|
||||
assertNotNull(ttsInitListener);
|
||||
|
||||
AndroidMock.replay(tts);
|
||||
|
||||
ttsInitListener.onInit(TextToSpeech.ERROR);
|
||||
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testShutdown() {
|
||||
// First, start
|
||||
doStart();
|
||||
AndroidMock.verify(mockTask);
|
||||
AndroidMock.reset(mockTask);
|
||||
|
||||
// Then, shut down
|
||||
PhoneStateListener phoneListener = phoneListenerCapture.getValue();
|
||||
mockTask.listenToPhoneState(
|
||||
same(phoneListener), eq(PhoneStateListener.LISTEN_NONE));
|
||||
tts.shutdown();
|
||||
AndroidMock.replay(mockTask, tts);
|
||||
task.shutdown();
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testRun() throws Exception {
|
||||
// Expect service data calls
|
||||
TripStatistics stats = new TripStatistics();
|
||||
|
||||
// Expect announcement building call
|
||||
expect(mockTask.getAnnouncement(same(stats))).andStubReturn(ANNOUNCEMENT);
|
||||
|
||||
// Put task in "ready" state
|
||||
startTask(TextToSpeech.SUCCESS);
|
||||
|
||||
// Expect actual announcement call
|
||||
expect(tts.speak(
|
||||
eq(ANNOUNCEMENT), eq(TextToSpeech.QUEUE_FLUSH),
|
||||
AndroidMock.<HashMap<String, String>>isNull()))
|
||||
.andReturn(TextToSpeech.SUCCESS);
|
||||
|
||||
// Run the announcement
|
||||
AndroidMock.replay(tts);
|
||||
task.runWithStatistics(stats);
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testRun_notReady() throws Exception {
|
||||
// Put task in "not ready" state
|
||||
startTask(TextToSpeech.ERROR);
|
||||
|
||||
// Run the announcement
|
||||
AndroidMock.replay(tts);
|
||||
task.runWithStatistics(null);
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testRun_duringCall() throws Exception {
|
||||
startTask(TextToSpeech.SUCCESS);
|
||||
|
||||
expect(tts.isSpeaking()).andStubReturn(false);
|
||||
|
||||
// Run the announcement
|
||||
AndroidMock.replay(tts);
|
||||
PhoneStateListener phoneListener = phoneListenerCapture.getValue();
|
||||
phoneListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK, null);
|
||||
task.runWithStatistics(null);
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testRun_ringWhileSpeaking() throws Exception {
|
||||
startTask(TextToSpeech.SUCCESS);
|
||||
|
||||
expect(tts.isSpeaking()).andStubReturn(true);
|
||||
expect(tts.stop()).andReturn(TextToSpeech.SUCCESS);
|
||||
|
||||
AndroidMock.replay(tts);
|
||||
|
||||
// Update the state to ringing - this should stop the current announcement.
|
||||
PhoneStateListener phoneListener = phoneListenerCapture.getValue();
|
||||
phoneListener.onCallStateChanged(TelephonyManager.CALL_STATE_RINGING, null);
|
||||
|
||||
// Run the announcement - this should do nothing.
|
||||
task.runWithStatistics(null);
|
||||
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testRun_whileRinging() throws Exception {
|
||||
startTask(TextToSpeech.SUCCESS);
|
||||
|
||||
expect(tts.isSpeaking()).andStubReturn(false);
|
||||
|
||||
// Run the announcement
|
||||
AndroidMock.replay(tts);
|
||||
PhoneStateListener phoneListener = phoneListenerCapture.getValue();
|
||||
phoneListener.onCallStateChanged(TelephonyManager.CALL_STATE_RINGING, null);
|
||||
task.runWithStatistics(null);
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testRun_noService() throws Exception {
|
||||
startTask(TextToSpeech.SUCCESS);
|
||||
|
||||
// Run the announcement
|
||||
AndroidMock.replay(tts);
|
||||
task.run(null);
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
public void testRun_noStats() throws Exception {
|
||||
// Expect service data calls
|
||||
|
||||
startTask(TextToSpeech.SUCCESS);
|
||||
|
||||
// Run the announcement
|
||||
AndroidMock.replay(tts);
|
||||
task.runWithStatistics(null);
|
||||
AndroidMock.verify(mockTask, tts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with time zero.
|
||||
*/
|
||||
public void testGetAnnounceTime_time_zero() {
|
||||
long time = 0; // 0 seconds
|
||||
assertEquals("0 minutes 0 seconds", task.getAnnounceTime(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with time one.
|
||||
*/
|
||||
public void testGetAnnounceTime_time_one() {
|
||||
long time = 1 * 1000; // 1 second
|
||||
assertEquals("0 minutes 1 second", task.getAnnounceTime(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with singular
|
||||
* numbers with the hour unit.
|
||||
*/
|
||||
public void testGetAnnounceTime_singular_has_hour() {
|
||||
long time = (1 * 60 * 60 * 1000) + (1 * 60 * 1000) + (1 * 1000); // 1 hour 1 minute 1 second
|
||||
assertEquals("1 hour 1 minute", task.getAnnounceTime(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with plural numbers
|
||||
* with the hour unit.
|
||||
*/
|
||||
public void testGetAnnounceTime_plural_has_hour() {
|
||||
long time = (2 * 60 * 60 * 1000) + (2 * 60 * 1000) + (2 * 1000); // 2 hours 2 minutes 2 seconds
|
||||
assertEquals("2 hours 2 minutes", task.getAnnounceTime(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with singular
|
||||
* numbers without the hour unit.
|
||||
*/
|
||||
public void testGetAnnounceTime_singular_no_hour() {
|
||||
long time = (1 * 60 * 1000) + (1 * 1000); // 1 minute 1 second
|
||||
assertEquals("1 minute 1 second", task.getAnnounceTime(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StatusAnnouncerTask#getAnnounceTime(long)} with plural numbers
|
||||
* without the hour unit.
|
||||
*/
|
||||
public void testGetAnnounceTime_plural_no_hour() {
|
||||
long time = (2 * 60 * 1000) + (2 * 1000); // 2 minutes 2 seconds
|
||||
assertEquals("2 minutes 2 seconds", task.getAnnounceTime(time));
|
||||
}
|
||||
|
||||
private void startTask(int state) {
|
||||
AndroidMock.resetToNice(tts);
|
||||
AndroidMock.replay(tts);
|
||||
doStart();
|
||||
OnInitListener ttsInitListener = initListenerCapture.getValue();
|
||||
ttsInitListener.onInit(state);
|
||||
AndroidMock.resetToDefault(tts);
|
||||
}
|
||||
|
||||
private void doStart() {
|
||||
mockTask.listenToPhoneState(capture(phoneListenerCapture),
|
||||
eq(PhoneStateListener.LISTEN_CALL_STATE));
|
||||
expect(mockTask.newTextToSpeech(
|
||||
same(getContext()), capture(initListenerCapture)))
|
||||
.andStubReturn(ttsDelegate);
|
||||
AndroidMock.replay(mockTask);
|
||||
task.start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2009 Google Inc. All Rights Reserved.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.stats;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Test for the DoubleBuffer class.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class DoubleBufferTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Tests that the constructor leaves the buffer in a valid state.
|
||||
*/
|
||||
public void testConstructor() {
|
||||
DoubleBuffer buffer = new DoubleBuffer(10);
|
||||
assertFalse(buffer.isFull());
|
||||
assertEquals(0.0, buffer.getAverage());
|
||||
double[] averageAndVariance = buffer.getAverageAndVariance();
|
||||
assertEquals(0.0, averageAndVariance[0]);
|
||||
assertEquals(0.0, averageAndVariance[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test with 10 of the same values.
|
||||
*/
|
||||
public void testBasic() {
|
||||
DoubleBuffer buffer = new DoubleBuffer(10);
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
buffer.setNext(1.0);
|
||||
assertFalse(buffer.isFull());
|
||||
assertEquals(1.0, buffer.getAverage());
|
||||
double[] averageAndVariance = buffer.getAverageAndVariance();
|
||||
assertEquals(1.0, averageAndVariance[0]);
|
||||
assertEquals(0.0, averageAndVariance[1]);
|
||||
}
|
||||
buffer.setNext(1);
|
||||
assertTrue(buffer.isFull());
|
||||
assertEquals(1.0, buffer.getAverage());
|
||||
double[] averageAndVariance = buffer.getAverageAndVariance();
|
||||
assertEquals(1.0, averageAndVariance[0]);
|
||||
assertEquals(0.0, averageAndVariance[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests with 5 entries of -10 and 5 entries of 10.
|
||||
*/
|
||||
public void testSplit() {
|
||||
DoubleBuffer buffer = new DoubleBuffer(10);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
buffer.setNext(-10);
|
||||
assertFalse(buffer.isFull());
|
||||
assertEquals(-10.0, buffer.getAverage());
|
||||
double[] averageAndVariance = buffer.getAverageAndVariance();
|
||||
assertEquals(-10.0, averageAndVariance[0]);
|
||||
assertEquals(0.0, averageAndVariance[1]);
|
||||
}
|
||||
|
||||
for (int i = 1; i < 5; i++) {
|
||||
buffer.setNext(10);
|
||||
assertFalse(buffer.isFull());
|
||||
double expectedAverage = ((i * 10.0) - 50.0) / (i + 5);
|
||||
assertEquals(buffer.toString(),
|
||||
expectedAverage, buffer.getAverage(), 0.01);
|
||||
double[] averageAndVariance = buffer.getAverageAndVariance();
|
||||
assertEquals(expectedAverage, averageAndVariance[0]);
|
||||
}
|
||||
buffer.setNext(10);
|
||||
assertTrue(buffer.isFull());
|
||||
assertEquals(0.0, buffer.getAverage());
|
||||
double[] averageAndVariance = buffer.getAverageAndVariance();
|
||||
assertEquals(0.0, averageAndVariance[0]);
|
||||
assertEquals(100.0, averageAndVariance[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that reset leaves the buffer in a valid state.
|
||||
*/
|
||||
public void testReset() {
|
||||
DoubleBuffer buffer = new DoubleBuffer(10);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
buffer.setNext(i);
|
||||
}
|
||||
assertTrue(buffer.isFull());
|
||||
|
||||
buffer.reset();
|
||||
assertFalse(buffer.isFull());
|
||||
assertEquals(0.0, buffer.getAverage());
|
||||
double[] averageAndVariance = buffer.getAverageAndVariance();
|
||||
assertEquals(0.0, averageAndVariance[0]);
|
||||
assertEquals(0.0, averageAndVariance[1]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests that if a lot of items are inserted the smoothing and looping works.
|
||||
*/
|
||||
public void testLoop() {
|
||||
DoubleBuffer buffer = new DoubleBuffer(10);
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
buffer.setNext(i);
|
||||
assertEquals(i >= 9, buffer.isFull());
|
||||
if (i > 10) {
|
||||
assertEquals(i - 4.5, buffer.getAverage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright 2009 Google Inc. All Rights Reserved.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.stats;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* This class test the ExtremityMonitor class.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class ExtremityMonitorTest extends TestCase {
|
||||
|
||||
public ExtremityMonitorTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void testInitialize() {
|
||||
ExtremityMonitor monitor = new ExtremityMonitor();
|
||||
assertEquals(Double.POSITIVE_INFINITY, monitor.getMin());
|
||||
assertEquals(Double.NEGATIVE_INFINITY, monitor.getMax());
|
||||
}
|
||||
|
||||
public void testSimple() {
|
||||
ExtremityMonitor monitor = new ExtremityMonitor();
|
||||
assertTrue(monitor.update(0));
|
||||
assertTrue(monitor.update(1));
|
||||
assertEquals(0.0, monitor.getMin());
|
||||
assertEquals(1.0, monitor.getMax());
|
||||
assertFalse(monitor.update(1));
|
||||
assertFalse(monitor.update(0.5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws a bunch of random numbers between [0,1] at the monitor.
|
||||
*/
|
||||
public void testRandom() {
|
||||
ExtremityMonitor monitor = new ExtremityMonitor();
|
||||
Random random = new Random(42);
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
monitor.update(random.nextDouble());
|
||||
}
|
||||
assertTrue(monitor.getMin() < 0.1);
|
||||
assertTrue(monitor.getMax() < 1.0);
|
||||
assertTrue(monitor.getMin() >= 0.0);
|
||||
assertTrue(monitor.getMax() > 0.9);
|
||||
}
|
||||
|
||||
public void testReset() {
|
||||
ExtremityMonitor monitor = new ExtremityMonitor();
|
||||
assertTrue(monitor.update(0));
|
||||
assertTrue(monitor.update(1));
|
||||
monitor.reset();
|
||||
assertEquals(Double.POSITIVE_INFINITY, monitor.getMin());
|
||||
assertEquals(Double.NEGATIVE_INFINITY, monitor.getMax());
|
||||
assertTrue(monitor.update(0));
|
||||
assertTrue(monitor.update(1));
|
||||
assertEquals(0.0, monitor.getMin());
|
||||
assertEquals(1.0, monitor.getMax());
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
|
||||
package com.google.android.apps.mytracks.stats;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Test the the function of the TripStatisticsBuilder class.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class TripStatisticsBuilderTest extends TestCase {
|
||||
|
||||
private TripStatisticsBuilder builder = null;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
builder = new TripStatisticsBuilder(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public void testAddLocationSimple() throws Exception {
|
||||
builder = new TripStatisticsBuilder(1000);
|
||||
TripStatistics stats = builder.getStatistics();
|
||||
|
||||
assertEquals(0.0, builder.getSmoothedElevation());
|
||||
assertEquals(Double.POSITIVE_INFINITY, stats.getMinElevation());
|
||||
assertEquals(Double.NEGATIVE_INFINITY, stats.getMaxElevation());
|
||||
assertEquals(0.0, stats.getMaxSpeed());
|
||||
assertEquals(Double.POSITIVE_INFINITY, stats.getMinGrade());
|
||||
assertEquals(Double.NEGATIVE_INFINITY, stats.getMaxGrade());
|
||||
assertEquals(0.0, stats.getTotalElevationGain());
|
||||
assertEquals(0, stats.getMovingTime());
|
||||
assertEquals(0.0, stats.getTotalDistance());
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Location l = new Location("test");
|
||||
l.setAccuracy(1.0f);
|
||||
l.setLongitude(45.0);
|
||||
|
||||
// Going up by 5 meters each time.
|
||||
l.setAltitude(i);
|
||||
// Moving by .1% of a degree latitude.
|
||||
l.setLatitude(i * .001);
|
||||
l.setSpeed(11.1f);
|
||||
// Each time slice is 10 seconds.
|
||||
long time = 1000 + 10000 * i;
|
||||
l.setTime(time);
|
||||
boolean moving = builder.addLocation(l, time);
|
||||
assertEquals((i != 0), moving);
|
||||
|
||||
stats = builder.getStatistics();
|
||||
assertEquals(10000 * i, stats.getTotalTime());
|
||||
assertEquals(10000 * i, stats.getMovingTime());
|
||||
assertEquals(i, builder.getSmoothedElevation(),
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR / 2);
|
||||
assertEquals(0.0, stats.getMinElevation());
|
||||
assertEquals(i, stats.getMaxElevation(),
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR / 2);
|
||||
assertEquals(i, stats.getTotalElevationGain(),
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
|
||||
if (i > Constants.SPEED_SMOOTHING_FACTOR) {
|
||||
assertEquals(11.1f, stats.getMaxSpeed(), 0.1);
|
||||
}
|
||||
if ((i > Constants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > Constants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
assertEquals(0.009, stats.getMinGrade(), 0.0001);
|
||||
assertEquals(0.009, stats.getMaxGrade(), 0.0001);
|
||||
}
|
||||
// 1 degree = 111 km
|
||||
// 1 timeslice = 0.001 degree = 111 m
|
||||
assertEquals(111.0 * i, stats.getTotalDistance(), 100);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that elevation works if the user is stable.
|
||||
*/
|
||||
public void testElevationSimple() throws Exception {
|
||||
for (double elevation = 0; elevation < 1000; elevation += 10) {
|
||||
builder = new TripStatisticsBuilder(System.currentTimeMillis());
|
||||
for (int j = 0; j < 100; j++) {
|
||||
assertEquals(0.0, builder.updateElevation(elevation));
|
||||
assertEquals(elevation, builder.getSmoothedElevation());
|
||||
TripStatistics data = builder.getStatistics();
|
||||
assertEquals(elevation, data.getMinElevation());
|
||||
assertEquals(elevation, data.getMaxElevation());
|
||||
assertEquals(0.0, data.getTotalElevationGain());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testElevationGain() throws Exception {
|
||||
for (double i = 0; i < 1000; i++) {
|
||||
double expectedGain;
|
||||
if (i < (Constants.ELEVATION_SMOOTHING_FACTOR - 1)) {
|
||||
expectedGain = 0;
|
||||
} else if (i < Constants.ELEVATION_SMOOTHING_FACTOR) {
|
||||
expectedGain = 0.5;
|
||||
} else {
|
||||
expectedGain = 1.0;
|
||||
}
|
||||
assertEquals(expectedGain,
|
||||
builder.updateElevation(i));
|
||||
assertEquals(i, builder.getSmoothedElevation(), 20);
|
||||
TripStatistics data = builder.getStatistics();
|
||||
assertEquals(0.0, data.getMinElevation(), 0.0);
|
||||
assertEquals(i, data.getMaxElevation(),
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
assertEquals(i, data.getTotalElevationGain(),
|
||||
Constants.ELEVATION_SMOOTHING_FACTOR);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGradeSimple() throws Exception {
|
||||
for (double i = 0; i < 1000; i++) {
|
||||
// The value of the elevation does not matter. This is just to fill the
|
||||
// buffer.
|
||||
builder.updateElevation(i);
|
||||
builder.updateGrade(100, 100);
|
||||
if ((i > Constants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > Constants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
assertEquals(1.0, builder.getStatistics().getMaxGrade());
|
||||
assertEquals(1.0, builder.getStatistics().getMinGrade());
|
||||
}
|
||||
}
|
||||
for (double i = 0; i < 1000; i++) {
|
||||
// The value of the elevation does not matter. This is just to fill the
|
||||
// buffer.
|
||||
builder.updateElevation(i);
|
||||
builder.updateGrade(100, -100);
|
||||
if ((i > Constants.GRADE_SMOOTHING_FACTOR)
|
||||
&& (i > Constants.ELEVATION_SMOOTHING_FACTOR)) {
|
||||
assertEquals(1.0, builder.getStatistics().getMaxGrade());
|
||||
assertEquals(-1.0, builder.getStatistics().getMinGrade());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testGradeIgnoreShort() throws Exception {
|
||||
for (double i = 0; i < 100; i++) {
|
||||
// The value of the elevation does not matter. This is just to fill the
|
||||
// buffer.
|
||||
builder.updateElevation(i);
|
||||
builder.updateGrade(1, 100);
|
||||
assertEquals(Double.NEGATIVE_INFINITY, builder.getStatistics().getMaxGrade());
|
||||
assertEquals(Double.POSITIVE_INFINITY, builder.getStatistics().getMinGrade());
|
||||
}
|
||||
}
|
||||
|
||||
public void testUpdateSpeedIncludeZero() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
builder.updateSpeed(i + 1000, 0.0, i, 4.0);
|
||||
assertEquals(0.0, builder.getStatistics().getMaxSpeed());
|
||||
assertEquals((i + 1) * 1000, builder.getStatistics().getMovingTime());
|
||||
}
|
||||
}
|
||||
|
||||
public void testUpdateSpeedIngoreErrorCode() {
|
||||
builder.updateSpeed(12345000, 128.0, 12344000, 0.0);
|
||||
assertEquals(0.0, builder.getStatistics().getMaxSpeed());
|
||||
assertEquals(1000, builder.getStatistics().getMovingTime());
|
||||
}
|
||||
|
||||
public void testUpdateSpeedIngoreLargeAcceleration() {
|
||||
builder.updateSpeed(12345000, 100.0, 12344000, 1.0);
|
||||
assertEquals(0.0, builder.getStatistics().getMaxSpeed());
|
||||
assertEquals(1000, builder.getStatistics().getMovingTime());
|
||||
}
|
||||
|
||||
public void testUpdateSpeed() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
builder.updateSpeed(i + 1000, 4.0, i, 4.0);
|
||||
assertEquals((i + 1) * 1000, builder.getStatistics().getMovingTime());
|
||||
if (i > Constants.SPEED_SMOOTHING_FACTOR) {
|
||||
assertEquals(4.0, builder.getStatistics().getMaxSpeed());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.stats;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link TripStatistics}.
|
||||
* This only tests non-trivial pieces of that class.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TripStatisticsTest extends TestCase {
|
||||
|
||||
private TripStatistics statistics;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
statistics = new TripStatistics();
|
||||
}
|
||||
|
||||
public void testSetBounds() {
|
||||
// This is not a trivial setter, conversion happens in it
|
||||
statistics.setBounds(12345, -34567, 56789, -98765);
|
||||
assertEquals(12345, statistics.getLeft());
|
||||
assertEquals(-34567, statistics.getTop());
|
||||
assertEquals(56789, statistics.getRight());
|
||||
assertEquals(-98765, statistics.getBottom());
|
||||
}
|
||||
|
||||
public void testMerge() {
|
||||
TripStatistics statistics2 = new TripStatistics();
|
||||
statistics.setStartTime(1000L); // Resulting start time
|
||||
statistics.setStopTime(2500L);
|
||||
statistics2.setStartTime(3000L);
|
||||
statistics2.setStopTime(4000L); // Resulting stop time
|
||||
statistics.setTotalTime(1500L);
|
||||
statistics2.setTotalTime(1000L); // Result: 1500+1000
|
||||
statistics.setMovingTime(700L);
|
||||
statistics2.setMovingTime(600L); // Result: 700+600
|
||||
statistics.setTotalDistance(750.0);
|
||||
statistics2.setTotalDistance(350.0); // Result: 750+350
|
||||
statistics.setTotalElevationGain(50.0);
|
||||
statistics2.setTotalElevationGain(850.0); // Result: 850+50
|
||||
statistics.setMaxSpeed(60.0); // Resulting max speed
|
||||
statistics2.setMaxSpeed(30.0);
|
||||
statistics.setMaxElevation(1250.0);
|
||||
statistics.setMinElevation(1200.0); // Resulting min elevation
|
||||
statistics2.setMaxElevation(3575.0); // Resulting max elevation
|
||||
statistics2.setMinElevation(2800.0);
|
||||
statistics.setMaxGrade(15.0);
|
||||
statistics.setMinGrade(-25.0); // Resulting min grade
|
||||
statistics2.setMaxGrade(35.0); // Resulting max grade
|
||||
statistics2.setMinGrade(0.0);
|
||||
|
||||
// Resulting bounds: -10000, 35000, 30000, -40000
|
||||
statistics.setBounds(-10000, 20000, 30000, -40000);
|
||||
statistics2.setBounds(-5000, 35000, 0, 20000);
|
||||
|
||||
statistics.merge(statistics2);
|
||||
|
||||
assertEquals(1000L, statistics.getStartTime());
|
||||
assertEquals(4000L, statistics.getStopTime());
|
||||
assertEquals(2500L, statistics.getTotalTime());
|
||||
assertEquals(1300L, statistics.getMovingTime());
|
||||
assertEquals(1100.0, statistics.getTotalDistance());
|
||||
assertEquals(900.0, statistics.getTotalElevationGain());
|
||||
assertEquals(60.0, statistics.getMaxSpeed());
|
||||
assertEquals(-10000, statistics.getLeft());
|
||||
assertEquals(30000, statistics.getRight());
|
||||
assertEquals(35000, statistics.getTop());
|
||||
assertEquals(-40000, statistics.getBottom());
|
||||
assertEquals(1200.0, statistics.getMinElevation());
|
||||
assertEquals(3575.0, statistics.getMaxElevation());
|
||||
assertEquals(-25.0, statistics.getMinGrade());
|
||||
assertEquals(35.0, statistics.getMaxGrade());
|
||||
}
|
||||
|
||||
public void testGetAverageSpeed() {
|
||||
statistics.setTotalDistance(1000.0);
|
||||
statistics.setTotalTime(50000); // in milliseconds
|
||||
assertEquals(20.0, statistics.getAverageSpeed());
|
||||
}
|
||||
|
||||
public void testGetAverageMovingSpeed() {
|
||||
statistics.setTotalDistance(1000.0);
|
||||
statistics.setMovingTime(20000); // in milliseconds
|
||||
assertEquals(50.0, statistics.getAverageMovingSpeed());
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// Copyright 2010 Google Inc. All Rights Reserved.
|
||||
|
||||
package com.google.android.apps.mytracks.testing;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* A fake factory for {@link MyTracksProviderUtils} which always returns a
|
||||
* predefined instance.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class TestingProviderUtilsFactory extends Factory {
|
||||
private MyTracksProviderUtils instance;
|
||||
|
||||
public TestingProviderUtilsFactory(MyTracksProviderUtils instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MyTracksProviderUtils newForContext(Context context) {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static Factory installWithInstance(MyTracksProviderUtils instance) {
|
||||
Factory oldFactory = Factory.getInstance();
|
||||
Factory factory = new TestingProviderUtilsFactory(instance);
|
||||
MyTracksProviderUtils.Factory.overrideInstance(factory);
|
||||
return oldFactory;
|
||||
}
|
||||
|
||||
public static void restoreOldFactory(Factory factory) {
|
||||
MyTracksProviderUtils.Factory.overrideInstance(factory);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2009 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for the Chart URL generator.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class ChartURLGeneratorTest extends TestCase {
|
||||
|
||||
public void testgetChartUrl() {
|
||||
Vector<Double> distances = new Vector<Double>();
|
||||
Vector<Double> elevations = new Vector<Double>();
|
||||
Track t = new Track();
|
||||
TripStatistics stats = t.getTripStatistics();
|
||||
stats.setMinElevation(0);
|
||||
stats.setMaxElevation(2000);
|
||||
stats.setTotalDistance(100);
|
||||
|
||||
distances.add(0.0);
|
||||
elevations.add(10.0);
|
||||
|
||||
distances.add(10.0);
|
||||
elevations.add(300.0);
|
||||
|
||||
distances.add(20.0);
|
||||
elevations.add(800.0);
|
||||
|
||||
distances.add(50.0);
|
||||
elevations.add(1900.0);
|
||||
|
||||
distances.add(75.0);
|
||||
elevations.add(1200.0);
|
||||
|
||||
distances.add(90.0);
|
||||
elevations.add(700.0);
|
||||
|
||||
distances.add(100.0);
|
||||
elevations.add(70.0);
|
||||
|
||||
String chart = ChartURLGenerator.getChartUrl(distances,
|
||||
elevations,
|
||||
t,
|
||||
"Title",
|
||||
true);
|
||||
|
||||
assertEquals(
|
||||
"http://chart.apis.google.com/chart?&chs=600x350&cht=lxy&"
|
||||
+ "chtt=Title&chxt=x,y&chxr=0,0,0,0|1,0.0,2100.0,300&chco=009A00&"
|
||||
+ "chm=B,00AA00,0,0,0&chg=100000,14.285714285714286,1,0&"
|
||||
+ "chd=e:AAGZMzf.v.5l..,ATJJYY55kkVVCI",
|
||||
chart);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* A unit test for {@link ChartsExtendedEncoder}.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
*/
|
||||
public class ChartsExtendedEncoderTest extends TestCase {
|
||||
|
||||
public void testGetEncodedValue_validArguments() {
|
||||
// Valid arguments.
|
||||
assertEquals("AK", ChartsExtendedEncoder.getEncodedValue(10));
|
||||
assertEquals("JO", ChartsExtendedEncoder.getEncodedValue(590));
|
||||
assertEquals("AA", ChartsExtendedEncoder.getEncodedValue(0));
|
||||
// 64^2 = 4096.
|
||||
assertEquals("..", ChartsExtendedEncoder.getEncodedValue(4095));
|
||||
}
|
||||
|
||||
public void testGetEncodedValue_invalidArguments() {
|
||||
// Invalid arguments.
|
||||
assertEquals("__", ChartsExtendedEncoder.getEncodedValue(4096));
|
||||
assertEquals("__", ChartsExtendedEncoder.getEncodedValue(1234564096));
|
||||
assertEquals("__", ChartsExtendedEncoder.getEncodedValue(-10));
|
||||
assertEquals("__", ChartsExtendedEncoder.getEncodedValue(-12324435));
|
||||
}
|
||||
|
||||
public void testGetSeparator() {
|
||||
assertEquals(",", ChartsExtendedEncoder.getSeparator());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link FileUtils}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class FileUtilsTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Tests {@link FileUtils#buildExternalDirectoryPath(String...)}.
|
||||
*/
|
||||
public void testBuildExternalDirectoryPath() {
|
||||
String expectedName = Environment.getExternalStorageDirectory() + File.separator
|
||||
+ Constants.SDCARD_TOP_DIR + File.separator + "a" + File.separator + "b" + File.separator
|
||||
+ "c";
|
||||
String dirName = FileUtils.buildExternalDirectoryPath("a", "b", "c");
|
||||
assertEquals(expectedName, dirName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link FileUtils#buildUniqueFileName(File, String, String)} when the
|
||||
* file is new.
|
||||
*/
|
||||
public void testBuildUniqueFileName_new() {
|
||||
String filename = FileUtils.buildUniqueFileName(new File("/dir"), "Filename", "ext");
|
||||
assertEquals("Filename.ext", filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link FileUtils#buildUniqueFileName(File, String, String)} when the
|
||||
* file exists already.
|
||||
*/
|
||||
public void testBuildUniqueFileName_exist() {
|
||||
// Expect "/default.prop" to exist on the phone/emulator
|
||||
String filename = FileUtils.buildUniqueFileName(new File("/"), "default", "prop");
|
||||
assertEquals("default(1).prop", filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link FileUtils#sanitizeFileName(String)} with special characters.
|
||||
* Verifies that they are sanitized.
|
||||
*/
|
||||
public void testSanitizeFileName() {
|
||||
String name = "Swim\10ming-^across:/the/ pacific (ocean).";
|
||||
String expected = "Swim_ming-^across_the_ pacific (ocean)_";
|
||||
assertEquals(expected, FileUtils.sanitizeFileName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link FileUtils#sanitizeFileName(String)} with i18n characters (in
|
||||
* Chinese and Russian). Verifies that they are allowed.
|
||||
*/
|
||||
public void testSanitizeFileName_i18n() {
|
||||
String name = "您好-привет";
|
||||
String expected = "您好-привет";
|
||||
assertEquals(expected, FileUtils.sanitizeFileName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link FileUtils#sanitizeFileName(String)} with special FAT32
|
||||
* characters. Verifies that they are allowed.
|
||||
*/
|
||||
public void testSanitizeFileName_special_characters() {
|
||||
String name = "$%'-_@~`!(){}^#&+,;=[] ";
|
||||
String expected = "$%'-_@~`!(){}^#&+,;=[] ";
|
||||
assertEquals(expected, FileUtils.sanitizeFileName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link FileUtils#sanitizeFileName(String)} with multiple escaped
|
||||
* characters in a row. Verifies that they are collapsed into one underscore.
|
||||
*/
|
||||
public void testSanitizeFileName_collapse() {
|
||||
String name = "hello//there";
|
||||
String expected = "hello_there";
|
||||
assertEquals(expected, FileUtils.sanitizeFileName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link FileUtils#truncateFileName(File, String, String)}. Verifies
|
||||
* the a long file name is truncated.
|
||||
*/
|
||||
public void testTruncateFileName() {
|
||||
File directory = new File("/dir1/dir2/");
|
||||
String suffix = ".gpx";
|
||||
char[] name = new char[FileUtils.MAX_FAT32_PATH_LENGTH];
|
||||
for (int i = 0; i < name.length; i++) {
|
||||
name[i] = 'a';
|
||||
}
|
||||
String nameString = new String(name);
|
||||
String truncated = FileUtils.truncateFileName(directory, nameString, suffix);
|
||||
|
||||
for (int i = 0; i < truncated.length(); i++) {
|
||||
assertEquals('a', truncated.charAt(i));
|
||||
}
|
||||
assertEquals(FileUtils.MAX_FAT32_PATH_LENGTH,
|
||||
new File(directory, truncated + suffix).getPath().length());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Tests for {@link StringUtils}.
|
||||
*
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
public class StringUtilsTest extends AndroidTestCase {
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#formatDateTimeIso8601(long)}.
|
||||
*/
|
||||
public void testFormatDateTimeIso8601() {
|
||||
assertEquals("1970-01-01T00:00:12.345Z", StringUtils.formatDateTimeIso8601(12345));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#formatElapsedTime(long)}.
|
||||
*/
|
||||
public void testformatElapsedTime() {
|
||||
// 1 second
|
||||
assertEquals("00:01", StringUtils.formatElapsedTime(1000));
|
||||
// 10 seconds
|
||||
assertEquals("00:10", StringUtils.formatElapsedTime(10000));
|
||||
// 1 minute
|
||||
assertEquals("01:00", StringUtils.formatElapsedTime(60000));
|
||||
// 10 minutes
|
||||
assertEquals("10:00", StringUtils.formatElapsedTime(600000));
|
||||
// 1 hour
|
||||
assertEquals("1:00:00", StringUtils.formatElapsedTime(3600000));
|
||||
// 10 hours
|
||||
assertEquals("10:00:00", StringUtils.formatElapsedTime(36000000));
|
||||
// 100 hours
|
||||
assertEquals("100:00:00", StringUtils.formatElapsedTime(360000000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#formatElapsedTimeWithHour(long)}.
|
||||
*/
|
||||
public void testformatElapsedTimeWithHour() {
|
||||
// 1 second
|
||||
assertEquals("0:00:01", StringUtils.formatElapsedTimeWithHour(1000));
|
||||
// 10 seconds
|
||||
assertEquals("0:00:10", StringUtils.formatElapsedTimeWithHour(10000));
|
||||
// 1 minute
|
||||
assertEquals("0:01:00", StringUtils.formatElapsedTimeWithHour(60000));
|
||||
// 10 minutes
|
||||
assertEquals("0:10:00", StringUtils.formatElapsedTimeWithHour(600000));
|
||||
// 1 hour
|
||||
assertEquals("1:00:00", StringUtils.formatElapsedTimeWithHour(3600000));
|
||||
// 10 hours
|
||||
assertEquals("10:00:00", StringUtils.formatElapsedTimeWithHour(36000000));
|
||||
// 100 hours
|
||||
assertEquals("100:00:00", StringUtils.formatElapsedTimeWithHour(360000000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#formatDistance(android.content.Context, double,
|
||||
* boolean)}.
|
||||
*/
|
||||
public void testFormatDistance() {
|
||||
// A large number in metric
|
||||
assertEquals("5.00 km", StringUtils.formatDistance(getContext(), 5000, true));
|
||||
// A large number in imperial
|
||||
assertEquals("3.11 mi", StringUtils.formatDistance(getContext(), 5000, false));
|
||||
// A small number in metric
|
||||
assertEquals("100.00 m", StringUtils.formatDistance(getContext(), 100, true));
|
||||
// A small number in imperial
|
||||
assertEquals("328.08 ft", StringUtils.formatDistance(getContext(), 100, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#formatSpeed(android.content.Context, double,
|
||||
* boolean, boolean)}.
|
||||
*/
|
||||
public void testFormatSpeed() {
|
||||
// Speed in metric
|
||||
assertEquals("36.00 km/h", StringUtils.formatSpeed(getContext(), 10, true, true));
|
||||
// Speed in imperial
|
||||
assertEquals("22.37 mi/h", StringUtils.formatSpeed(getContext(), 10, false, true));
|
||||
// Pace in metric
|
||||
assertEquals("1.67 min/km", StringUtils.formatSpeed(getContext(), 10, true, false));
|
||||
// Pace in imperial
|
||||
assertEquals("2.68 min/mi", StringUtils.formatSpeed(getContext(), 10, false, false));
|
||||
// zero pace
|
||||
assertEquals("0.00 min/km", StringUtils.formatSpeed(getContext(), 0, true, false));
|
||||
assertEquals("0.00 min/mi", StringUtils.formatSpeed(getContext(), 0, false, false));
|
||||
// speed is NaN
|
||||
assertEquals("-", StringUtils.formatSpeed(getContext(), Double.NaN, true, true));
|
||||
// speed is infinite
|
||||
assertEquals("-", StringUtils.formatSpeed(getContext(), Double.NEGATIVE_INFINITY, true, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#formatCData(String)}.
|
||||
*/
|
||||
public void testFormatCData() {
|
||||
assertEquals("<![CDATA[hello]]>", StringUtils.formatCData("hello"));
|
||||
assertEquals("<![CDATA[hello]]]]><![CDATA[>there]]>", StringUtils.formatCData("hello]]>there"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#getTime(String)}.
|
||||
*/
|
||||
public void testGetTime() {
|
||||
assertGetTime("2010-05-04T03:02:01", 2010, 5, 4, 3, 2, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01Z", 2010, 5, 4, 3, 2, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#getTime(String)} with fractional seconds.
|
||||
*/
|
||||
public void testGetTime_fractional() {
|
||||
assertGetTime("2010-05-04T03:02:01.3", 2010, 5, 4, 3, 2, 1, 300);
|
||||
assertGetTime("2010-05-04T03:02:01.35", 2010, 5, 4, 3, 2, 1, 350);
|
||||
assertGetTime("2010-05-04T03:02:01.352Z", 2010, 5, 4, 3, 2, 1, 352);
|
||||
assertGetTime("2010-05-04T03:02:01.3525Z", 2010, 5, 4, 3, 2, 1, 352);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#getTime(String)} with time zone.
|
||||
*/
|
||||
public void testGetTime_timezone() {
|
||||
assertGetTime("2010-05-04T03:02:01Z", 2010, 5, 4, 3, 2, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01+00:00", 2010, 5, 4, 3, 2, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01-00:00", 2010, 5, 4, 3, 2, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01+01:00", 2010, 5, 4, 2, 2, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01+10:30", 2010, 5, 3, 16, 32, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01-09:30", 2010, 5, 4, 12, 32, 1, 0);
|
||||
assertGetTime("2010-05-04T03:02:01-05:00", 2010, 5, 4, 8, 2, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#getTime(String)} with fractional seconds and time
|
||||
* zone.
|
||||
*/
|
||||
public void testGetTime_fractionalAndTimezone() {
|
||||
assertGetTime("2010-05-04T03:02:01.352Z", 2010, 5, 4, 3, 2, 1, 352);
|
||||
assertGetTime("2010-05-04T03:02:01.47+00:00", 2010, 5, 4, 3, 2, 1, 470);
|
||||
assertGetTime("2010-05-04T03:02:01.5791+03:00", 2010, 5, 4, 0, 2, 1, 579);
|
||||
assertGetTime("2010-05-04T03:02:01.8-05:30", 2010, 5, 4, 8, 32, 1, 800);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts the {@link StringUtils#getTime(String)} returns the expected
|
||||
* values.
|
||||
*
|
||||
* @param xmlDateTime the xml date time string
|
||||
* @param year the expected year
|
||||
* @param month the expected month
|
||||
* @param day the expected day
|
||||
* @param hour the expected hour
|
||||
* @param minute the expected minute
|
||||
* @param second the expected second
|
||||
* @param millisecond the expected milliseconds
|
||||
*/
|
||||
private void assertGetTime(String xmlDateTime, int year, int month, int day, int hour, int minute,
|
||||
int second, int millisecond) {
|
||||
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
||||
calendar.set(year, month - 1, day, hour, minute, second);
|
||||
calendar.set(GregorianCalendar.MILLISECOND, millisecond);
|
||||
assertEquals(calendar.getTimeInMillis(), StringUtils.getTime(xmlDateTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#getTimeParts(long)} with a positive number.
|
||||
*/
|
||||
public void testGetTimeParts_postive() {
|
||||
int parts[] = StringUtils.getTimeParts(61000);
|
||||
assertEquals(1, parts[0]);
|
||||
assertEquals(1, parts[1]);
|
||||
assertEquals(0, parts[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link StringUtils#getTimeParts(long)} with a negative number.
|
||||
*/
|
||||
public void testGetTimeParts_negative() {
|
||||
int parts[] = StringUtils.getTimeParts(-61000);
|
||||
assertEquals(-1, parts[0]);
|
||||
assertEquals(-1, parts[1]);
|
||||
assertEquals(0, parts[2]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Tests {@link TrackNameUtils}.
|
||||
*
|
||||
* @author Matthew Simmons
|
||||
*/
|
||||
public class TrackNameUtilsTest extends AndroidTestCase {
|
||||
|
||||
private static final long TRACK_ID = 1L;
|
||||
private static final long START_TIME = 1288213406000L;
|
||||
|
||||
/**
|
||||
* Tests when the track_name_key is
|
||||
* settings_recording_track_name_date_local_value.
|
||||
*/
|
||||
public void testTrackName_date_local() {
|
||||
PreferencesUtils.setString(getContext(), R.string.track_name_key,
|
||||
getContext().getString(R.string.settings_recording_track_name_date_local_value));
|
||||
assertEquals(StringUtils.formatDateTime(getContext(), START_TIME),
|
||||
TrackNameUtils.getTrackName(getContext(), TRACK_ID, START_TIME, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests when the track_name_key is
|
||||
* settings_recording_track_name_date_iso_8601_value.
|
||||
*/
|
||||
public void testTrackName_date_iso_8601() {
|
||||
PreferencesUtils.setString(getContext(), R.string.track_name_key,
|
||||
getContext().getString(R.string.settings_recording_track_name_date_iso_8601_value));
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(TrackNameUtils.ISO_8601_FORMAT);
|
||||
assertEquals(simpleDateFormat.format(new Date(START_TIME)),
|
||||
TrackNameUtils.getTrackName(getContext(), TRACK_ID, START_TIME, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests when the track_name_key is
|
||||
* settings_recording_track_name_number_value.
|
||||
*/
|
||||
public void testTrackName_number() {
|
||||
PreferencesUtils.setString(getContext(), R.string.track_name_key,
|
||||
getContext().getString(R.string.settings_recording_track_name_number_value));
|
||||
assertEquals(
|
||||
"Track " + TRACK_ID, TrackNameUtils.getTrackName(getContext(), TRACK_ID, START_TIME, null));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user