Merge branch 'documentation/JAL-2751patch2102b2' into releases/Release_2_10_2b1_Branch
[jalview.git] / test / jalview / analysis / RnaTest.java
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.assertNull;
26 import static org.testng.AssertJUnit.assertTrue;
27 import static org.testng.AssertJUnit.fail;
28
29 import jalview.analysis.SecStrConsensus.SimpleBP;
30 import jalview.gui.JvOptionPane;
31
32 import java.util.Vector;
33
34 import org.testng.annotations.BeforeClass;
35 import org.testng.annotations.Test;
36
37 public class RnaTest
38 {
39
40   @BeforeClass(alwaysRun = true)
41   public void setUpJvOptionPane()
42   {
43     JvOptionPane.setInteractiveMode(false);
44     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
45   }
46
47   @Test(groups = { "Functional" })
48   public void testGetSimpleBPs() throws WUSSParseException
49   {
50     String rna = "([{})]"; // JAL-1081 example
51     Vector<SimpleBP> bps = Rna.getSimpleBPs(rna);
52     assertEquals(3, bps.size());
53
54     /*
55      * the base pairs are added in the order in which the matching base is found
56      * (popping the stack of unmatched opening brackets)
57      */
58     assertEquals(2, bps.get(0).bp5); // {
59     assertEquals(3, bps.get(0).bp3); // }
60     assertEquals(0, bps.get(1).bp5); // (
61     assertEquals(4, bps.get(1).bp3); // )
62     assertEquals(1, bps.get(2).bp5); // [
63     assertEquals(5, bps.get(2).bp3); // ]
64   }
65
66   @Test(groups = { "Functional" })
67   public void testGetSimpleBPs_unmatchedOpener()
68   {
69     String rna = "(([{})]";
70     try
71     {
72       Rna.getSimpleBPs(rna);
73       fail("expected exception");
74     } catch (WUSSParseException e)
75     {
76       // error reported as after end of input string
77       assertEquals(rna.length(), e.getProblemPos());
78     }
79   }
80
81   @Test(groups = { "Functional" })
82   public void testGetSimpleBPs_unmatchedCloser()
83   {
84     String rna = "([{})]]]";
85     try
86     {
87       Rna.getSimpleBPs(rna);
88       fail("expected exception");
89     } catch (WUSSParseException e)
90     {
91       // error reported as at first unmatched close
92       assertEquals(6, e.getProblemPos());
93     }
94
95     /*
96      * a variant where we have no opening bracket of the same type
97      * as the unmatched closing bracket (no stack rather than empty stack)
98      */
99     rna = "((()])";
100     try
101     {
102       Rna.getSimpleBPs(rna);
103       fail("expected exception");
104     } catch (WUSSParseException e)
105     {
106       assertEquals(4, e.getProblemPos());
107     }
108   }
109
110   @Test(groups = { "Functional" })
111   public void testGetRNASecStrucState()
112   {
113     assertNull(Rna.getRNASecStrucState(null));
114     for (int i = 0; i <= 255; i++)
115     {
116       String s = String.valueOf((char) i);
117       String ss = Rna.getRNASecStrucState(s);
118
119       /*
120        * valid SS chars are a-z, A-Z, and various brackets;
121        * anything else is returned as a space
122        */
123       if ((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z')
124               || "()[]{}<>".indexOf(s) > -1)
125       {
126         assertEquals("" + i, s, ss);
127       }
128       else
129       {
130         assertEquals(" ", ss);
131       }
132     }
133
134     /*
135      * a string is processed character by character
136      */
137     assertEquals("a [K ]z} {Q b(w)p><i",
138             Rna.getRNASecStrucState("a.[K-]z}?{Q b(w)p><i"));
139   }
140
141   /**
142    * Tests for isClosingParenthesis with char or String argument
143    */
144   @Test(groups = { "Functional" })
145   public void testIsClosingParenthesis()
146   {
147     assertFalse(Rna.isClosingParenthesis(null));
148
149     /*
150      * only a-z, )]}> are closing bracket symbols
151      */
152     for (int i = 0; i <= 255; i++)
153     {
154       boolean isClosingChar = Rna.isClosingParenthesis((char) i);
155       boolean isClosingString = Rna.isClosingParenthesis(String
156               .valueOf((char) i));
157       if ((i >= 'a' && i <= 'z') || i == ')' || i == '}' || i == ']'
158               || i == '>')
159       {
160         assertTrue(String.format("close base pair %c", i), isClosingChar);
161         assertTrue(String.format("close base pair %c", i), isClosingString);
162       }
163       else
164       {
165         assertFalse(String.format("close base pair %c", i), isClosingChar);
166         assertFalse(String.format("close base pair %c", i), isClosingString);
167       }
168       assertFalse(Rna.isClosingParenthesis(String.valueOf((char) i) + " "));
169     }
170   }
171
172   @Test(groups = { "Functional" })
173   public void testIsCanonicalOrWobblePair()
174   {
175     String bases = "acgtuACGTU";
176     for (int i = 0; i < bases.length(); i++)
177     {
178       for (int j = 0; j < bases.length(); j++)
179       {
180         char first = bases.charAt(i);
181         char second = bases.charAt(j);
182         boolean result = Rna.isCanonicalOrWobblePair(first, second);
183         String pair = new String(new char[] { first, second })
184                 .toUpperCase();
185         if (pair.equals("AT") || pair.equals("TA") || pair.equals("AU")
186                 || pair.equals("UA") || pair.equals("GC")
187                 || pair.equals("CG") || pair.equals("GT")
188                 || pair.equals("TG") || pair.equals("GU")
189                 || pair.equals("UG"))
190         {
191           assertTrue(pair + " should be valid", result);
192         }
193         else
194         {
195           assertFalse(pair + " should be invalid", result);
196         }
197       }
198     }
199   }
200
201   @Test(groups = { "Functional" })
202   public void testIsCanonicalPair()
203   {
204     String bases = "acgtuACGTU";
205     for (int i = 0; i < bases.length(); i++)
206     {
207       for (int j = 0; j < bases.length(); j++)
208       {
209         char first = bases.charAt(i);
210         char second = bases.charAt(j);
211         boolean result = Rna.isCanonicalPair(first, second);
212         String pair = new String(new char[] { first, second })
213                 .toUpperCase();
214         if (pair.equals("AT") || pair.equals("TA") || pair.equals("AU")
215                 || pair.equals("UA") || pair.equals("GC")
216                 || pair.equals("CG"))
217         {
218           assertTrue(pair + " should be valid", result);
219         }
220         else
221         {
222           assertFalse(pair + " should be invalid", result);
223         }
224       }
225     }
226   }
227
228   /**
229    * Tests for isOpeningParenthesis with char or String argument
230    */
231   @Test(groups = { "Functional" })
232   public void testIsOpeningParenthesis()
233   {
234     /*
235      * only A-Z, ([{< are opening bracket symbols
236      */
237     for (int i = 0; i <= 255; i++)
238     {
239       boolean isOpeningChar = Rna.isOpeningParenthesis((char) i);
240       boolean isOpeningString = Rna.isOpeningParenthesis(String
241               .valueOf((char) i));
242       if ((i >= 'A' && i <= 'Z') || i == '(' || i == '{' || i == '['
243               || i == '<')
244       {
245         assertTrue(String.format("Open base pair %c", i), isOpeningChar);
246         assertTrue(String.format("Open base pair %c", i), isOpeningString);
247       }
248       else
249       {
250         assertFalse(String.format("Open base pair %c", i), isOpeningChar);
251         assertFalse(String.format("Open base pair %c", i), isOpeningString);
252       }
253       assertFalse(Rna.isOpeningParenthesis(String.valueOf((char) i) + " "));
254     }
255   }
256
257   @Test(groups = { "Functional" })
258   public void testGetMatchingOpeningParenthesis() throws WUSSParseException
259   {
260     for (int i = 0; i <= 255; i++)
261     {
262       boolean isClosing = Rna.isClosingParenthesis((char) i);
263       if (isClosing)
264       {
265         char opening = Rna.getMatchingOpeningParenthesis((char) i);
266         if (i >= 'a' && i <= 'z')
267         {
268           assertEquals(i + 'A' - 'a', opening);
269         }
270         else if (i == ')' && opening == '(' || i == ']' && opening == '['
271                 || i == '}' && opening == '{' || i == '>' && opening == '<')
272         {
273           // ok
274         }
275         else
276         {
277           fail("Got " + opening + " as opening bracket pair for "
278                   + ((char) i));
279         }
280       }
281     }
282   }
283
284   /**
285    * Tests for isRnaSecondaryStructureSymbol with char or String argument
286    */
287   @Test(groups = { "Functional" })
288   public void testIsRnaSecondaryStructureSymbol()
289   {
290     assertFalse(Rna.isRnaSecondaryStructureSymbol(null));
291
292     /*
293      * only A-Z,  a-z, ()[]{}<> are valid symbols
294      */
295     for (int i = 0; i <= 255; i++)
296     {
297       boolean isValidChar = Rna.isRnaSecondaryStructureSymbol((char) i);
298       boolean isValidString = Rna.isRnaSecondaryStructureSymbol(String
299               .valueOf((char) i));
300       if ((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z') || i == '('
301               || i == ')' || i == '{' || i == '}' || i == '[' || i == ']'
302               || i == '<' || i == '>')
303       {
304         assertTrue(String.format("close base pair %c", i), isValidChar);
305         assertTrue(String.format("close base pair %c", i), isValidString);
306       }
307       else
308       {
309         assertFalse(String.format("close base pair %c", i), isValidChar);
310         assertFalse(String.format("close base pair %c", i), isValidString);
311       }
312       assertFalse(Rna.isRnaSecondaryStructureSymbol(String
313               .valueOf((char) i) + " "));
314     }
315   }
316 }