Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
2b1a0663
authored
Jan 06, 2020
by
ibaker
Committed by
Ian Baker
Jan 06, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add RubySpan support to SpannedSubject
PiperOrigin-RevId: 288280332
parent
e55af3e3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
230 additions
and
2 deletions
testutils/src/main/java/com/google/android/exoplayer2/testutil/truth/SpannedSubject.java
testutils/src/test/java/com/google/android/exoplayer2/testutil/truth/SpannedSubjectTest.java
testutils/src/main/java/com/google/android/exoplayer2/testutil/truth/SpannedSubject.java
View file @
2b1a0663
...
@@ -30,6 +30,7 @@ import android.text.style.UnderlineSpan;
...
@@ -30,6 +30,7 @@ import android.text.style.UnderlineSpan;
import
androidx.annotation.CheckResult
;
import
androidx.annotation.CheckResult
;
import
androidx.annotation.ColorInt
;
import
androidx.annotation.ColorInt
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.text.span.RubySpan
;
import
com.google.common.truth.FailureMetadata
;
import
com.google.common.truth.FailureMetadata
;
import
com.google.common.truth.Subject
;
import
com.google.common.truth.Subject
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
...
@@ -194,7 +195,7 @@ public final class SpannedSubject extends Subject {
...
@@ -194,7 +195,7 @@ public final class SpannedSubject extends Subject {
}
}
/**
/**
* Checks that the subject as a {@link ForegroundColorSpan} from {@code start} to {@code end}.
* Checks that the subject
h
as a {@link ForegroundColorSpan} from {@code start} to {@code end}.
*
*
* <p>The color is asserted in a follow-up method call on the return {@link Colored} object.
* <p>The color is asserted in a follow-up method call on the return {@link Colored} object.
*
*
...
@@ -222,7 +223,7 @@ public final class SpannedSubject extends Subject {
...
@@ -222,7 +223,7 @@ public final class SpannedSubject extends Subject {
}
}
/**
/**
* Checks that the subject
as a {@link Fore
groundColorSpan} from {@code start} to {@code end}.
* Checks that the subject
has a {@link Back
groundColorSpan} from {@code start} to {@code end}.
*
*
* <p>The color is asserted in a follow-up method call on the return {@link Colored} object.
* <p>The color is asserted in a follow-up method call on the return {@link Colored} object.
*
*
...
@@ -249,6 +250,30 @@ public final class SpannedSubject extends Subject {
...
@@ -249,6 +250,30 @@ public final class SpannedSubject extends Subject {
.
that
(
backgroundColorSpans
);
.
that
(
backgroundColorSpans
);
}
}
/**
* Checks that the subject has a {@link RubySpan} from {@code start} to {@code end}.
*
* <p>The ruby-text is asserted in a follow-up method call on the return {@link RubyText} object.
*
* @param start The start of the expected span.
* @param end The end of the expected span.
* @return A {@link Colored} object to assert on the color of the matching spans.
*/
@CheckResult
public
RubyText
hasRubySpanBetween
(
int
start
,
int
end
)
{
if
(
actual
==
null
)
{
failWithoutActual
(
simpleFact
(
"Spanned must not be null"
));
return
ALREADY_FAILED_WITH_TEXT
;
}
List
<
RubySpan
>
rubySpans
=
findMatchingSpans
(
start
,
end
,
RubySpan
.
class
);
if
(
rubySpans
.
isEmpty
())
{
failWithExpectedSpan
(
start
,
end
,
RubySpan
.
class
,
actual
.
toString
().
substring
(
start
,
end
));
return
ALREADY_FAILED_WITH_TEXT
;
}
return
check
(
"RubySpan (start=%s,end=%s)"
,
start
,
end
).
about
(
rubySpans
(
actual
)).
that
(
rubySpans
);
}
private
<
T
>
List
<
T
>
findMatchingSpans
(
int
startIndex
,
int
endIndex
,
Class
<
T
>
spanClazz
)
{
private
<
T
>
List
<
T
>
findMatchingSpans
(
int
startIndex
,
int
endIndex
,
Class
<
T
>
spanClazz
)
{
List
<
T
>
spans
=
new
ArrayList
<>();
List
<
T
>
spans
=
new
ArrayList
<>();
for
(
T
span
:
actual
.
getSpans
(
startIndex
,
endIndex
,
spanClazz
))
{
for
(
T
span
:
actual
.
getSpans
(
startIndex
,
endIndex
,
spanClazz
))
{
...
@@ -440,4 +465,92 @@ public final class SpannedSubject extends Subject {
...
@@ -440,4 +465,92 @@ public final class SpannedSubject extends Subject {
return
check
(
"flags"
).
about
(
spanFlags
()).
that
(
matchingSpanFlags
);
return
check
(
"flags"
).
about
(
spanFlags
()).
that
(
matchingSpanFlags
);
}
}
}
}
/** Allows assertions about a span's ruby text and its position. */
public
interface
RubyText
{
/**
* Checks that at least one of the matched spans has the expected {@code text}.
*
* @param text The expected text.
* @param position The expected position of the text.
* @return A {@link WithSpanFlags} object for optional additional assertions on the flags.
*/
AndSpanFlags
withTextAndPosition
(
String
text
,
@RubySpan
.
Position
int
position
);
}
private
static
final
RubyText
ALREADY_FAILED_WITH_TEXT
=
(
text
,
position
)
->
ALREADY_FAILED_AND_FLAGS
;
private
Factory
<
RubySpansSubject
,
List
<
RubySpan
>>
rubySpans
(
Spanned
actualSpanned
)
{
return
(
FailureMetadata
metadata
,
List
<
RubySpan
>
spans
)
->
new
RubySpansSubject
(
metadata
,
spans
,
actualSpanned
);
}
private
static
final
class
RubySpansSubject
extends
Subject
implements
RubyText
{
private
final
List
<
RubySpan
>
actualSpans
;
private
final
Spanned
actualSpanned
;
private
RubySpansSubject
(
FailureMetadata
metadata
,
List
<
RubySpan
>
actualSpans
,
Spanned
actualSpanned
)
{
super
(
metadata
,
actualSpans
);
this
.
actualSpans
=
actualSpans
;
this
.
actualSpanned
=
actualSpanned
;
}
@Override
public
AndSpanFlags
withTextAndPosition
(
String
text
,
@RubySpan
.
Position
int
position
)
{
List
<
Integer
>
matchingSpanFlags
=
new
ArrayList
<>();
List
<
TextAndPosition
>
spanTextsAndPositions
=
new
ArrayList
<>();
for
(
RubySpan
span
:
actualSpans
)
{
spanTextsAndPositions
.
add
(
new
TextAndPosition
(
span
.
rubyText
,
span
.
position
));
if
(
span
.
rubyText
.
equals
(
text
))
{
matchingSpanFlags
.
add
(
actualSpanned
.
getSpanFlags
(
span
));
}
}
check
(
"rubyTextAndPosition"
)
.
that
(
spanTextsAndPositions
)
.
containsExactly
(
new
TextAndPosition
(
text
,
position
));
return
check
(
"flags"
).
about
(
spanFlags
()).
that
(
matchingSpanFlags
);
}
private
static
class
TextAndPosition
{
private
final
String
text
;
@RubySpan
.
Position
private
final
int
position
;
private
TextAndPosition
(
String
text
,
int
position
)
{
this
.
text
=
text
;
this
.
position
=
position
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
TextAndPosition
that
=
(
TextAndPosition
)
o
;
if
(
position
!=
that
.
position
)
{
return
false
;
}
return
text
.
equals
(
that
.
text
);
}
@Override
public
int
hashCode
()
{
int
result
=
text
.
hashCode
();
result
=
31
*
result
+
position
;
return
result
;
}
@Override
public
String
toString
()
{
return
String
.
format
(
"{text='%s',position=%s}"
,
text
,
position
);
}
}
}
}
}
testutils/src/test/java/com/google/android/exoplayer2/testutil/truth/SpannedSubjectTest.java
View file @
2b1a0663
...
@@ -30,6 +30,7 @@ import android.text.style.ForegroundColorSpan;
...
@@ -30,6 +30,7 @@ import android.text.style.ForegroundColorSpan;
import
android.text.style.StyleSpan
;
import
android.text.style.StyleSpan
;
import
android.text.style.UnderlineSpan
;
import
android.text.style.UnderlineSpan
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.text.span.RubySpan
;
import
com.google.common.truth.ExpectFailure
;
import
com.google.common.truth.ExpectFailure
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runner.RunWith
;
...
@@ -338,6 +339,120 @@ public class SpannedSubjectTest {
...
@@ -338,6 +339,120 @@ public class SpannedSubjectTest {
.
contains
(
String
.
valueOf
(
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
));
.
contains
(
String
.
valueOf
(
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
));
}
}
@Test
public
void
rubySpan_success
()
{
SpannableString
spannable
=
SpannableString
.
valueOf
(
"test with rubied section"
);
int
start
=
"test with "
.
length
();
int
end
=
start
+
"rubied"
.
length
();
spannable
.
setSpan
(
new
RubySpan
(
"ruby text"
,
RubySpan
.
POSITION_OVER
),
start
,
end
,
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
);
assertThat
(
spannable
)
.
hasRubySpanBetween
(
start
,
end
)
.
withTextAndPosition
(
"ruby text"
,
RubySpan
.
POSITION_OVER
)
.
andFlags
(
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
);
}
@Test
public
void
rubySpan_wrongEndIndex
()
{
SpannableString
spannable
=
SpannableString
.
valueOf
(
"test with cyan section"
);
int
start
=
"test with "
.
length
();
int
end
=
start
+
"cyan"
.
length
();
spannable
.
setSpan
(
new
RubySpan
(
"ruby text"
,
RubySpan
.
POSITION_OVER
),
start
,
end
,
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
);
int
incorrectEnd
=
end
+
2
;
AssertionError
expected
=
expectFailure
(
whenTesting
->
whenTesting
.
that
(
spannable
)
.
hasRubySpanBetween
(
start
,
incorrectEnd
)
.
withTextAndPosition
(
"ruby text"
,
RubySpan
.
POSITION_OVER
));
assertThat
(
expected
).
factValue
(
"expected"
).
contains
(
"end="
+
incorrectEnd
);
assertThat
(
expected
).
factValue
(
"but found"
).
contains
(
"end="
+
end
);
}
@Test
public
void
rubySpan_wrongText
()
{
SpannableString
spannable
=
SpannableString
.
valueOf
(
"test with rubied section"
);
int
start
=
"test with "
.
length
();
int
end
=
start
+
"rubied"
.
length
();
spannable
.
setSpan
(
new
RubySpan
(
"ruby text"
,
RubySpan
.
POSITION_OVER
),
start
,
end
,
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
);
AssertionError
expected
=
expectFailure
(
whenTesting
->
whenTesting
.
that
(
spannable
)
.
hasRubySpanBetween
(
start
,
end
)
.
withTextAndPosition
(
"incorrect text"
,
RubySpan
.
POSITION_OVER
));
assertThat
(
expected
).
factValue
(
"value of"
).
contains
(
"rubyTextAndPosition"
);
assertThat
(
expected
).
factValue
(
"expected"
).
contains
(
"text='incorrect text'"
);
assertThat
(
expected
).
factValue
(
"but was"
).
contains
(
"text='ruby text'"
);
}
@Test
public
void
rubySpan_wrongPosition
()
{
SpannableString
spannable
=
SpannableString
.
valueOf
(
"test with rubied section"
);
int
start
=
"test with "
.
length
();
int
end
=
start
+
"rubied"
.
length
();
spannable
.
setSpan
(
new
RubySpan
(
"ruby text"
,
RubySpan
.
POSITION_OVER
),
start
,
end
,
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
);
AssertionError
expected
=
expectFailure
(
whenTesting
->
whenTesting
.
that
(
spannable
)
.
hasRubySpanBetween
(
start
,
end
)
.
withTextAndPosition
(
"ruby text"
,
RubySpan
.
POSITION_UNDER
));
assertThat
(
expected
).
factValue
(
"value of"
).
contains
(
"rubyTextAndPosition"
);
assertThat
(
expected
).
factValue
(
"expected"
).
contains
(
"position="
+
RubySpan
.
POSITION_UNDER
);
assertThat
(
expected
).
factValue
(
"but was"
).
contains
(
"position="
+
RubySpan
.
POSITION_OVER
);
}
@Test
public
void
rubySpan_wrongFlags
()
{
SpannableString
spannable
=
SpannableString
.
valueOf
(
"test with rubied section"
);
int
start
=
"test with "
.
length
();
int
end
=
start
+
"rubied"
.
length
();
spannable
.
setSpan
(
new
RubySpan
(
"ruby text"
,
RubySpan
.
POSITION_OVER
),
start
,
end
,
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
);
AssertionError
expected
=
expectFailure
(
whenTesting
->
whenTesting
.
that
(
spannable
)
.
hasRubySpanBetween
(
start
,
end
)
.
withTextAndPosition
(
"ruby text"
,
RubySpan
.
POSITION_OVER
)
.
andFlags
(
Spanned
.
SPAN_EXCLUSIVE_EXCLUSIVE
));
assertThat
(
expected
).
factValue
(
"value of"
).
contains
(
"flags"
);
assertThat
(
expected
)
.
factValue
(
"expected to contain"
)
.
contains
(
String
.
valueOf
(
Spanned
.
SPAN_EXCLUSIVE_EXCLUSIVE
));
assertThat
(
expected
)
.
factValue
(
"but was"
)
.
contains
(
String
.
valueOf
(
Spanned
.
SPAN_INCLUSIVE_EXCLUSIVE
));
}
private
static
AssertionError
expectFailure
(
private
static
AssertionError
expectFailure
(
ExpectFailure
.
SimpleSubjectBuilderCallback
<
SpannedSubject
,
Spanned
>
callback
)
{
ExpectFailure
.
SimpleSubjectBuilderCallback
<
SpannedSubject
,
Spanned
>
callback
)
{
return
expectFailureAbout
(
spanned
(),
callback
);
return
expectFailureAbout
(
spanned
(),
callback
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment