Clover icon

Coverage Report

  1. Project Clover database Wed Nov 12 2025 09:00:47 GMT
  2. Package jalview.analysis

File AlignmentAnnotationUtilsTest.java

 

Code metrics

2
235
11
1
540
360
12
0.05
21.36
11
1.09

Classes

Class Line # Actions
AlignmentAnnotationUtilsTest 52 235 12
1.0100%
 

Contributing tests

This file is covered by 10 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.analysis;
22   
23    import static org.testng.AssertJUnit.assertEquals;
24    import static org.testng.AssertJUnit.assertFalse;
25    import static org.testng.AssertJUnit.assertTrue;
26   
27    import jalview.datamodel.AlignmentAnnotation;
28    import jalview.datamodel.AlignmentI;
29    import jalview.datamodel.Annotation;
30    import jalview.datamodel.PDBEntry;
31    import jalview.datamodel.Sequence;
32    import jalview.datamodel.SequenceI;
33    import jalview.gui.JvOptionPane;
34    import jalview.io.DataSourceType;
35    import jalview.io.FileFormat;
36    import jalview.util.Constants;
37   
38    import java.io.IOException;
39    import java.util.ArrayList;
40    import java.util.BitSet;
41    import java.util.Collection;
42    import java.util.HashMap;
43    import java.util.List;
44    import java.util.Map;
45    import java.util.Vector;
46   
47    import org.testng.annotations.BeforeClass;
48    import org.testng.annotations.BeforeMethod;
49    import org.testng.annotations.DataProvider;
50    import org.testng.annotations.Test;
51   
 
52    public class AlignmentAnnotationUtilsTest
53    {
54   
 
55  1 toggle @BeforeClass(alwaysRun = true)
56    public void setUpJvOptionPane()
57    {
58  1 JvOptionPane.setInteractiveMode(false);
59  1 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
60    }
61   
62    // 4 sequences x 13 positions
63    final static String EOL = "\n";
64   
65    // @formatter:off
66    final static String TEST_DATA =
67    ">FER_CAPAA Ferredoxin" + EOL +
68    "TIETHKEAELVG-" + EOL +
69    ">FER_CAPAN Ferredoxin, chloroplast precursor" + EOL +
70    "TIETHKEAELVG-" + EOL +
71    ">FER1_SOLLC Ferredoxin-1, chloroplast precursor" + EOL +
72    "TIETHKEEELTA-" + EOL +
73    ">Q93XJ9_SOLTU Ferredoxin I precursor" + EOL +
74    "TIETHKEEELTA-" + EOL;
75    // @formatter:on
76   
77    private static final int SEQ_ANN_COUNT = 12;
78   
79    private AlignmentI alignment;
80   
81    /**
82    * Test method that converts a (possibly null) array to a list.
83    */
 
84  1 toggle @Test(groups = { "Functional" })
85    public void testAsList()
86    {
87    // null array
88  1 Collection<AlignmentAnnotation> c1 = AlignmentAnnotationUtils
89    .asList(null);
90  1 assertTrue(c1.isEmpty());
91   
92    // empty array
93  1 AlignmentAnnotation[] anns = new AlignmentAnnotation[0];
94  1 c1 = AlignmentAnnotationUtils.asList(anns);
95  1 assertTrue(c1.isEmpty());
96   
97    // non-empty array
98  1 anns = new AlignmentAnnotation[2];
99  1 anns[0] = new AlignmentAnnotation("label0", "desc0", 0.0f);
100  1 anns[1] = new AlignmentAnnotation("label1", "desc1", 1.0f);
101  1 c1 = AlignmentAnnotationUtils.asList(anns);
102  1 assertEquals(2, c1.size());
103  1 assertTrue(c1.contains(anns[0]));
104  1 assertTrue(c1.contains(anns[1]));
105    }
106   
107    /**
108    * This output is not part of the test but may help make sense of it...
109    *
110    * @param shownTypes
111    * @param hiddenTypes
112    */
 
113  2 toggle protected void consoleDebug(Map<String, List<List<String>>> shownTypes,
114    Map<String, List<List<String>>> hiddenTypes)
115    {
116  2 for (String calcId : shownTypes.keySet())
117    {
118  3 System.out.println("Visible annotation types for calcId=" + calcId);
119  3 for (List<String> type : shownTypes.get(calcId))
120    {
121  3 System.out.println(" " + type);
122    }
123    }
124  2 for (String calcId : hiddenTypes.keySet())
125    {
126  4 System.out.println("Hidden annotation types for calcId=" + calcId);
127  4 for (List<String> type : hiddenTypes.get(calcId))
128    {
129  5 System.out.println(" " + type);
130    }
131    }
132    }
133   
134    /**
135    * Add a sequence group to the alignment with the specified sequences (base 0)
136    * in it
137    *
138    * @param i
139    * @param more
140    */
 
141  2 toggle private List<SequenceI> selectSequences(int... selected)
142    {
143  2 List<SequenceI> result = new ArrayList<SequenceI>();
144  2 SequenceI[] seqs = alignment.getSequencesArray();
145  2 for (int i : selected)
146    {
147  4 result.add(seqs[i]);
148    }
149  2 return result;
150    }
151   
152    /**
153    * Load the test alignment and generate annotations on it
154    *
155    * @throws IOException
156    */
 
157  11 toggle @BeforeMethod(alwaysRun = true)
158    public void setUp() throws IOException
159    {
160  11 alignment = new jalview.io.FormatAdapter().readFile(TEST_DATA,
161    DataSourceType.PASTE, FileFormat.Fasta);
162   
163  11 AlignmentAnnotation[] anns = new AlignmentAnnotation[SEQ_ANN_COUNT];
164  143 for (int i = 0; i < anns.length; i++)
165    {
166    /*
167    * Use the constructor for a positional annotation (with an Annotation
168    * array)
169    */
170  132 anns[i] = new AlignmentAnnotation("Label" + i, "Desc " + i,
171    new Annotation[] {});
172  132 anns[i].setCalcId("CalcId" + i);
173  132 anns[i].visible = true;
174  132 alignment.addAnnotation(anns[i]);
175    }
176    }
177   
178    /**
179    * Test a mixture of show/hidden annotations in/outside selection group.
180    */
 
181  1 toggle @Test(groups = { "Functional" })
182    public void testGetShownHiddenTypes_forSelectionGroup()
183    {
184  1 Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
185  1 Map<String, List<List<String>>> hiddenTypes = new HashMap<String, List<List<String>>>();
186  1 AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
187  1 SequenceI[] seqs = alignment.getSequencesArray();
188   
189    /*
190    * Configure annotation properties for test
191    */
192    // not in selection group (should be ignored):
193    // hidden annotation Label4 not in selection group
194  1 anns[4].sequenceRef = seqs[2];
195  1 anns[4].visible = false;
196  1 anns[7].sequenceRef = seqs[1];
197  1 anns[7].visible = true;
198   
199    /*
200    * in selection group, hidden:
201    */
202  1 anns[2].sequenceRef = seqs[3]; // CalcId2/Label2
203  1 anns[2].visible = false;
204  1 anns[3].sequenceRef = seqs[3]; // CalcId3/Label2
205  1 anns[3].visible = false;
206  1 anns[3].label = "Label2";
207  1 anns[4].sequenceRef = seqs[3]; // CalcId2/Label3
208  1 anns[4].visible = false;
209  1 anns[4].label = "Label3";
210  1 anns[4].setCalcId("CalcId2");
211  1 anns[8].sequenceRef = seqs[0]; // CalcId9/Label9
212  1 anns[8].visible = false;
213  1 anns[8].label = "Label9";
214  1 anns[8].setCalcId("CalcId9");
215    /*
216    * in selection group, visible
217    */
218  1 anns[6].sequenceRef = seqs[0]; // CalcId6/Label6
219  1 anns[6].visible = true;
220  1 anns[9].sequenceRef = seqs[3]; // CalcId9/Label9
221  1 anns[9].visible = true;
222   
223  1 List<SequenceI> selected = selectSequences(0, 3);
224  1 AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
225    AlignmentAnnotationUtils.asList(anns), selected);
226   
227    // check results; note CalcId9/Label9 is both hidden and shown (for
228    // different sequences) so should be in both
229    // shown: CalcId6/Label6 and CalcId9/Label9
230  1 assertEquals(2, shownTypes.size());
231  1 assertEquals(1, shownTypes.get("CalcId6").size());
232  1 assertEquals(1, shownTypes.get("CalcId6").get(0).size());
233  1 assertEquals("Label6", shownTypes.get("CalcId6").get(0).get(0));
234  1 assertEquals(1, shownTypes.get("CalcId9").size());
235  1 assertEquals(1, shownTypes.get("CalcId9").get(0).size());
236  1 assertEquals("Label9", shownTypes.get("CalcId9").get(0).get(0));
237   
238    // hidden: CalcId2/Label2, CalcId2/Label3, CalcId3/Label2, CalcId9/Label9
239  1 assertEquals(3, hiddenTypes.size());
240  1 assertEquals(2, hiddenTypes.get("CalcId2").size());
241  1 assertEquals(1, hiddenTypes.get("CalcId2").get(0).size());
242  1 assertEquals("Label2", hiddenTypes.get("CalcId2").get(0).get(0));
243  1 assertEquals(1, hiddenTypes.get("CalcId2").get(1).size());
244  1 assertEquals("Label3", hiddenTypes.get("CalcId2").get(1).get(0));
245  1 assertEquals(1, hiddenTypes.get("CalcId3").size());
246  1 assertEquals(1, hiddenTypes.get("CalcId3").get(0).size());
247  1 assertEquals("Label2", hiddenTypes.get("CalcId3").get(0).get(0));
248  1 assertEquals(1, hiddenTypes.get("CalcId9").size());
249  1 assertEquals(1, hiddenTypes.get("CalcId9").get(0).size());
250  1 assertEquals("Label9", hiddenTypes.get("CalcId9").get(0).get(0));
251   
252  1 consoleDebug(shownTypes, hiddenTypes);
253    }
254   
255    /**
256    * Test case where there are 'grouped' annotations, visible and hidden, within
257    * and without the selection group.
258    */
 
259  1 toggle @Test(groups = { "Functional" })
260    public void testGetShownHiddenTypes_withGraphGroups()
261    {
262  1 final int GROUP_3 = 3;
263  1 final int GROUP_4 = 4;
264  1 final int GROUP_5 = 5;
265  1 final int GROUP_6 = 6;
266   
267  1 Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
268  1 Map<String, List<List<String>>> hiddenTypes = new HashMap<String, List<List<String>>>();
269  1 AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
270  1 SequenceI[] seqs = alignment.getSequencesArray();
271   
272    /*
273    * Annotations for selection group and graph group
274    *
275    * Hidden annotations Label2, Label3, in (hidden) group 5
276    */
277  1 anns[2].sequenceRef = seqs[3];
278  1 anns[2].visible = false;
279  1 anns[2].graph = AlignmentAnnotation.LINE_GRAPH;
280  1 anns[2].graphGroup = GROUP_5; // not a visible group
281  1 anns[3].sequenceRef = seqs[0];
282  1 anns[3].visible = false;
283  1 anns[3].graph = AlignmentAnnotation.LINE_GRAPH;
284  1 anns[3].graphGroup = GROUP_5;
285    // need to ensure annotations have the same calcId as well
286  1 anns[3].setCalcId("CalcId2");
287    // annotations for a different hidden group generating the same group label
288  1 anns[10].sequenceRef = seqs[0];
289  1 anns[10].visible = false;
290  1 anns[10].graph = AlignmentAnnotation.LINE_GRAPH;
291  1 anns[10].graphGroup = GROUP_3;
292  1 anns[10].label = "Label3";
293  1 anns[10].setCalcId("CalcId2");
294  1 anns[11].sequenceRef = seqs[3];
295  1 anns[11].visible = false;
296  1 anns[11].graph = AlignmentAnnotation.LINE_GRAPH;
297  1 anns[11].graphGroup = GROUP_3;
298  1 anns[11].label = "Label2";
299  1 anns[11].setCalcId("CalcId2");
300   
301    // annotations Label1 (hidden), Label5 (visible) in group 6 (visible)
302  1 anns[1].sequenceRef = seqs[3];
303    // being in a visible group should take precedence over this visibility
304  1 anns[1].visible = false;
305  1 anns[1].graph = AlignmentAnnotation.LINE_GRAPH;
306  1 anns[1].graphGroup = GROUP_6;
307  1 anns[5].sequenceRef = seqs[0];
308  1 anns[5].visible = true;
309  1 anns[5].graph = AlignmentAnnotation.LINE_GRAPH;
310  1 anns[5].graphGroup = GROUP_6;
311  1 anns[5].setCalcId("CalcId1");
312    /*
313    * Annotations 0 and 4 are visible, for a different CalcId and graph group.
314    * They produce the same label as annotations 1 and 5, which should not be
315    * duplicated in the results. This case corresponds to (e.g.) many
316    * occurrences of an IUPred Short/Long annotation group, one per sequence.
317    */
318  1 anns[4].sequenceRef = seqs[0];
319  1 anns[4].visible = false;
320  1 anns[4].graph = AlignmentAnnotation.LINE_GRAPH;
321  1 anns[4].graphGroup = GROUP_4;
322  1 anns[4].label = "Label1";
323  1 anns[4].setCalcId("CalcId1");
324  1 anns[0].sequenceRef = seqs[0];
325  1 anns[0].visible = true;
326  1 anns[0].graph = AlignmentAnnotation.LINE_GRAPH;
327  1 anns[0].graphGroup = GROUP_4;
328  1 anns[0].label = "Label5";
329  1 anns[0].setCalcId("CalcId1");
330   
331    /*
332    * Annotations outwith selection group - should be ignored.
333    */
334    // Hidden grouped annotations
335  1 anns[6].sequenceRef = seqs[2];
336  1 anns[6].visible = false;
337  1 anns[6].graph = AlignmentAnnotation.LINE_GRAPH;
338  1 anns[6].graphGroup = GROUP_4;
339  1 anns[8].sequenceRef = seqs[1];
340  1 anns[8].visible = false;
341  1 anns[8].graph = AlignmentAnnotation.LINE_GRAPH;
342  1 anns[8].graphGroup = GROUP_4;
343   
344    // visible grouped annotations Label7, Label9
345  1 anns[7].sequenceRef = seqs[2];
346  1 anns[7].visible = true;
347  1 anns[7].graph = AlignmentAnnotation.LINE_GRAPH;
348  1 anns[7].graphGroup = GROUP_4;
349  1 anns[9].sequenceRef = seqs[1];
350  1 anns[9].visible = true;
351  1 anns[9].graph = AlignmentAnnotation.LINE_GRAPH;
352  1 anns[9].graphGroup = GROUP_4;
353   
354    /*
355    * Generate annotations[] arrays to match aligned columns
356    */
357    // adjustForAlignment(anns);
358   
359  1 List<SequenceI> selected = selectSequences(0, 3);
360  1 AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
361    AlignmentAnnotationUtils.asList(anns), selected);
362   
363  1 consoleDebug(shownTypes, hiddenTypes);
364   
365    // CalcId1 / Label1, Label5 (only) should be 'shown', once, as a compound
366    // type
367  1 assertEquals(1, shownTypes.size());
368  1 assertEquals(1, shownTypes.get("CalcId1").size());
369  1 assertEquals(2, shownTypes.get("CalcId1").get(0).size());
370  1 assertEquals("Label1", shownTypes.get("CalcId1").get(0).get(0));
371  1 assertEquals("Label5", shownTypes.get("CalcId1").get(0).get(1));
372   
373    // CalcId2 / Label2, Label3 (only) should be 'hidden'
374  1 assertEquals(1, hiddenTypes.size());
375  1 assertEquals(1, hiddenTypes.get("CalcId2").size());
376  1 assertEquals(2, hiddenTypes.get("CalcId2").get(0).size());
377  1 assertEquals("Label2", hiddenTypes.get("CalcId2").get(0).get(0));
378  1 assertEquals("Label3", hiddenTypes.get("CalcId2").get(0).get(1));
379    }
380   
381    /**
382    * Test method that determines visible graph groups.
383    */
 
384  1 toggle @Test(groups = { "Functional" })
385    public void testGetVisibleGraphGroups()
386    {
387  1 AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
388    /*
389    * a bar graph group is not included
390    */
391  1 anns[0].graph = AlignmentAnnotation.BAR_GRAPH;
392  1 anns[0].graphGroup = 1;
393  1 anns[0].visible = true;
394   
395    /*
396    * a line graph group is included as long as one of its members is visible
397    */
398  1 anns[1].graph = AlignmentAnnotation.LINE_GRAPH;
399  1 anns[1].graphGroup = 5;
400  1 anns[1].visible = false;
401  1 anns[2].graph = AlignmentAnnotation.LINE_GRAPH;
402  1 anns[2].graphGroup = 5;
403  1 anns[2].visible = true;
404   
405    /*
406    * a line graph group with no visible rows is not included
407    */
408  1 anns[3].graph = AlignmentAnnotation.LINE_GRAPH;
409  1 anns[3].graphGroup = 3;
410  1 anns[3].visible = false;
411   
412    // a visible line graph with no graph group is not included
413  1 anns[4].graph = AlignmentAnnotation.LINE_GRAPH;
414  1 anns[4].graphGroup = -1;
415  1 anns[4].visible = true;
416   
417  1 BitSet result = AlignmentAnnotationUtils.getVisibleLineGraphGroups(
418    AlignmentAnnotationUtils.asList(anns));
419  1 assertTrue(result.get(5));
420  1 assertFalse(result.get(0));
421  1 assertFalse(result.get(1));
422  1 assertFalse(result.get(2));
423  1 assertFalse(result.get(3));
424    }
425   
426    /**
427    * Test for case where no sequence is selected. Shouldn't normally arise but
428    * check it handles it gracefully.
429    */
 
430  1 toggle @Test(groups = { "Functional" })
431    public void testGetShownHiddenTypes_noSequenceSelected()
432    {
433  1 Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
434  1 Map<String, List<List<String>>> hiddenTypes = new HashMap<String, List<List<String>>>();
435  1 AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
436    // selected sequences null
437  1 AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
438    AlignmentAnnotationUtils.asList(anns), null);
439  1 assertTrue(shownTypes.isEmpty());
440  1 assertTrue(hiddenTypes.isEmpty());
441   
442  1 List<SequenceI> sequences = new ArrayList<SequenceI>();
443    // selected sequences empty list
444  1 AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
445    AlignmentAnnotationUtils.asList(anns), sequences);
446  1 assertTrue(shownTypes.isEmpty());
447  1 assertTrue(hiddenTypes.isEmpty());
448    }
449   
450   
451   
 
452  1 toggle @DataProvider(name = "SSSourceFromAnnotationDescription")
453    public static Object[][] provideSSSourceFromAnnotationDescription()
454    {
455    // Case 1: Annotation from JPred
456  1 AlignmentAnnotation annotation1 = new AlignmentAnnotation("jnetpred",
457    "JPred Output", new Annotation[] {});
458   
459    // Case 2: Annotation from AlphaFold
460  1 SequenceI seq2 = new Sequence("Seq2", "ASD---ASD------", 37, 42);
461  1 AlignmentAnnotation annotation2 = new AlignmentAnnotation(
462    "Secondary Structure", "Secondary Structure for af-q43517-f1A",
463    new Annotation[] {});
464  1 PDBEntry pdbEntry2 = new PDBEntry();
465  1 pdbEntry2.setId("af-q43517");
466  1 pdbEntry2.setProvider("Alphafold");
467  1 Vector<PDBEntry> pdbEntries2 = new Vector<>();
468  1 pdbEntries2.add(pdbEntry2);
469  1 SequenceI ds2 = new Sequence("Seq2", "ASD---ASD------", 37, 42);
470  1 ds2.setPDBId(pdbEntries2);
471  1 seq2.setDatasetSequence(ds2);
472  1 annotation2.sequenceRef = seq2;
473   
474    // Case 3: Annotation from PDB
475  1 SequenceI seq3 = new Sequence("Seq4", "ASD---ASD---AS-", 37, 44);
476  1 AlignmentAnnotation annotation3 = new AlignmentAnnotation(
477    "Secondary Structure", "Secondary Structure for 1ABC",
478    new Annotation[] {});
479  1 annotation3.setProperty(Constants.PDBID, "1ABC");
480  1 annotation3.setProperty(Constants.CHAINID, "A");
481  1 PDBEntry pdbEntry3 = new PDBEntry();
482  1 pdbEntry3.setId("1ABC:A");
483  1 Vector<PDBEntry> pdbEntries3 = new Vector<>();
484  1 pdbEntries3.add(pdbEntry3);
485  1 SequenceI ds3 = new Sequence("Seq2", "ASD---ASD------", 37, 42);
486  1 ds3.setPDBId(pdbEntries3);
487  1 seq3.setDatasetSequence(ds3);
488  1 annotation3.sequenceRef = seq3;
489   
490    // Case 4: Annotation from Swiss Model
491  1 SequenceI seq4 = new Sequence("Seq5", "ASD---ASD---AS-", 37, 44);
492  1 AlignmentAnnotation annotation4 = new AlignmentAnnotation(
493    "Secondary Structure",
494    "Secondary Structure for 1ABC",
495    new Annotation[] {});
496  1 PDBEntry pdbEntry4 = new PDBEntry();
497  1 pdbEntry4.setId("1ABC:A");
498  1 pdbEntry4.setProvider("Swiss Model");
499  1 Vector<PDBEntry> pdbEntries4 = new Vector<>();
500  1 pdbEntries4.add(pdbEntry4);
501  1 SequenceI ds4 = new Sequence("Seq2", "ASD---ASD------", 37, 42);
502  1 ds4.setPDBId(pdbEntries4);
503  1 seq4.setDatasetSequence(ds4);
504  1 annotation4.sequenceRef = seq4;
505   
506    // Case 5: Annotation with SS provider property set
507  1 AlignmentAnnotation annotation5 = new AlignmentAnnotation(
508    "Secondary Structure", "Secondary Structure",
509    new Annotation[] {});
510  1 annotation5.setProperty(Constants.SS_PROVIDER_PROPERTY, "MyProvider");
511   
512    // Case 6: Annotation with unmatching labels
513  1 AlignmentAnnotation annotation6 = new AlignmentAnnotation("Consensus",
514    "Consensus", new Annotation[] {});
515   
516  1 return new Object[][] { { annotation1, "JPred", null },
517    { annotation2, "Alphafold", null },
518    { annotation3, "PDB", "1ABC:A" },
519    { annotation4, "Swiss Model", null },
520    { annotation5, "MyProvider", null },
521    { annotation6, null, null } };
522    }
523   
 
524  6 toggle @Test(dataProvider = "SSSourceFromAnnotationDescription", groups = { "Functional" })
525    public void testExtractSSSourceFromAnnotationDescription(
526    AlignmentAnnotation annotation, String expectedProvider,
527    String expectedAnnotationDetails)
528    {
529   
530  6 String actualProvider = AlignmentAnnotationUtils
531    .extractSSSourceFromAnnotationDescription(annotation);
532   
533  6 assertEquals(expectedProvider, actualProvider);
534  6 assertEquals(expectedProvider,
535    annotation.getProperty(Constants.SS_PROVIDER_PROPERTY));
536  6 assertEquals(expectedAnnotationDetails,
537    annotation.getAnnotationDetailsProperty());
538    }
539   
540    }