001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.drjava.model.definitions.reducedmodel;
038:
039: /**
040: * Tests the interaction between quotes and backslashes.
041: * @version $Id: SingleQuoteTest.java 4255 2007-08-28 19:17:37Z mgricken $
042: */
043: public final class SingleQuoteTest extends BraceReductionTestCase
044: implements ReducedModelStates {
045: /**
046: * Tests the relationship between backslash characters and quote characters.
047: * It focuses on the case where the backslash is inserted first before the quote.
048: */
049: public void testInsideQuotePrevious() {
050: model1.insertChar('\'');
051: model1.insertChar('\\');
052: model1.insertChar('\'');
053: model1.move(-2);
054: // "#\"
055: assertEquals("#0.0", "\\'", model1.currentToken().getType());
056: assertEquals("#0.1", INSIDE_SINGLE_QUOTE,
057: stateOfCurrentToken(model1));
058: model1.move(2);
059: model1.insertChar('\'');
060: model1.move(-1);
061: // '\'#'
062: assertEquals("#1.0", "\'", model1.currentToken().getType());
063: assertEquals("#1.1", FREE, stateOfCurrentToken(model1));
064: assertTrue("#1.2", model1.currentToken().isClosed());
065: model1.move(1);
066: model1.insertChar('\'');
067: model1.insertChar('\\');
068: model1.insertChar('\\');
069: model1.move(-2);
070: // '\'''#\\
071: assertEquals("#2.0", "\\\\", model1.currentToken().getType());
072: assertEquals("#2.1", INSIDE_SINGLE_QUOTE,
073: stateOfCurrentToken(model1));
074: model1.move(2);
075: model1.insertChar('\\');
076: model1.move(-1);
077: // '\'''\\#\
078: assertEquals("#3.0", "\\", model1.currentToken().getType());
079: assertEquals("#3.1", INSIDE_SINGLE_QUOTE,
080: stateOfCurrentToken(model1));
081: model1.move(1);
082: model1.insertChar('\'');
083: model1.move(-1);
084: // '\'''\\\#"
085: assertEquals("#4.0", "\\'", model1.currentToken().getType());
086: assertEquals("#4.1", INSIDE_SINGLE_QUOTE,
087: stateOfCurrentToken(model1));
088: }
089:
090: /**
091: * Tests the relationship between backslashes and quotes.
092: * Focuses on the case where a backslash is inserted and turns a regular quote
093: * into an escaped quote.
094: */
095: public void testInsideQuoteNext() {
096: model1.insertChar('\'');
097: model1.insertChar('\'');
098: model1.move(-1);
099: model1.insertChar('\\');
100: assertEquals("#0.0", "\\'", model1.currentToken().getType());
101: assertEquals("#0.1", INSIDE_SINGLE_QUOTE,
102: stateOfCurrentToken(model1));
103: assertEquals("#0.2", 1, model1.getBlockOffset());
104: model1.move(1);
105: model1.insertChar('\'');
106: model1.move(-1);
107: assertEquals("#1.0", "\'", model1.currentToken().getType());
108: assertEquals("#1.1", FREE, stateOfCurrentToken(model1));
109: assertTrue("#1.2", model1.currentToken().isClosed());
110: model1.move(1);
111: model1.insertChar('\'');
112: model1.insertChar('\\');
113: model1.move(-1);
114: model1.insertChar('\\');
115: assertEquals("#2.0", "\\\\", model1.currentToken().getType());
116: assertEquals("#2.1", INSIDE_SINGLE_QUOTE,
117: stateOfCurrentToken(model1));
118: assertEquals("#2.2", 6, model1.absOffset());
119: model1.move(-2);
120: model1.insertChar('{');
121: model1.move(-1);
122: assertEquals("#3.0", "{", model1.currentToken().getType());
123: assertEquals("#3.1", FREE, stateOfCurrentToken(model1));
124: model1.move(1);
125: model1.move(3);
126: model1.insertChar('\'');
127: model1.move(-1);
128: assertEquals("#4.0", "\'", model1.currentToken().getType());
129: assertEquals("#4.1", FREE, stateOfCurrentToken(model1));
130: assertTrue("#4.2", model1.currentToken().isClosed());
131: model1.insertChar('\\');
132: assertEquals("#5.0", "\\'", model1.currentToken().getType());
133: assertEquals("#5.1", INSIDE_SINGLE_QUOTE,
134: stateOfCurrentToken(model1));
135: assertEquals("#5.2", 1, model1.getBlockOffset());
136: }
137:
138: /**
139: * Tests the case when a backslash is inserted before two backslashes.
140: * The existing double escape is broken and the first two backslashes become
141: * a double escape with the third backslash ending up alone.
142: */
143: public void testBackSlashBeforeDoubleEscape() {
144: model1.insertChar('\\');
145: model1.insertChar('\\');
146: model1.move(-2);
147: model1.insertChar('\\');
148: assertEquals("#0.0", "\\\\", model1.currentToken().getType());
149: assertEquals("#0.1", 2, model1.currentToken().getSize());
150: model1.move(1);
151: assertEquals("#0.2", "\\", model1.currentToken().getType());
152: model2.insertChar('\\');
153: model2.insertChar('\'');
154: model2.move(-2);
155: model2.insertChar('\\');
156: assertEquals("#1.0", "\\\\", model2.currentToken().getType());
157: assertEquals("#1.1", 1, model2.absOffset());
158: model2.move(1);
159: assertEquals("#1.2", "'", model2.currentToken().getType());
160: }
161:
162: /**
163: * Tests the case where a backslash breaks up two backslashes together.
164: * The newly inserted backslash and the first backslash form a new double escape
165: * and the second backslash in the previous double escape becomes free.
166: */
167: public void testInsertBetweenDoubleEscape() {
168: model1.insertChar('\\');
169: model1.insertChar('\\');
170: model1.move(-1);
171: model1.insertChar('\\');
172: model1.move(-2);
173: assertEquals("#0.0", "\\\\", model1.currentToken().getType());
174: model1.move(2);
175: assertEquals("#0.1", "\\", model1.currentToken().getType());
176: model2.insertChar('\\');
177: model2.insertChar('\'');
178: model2.move(-1);
179: model2.insertChar('\\');
180: model2.move(-2);
181: assertEquals("#1.0", "\\\\", model2.currentToken().getType());
182: model2.move(2);
183: assertEquals("#1.1", "\'", model2.currentToken().getType());
184: model0.insertChar('\\');
185: model0.insertChar('\\');
186: model0.move(-1);
187: model0.insertChar(')');
188: model0.move(-2);
189: assertEquals("#2.0", "\\", model0.currentToken().getType());
190: model0.move(1);
191: assertEquals("#2.1", ")", model0.currentToken().getType());
192: model0.move(1);
193: assertEquals("#2.2", "\\", model0.currentToken().getType());
194: model0.move(1);
195: model0.delete(-3);
196: model0.insertChar('\\');
197: model0.insertChar('\'');
198: model0.move(-1);
199: model0.insertChar(')');
200: model0.move(-2);
201: assertEquals("#3.0", "\\", model0.currentToken().getType());
202: model0.move(1);
203: assertEquals("#3.1", ")", model0.currentToken().getType());
204: model0.move(1);
205: assertEquals("#3.2", "'", model0.currentToken().getType());
206: }
207:
208: /**
209: * Tests the case where deletion combines a backslash and a quote or two backslashes.
210: * The deletion of characters in between the two special characters brings them together
211: * and unites them into a 2-character special token.
212: */
213: public void testDeleteAndCombine() {
214: model0.insertChar('\\');
215: insertGap(model0, 2);
216: model0.insertChar('\'');
217: model0.move(-1);
218: assertEquals("#0.0", "\'", model0.currentToken().getType());
219: model0.delete(-2);
220: assertEquals("#1.0", "\\'", model0.currentToken().getType());
221: assertEquals("#1.1", 1, model0.absOffset());
222: model0.delete(1);
223: insertGap(model0, 2);
224: model0.insertChar('\\');
225: model0.move(-1);
226: assertEquals("#2.0", "\\", model0.currentToken().getType());
227: model0.delete(-2);
228: assertEquals("#3.0", "\\\\", model0.currentToken().getType());
229: assertEquals("#3.1", 2, model0.currentToken().getSize());
230: }
231:
232: /**
233: * Tests more of the same sort of cases as found in testDeleteAndCombine().
234: */
235: public void testDeleteAndCombine2() {
236: model0.insertChar('\\');
237: model0.insertChar('\'');
238: model0.move(-1);
239: model0.delete(-1);
240: assertEquals("#0.0", "\'", model0.currentToken().getType());
241: assertEquals("#0.1", FREE, model0.getStateAtCurrent());
242: model1.insertChar('\\');
243: model1.insertChar('\\');
244: model1.delete(-1);
245: model1.move(-1);
246: assertEquals("#1.0", "\\", model1.currentToken().getType());
247: model1.move(1);
248: model1.insertChar('\\');
249: model1.move(-1);
250: model1.delete(-1);
251: assertEquals("#2.0", "\\", model1.currentToken().getType());
252: }
253:
254: /**
255: * More of the same sort of cases as found in testDeleteAndCombine().
256: */
257: public void testDeleteAndCombine3() {
258: model0.insertChar('\\');
259: model0.insertChar('\\');
260: insertGap(model0, 3);
261: model0.insertChar('\\');
262: model0.move(-1);
263: model0.delete(-4);
264: assertEquals("#0.0", "\\\\", model0.currentToken().getType());
265: assertEquals("#0.1", 1, model0.absOffset());
266: model1.insertChar('\\');
267: insertGap(model1, 3);
268: model1.insertChar('\\');
269: model1.insertChar('\'');
270: model1.move(-1);
271: model1.delete(-4);
272: assertEquals("#1.0", "\\\'", model1.currentToken().getType());
273: assertEquals("#1.1", 1, model1.absOffset());
274: }
275:
276: /**
277: * Tests cases where a long chain of backslashes and quotes can be all altered with a simple
278: * insertion or deletion of a special character.
279: */
280: public void testChainEffect() {
281: model0.insertChar('\'');
282: model0.insertChar('\\');
283: model0.insertChar('\'');
284: model0.insertChar('\'');
285: model0.insertChar('\'');
286: model0.insertChar('\\');
287: model0.insertChar('\'');
288: model0.insertChar('\'');
289: model0.insertChar('\'');
290: model0.insertChar('\\');
291: model0.insertChar('\'');
292: model0.insertChar('\'');
293: // '\'''\'''\''#
294: model0.move(-1);
295: assertEquals("#0.0", "\'", model0.currentToken().getType());
296: assertTrue("#0.1", model0.currentToken().isClosed());
297: model0.move(-2);
298: // '\'''\'''#\''
299: assertEquals("#1.0", "\\'", model0.currentToken().getType());
300: assertEquals("#1.1", INSIDE_SINGLE_QUOTE,
301: stateOfCurrentToken(model0));
302: model0.move(-1);
303: assertEquals("#1.2", "'", model0.currentToken().getType());
304: assertEquals("#1.3", FREE, stateOfCurrentToken(model0));
305: assertTrue("#1.4", model0.currentToken().isOpen());
306: model0.move(1);
307: model0.insertChar('\\');
308: // '\'''\'''\#\''
309: assertEquals("#2.0", "\\\\", model0.currentToken().getType());
310: assertEquals("#2.1", INSIDE_SINGLE_QUOTE,
311: stateOfCurrentToken(model0));
312: assertEquals("#2.2", 10, model0.absOffset());
313: model0.move(-2);
314: assertEquals("#2.3", "'", model0.currentToken().getType());
315: assertEquals("#2.4", FREE, stateOfCurrentToken(model0));
316: assertTrue("#2.5", model0.currentToken().isOpen());
317: model0.move(3);
318: assertEquals("#2.6", "'", model0.currentToken().getType());
319: assertEquals("#2.7", FREE, stateOfCurrentToken(model0));
320: assertTrue("#2.8", model0.currentToken().isClosed());
321: model0.move(-1);
322: model0.insertChar('\'');
323: // '\'''\'''\'#\''
324: assertEquals("#3.0", "\\'", model0.currentToken().getType());
325: assertEquals("#3.1", INSIDE_SINGLE_QUOTE,
326: stateOfCurrentToken(model0));
327: assertEquals("#3.2", 11, model0.absOffset());
328: model0.move(-2);
329: assertEquals("#3.3", "\\'", model0.currentToken().getType());
330: assertEquals("#3.4", INSIDE_SINGLE_QUOTE,
331: stateOfCurrentToken(model0));
332: model0.move(4);
333: assertEquals("#3.5", "'", model0.currentToken().getType());
334: assertEquals("#3.6", FREE, stateOfCurrentToken(model0));
335: assertTrue("#3.7", model0.currentToken().isClosed());
336: model0.move(-12);
337: // '#\'''\'''\'\''
338: model0.delete(1);
339: // '#'''\'''\'\''
340: model0.move(-1);
341: // #''''\'''\'\''
342: assertEquals("#4.0", "'", model0.currentToken().getType());
343: assertTrue("#4.1", model0.currentToken().isOpen());
344: assertEquals("#4.2", FREE, stateOfCurrentToken(model0));
345: model0.move(1);
346: // '#'''\'''\'\''
347: assertEquals("#4.3", "'", model0.currentToken().getType());
348: assertTrue("#4.4", model0.currentToken().isClosed());
349: assertEquals("#4.5", FREE, stateOfCurrentToken(model0));
350: model0.move(1);
351: // ''#''\'''\'\''
352: assertEquals("#5.0", "'", model0.currentToken().getType());
353: assertTrue("#5.1", model0.currentToken().isOpen());
354: assertEquals("#5.2", FREE, stateOfCurrentToken(model0));
355: model0.move(1);
356: // '''#'\'''\'\''
357: assertEquals("#5.3", "'", model0.currentToken().getType());
358: assertTrue("#5.4", model0.currentToken().isClosed());
359: assertEquals("#5.5", FREE, stateOfCurrentToken(model0));
360: model0.move(1);
361: // ''''#\'''\'\''
362: assertEquals("#5.6", "\\'", model0.currentToken().getType());
363: assertEquals("#5.7", FREE, stateOfCurrentToken(model0));
364: model0.move(2);
365: // ''''\'#''\'\''
366: assertEquals("#6.0", "'", model0.currentToken().getType());
367: assertTrue("#6.1", model0.currentToken().isOpen());
368: assertEquals("#6.2", FREE, stateOfCurrentToken(model0));
369: model0.move(1);
370: // ''''\''#'\'\''
371: assertEquals("#6.3", "'", model0.currentToken().getType());
372: assertTrue("#6.4", model0.currentToken().isClosed());
373: assertEquals("#6.5", FREE, stateOfCurrentToken(model0));
374: model0.move(1);
375: // ''''\'''#\'\''
376: assertEquals("#6.6", "\\'", model0.currentToken().getType());
377: assertEquals("#6.7", FREE, stateOfCurrentToken(model0));
378: model0.move(2);
379: // ''''\'''\'#\''
380: assertEquals("#6.0", "\\'", model0.currentToken().getType());
381: assertEquals("#6.1", FREE, stateOfCurrentToken(model0));
382: model0.move(2);
383: // ''''\'''\'\'#'
384: assertEquals("#6.2", "'", model0.currentToken().getType());
385: assertTrue("#6.3", model0.currentToken().isOpen());
386: assertEquals("#6.4", FREE, stateOfCurrentToken(model0));
387: }
388: }
|