Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 5440a6b9b65833f09ab52568c989386752f81c61 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
//
//  ========================================================================
//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.toolchain.test;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.Path;

import junit.framework.TestCase;

import org.junit.Assert;

/**
 * Common utility methods for working with JUnit tests cases in a maven friendly way.
 */
public final class MavenTestingUtils
{
    private static Path basePath;
    private static Path testResourcesPath;
    private static Path targetPath;

    private MavenTestingUtils()
    {
        /* prevent instantiation */
    }

    /**
     * Obtain a {@link File} reference to the maven ${basedir} for the module.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getBasePath().toFile()</code>
     * 
     * @return the equivalent to the maven ${basedir} property.
     * @see #getBasePath()
     * @deprecated use {@link #getBaseDir()} instead
     */
    @Deprecated
    public static File getBasedir()
    {
        return getBaseDir();
    }
    
    /**
     * Obtain a {@link File} reference to the maven ${basedir} for the module.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getBasePath().toFile()</code>
     * 
     * @return the equivalent to the maven ${basedir} property.
     * @see #getBasePath()
     */
    public static File getBaseDir()
    {
        return getBasePath().toFile();
    }

    /**
     * Obtain a {@link Path} reference to the maven ${basedir} for the module.
     * <p>
     * Note: while running in maven, the ${basedir} is populated by maven and used by the surefire-plugin. <br>
     * While running in eclipse, the ${basedir} property is unset, resulting in this method falling back to ${user.dir}
     * equivalent use.
     * 
     * @return the equivalent to the maven ${basedir} property.
     */
    public static Path getBasePath()
    {
        if (basePath == null)
        {
            String cwd = System.getProperty("basedir");

            if (cwd == null)
            {
                cwd = System.getProperty("user.dir");
            }

            try
            {
                basePath = new File(cwd).toPath().toRealPath();
            }
            catch (IOException e)
            {
                // if toRealPath() fails, fallback to as detected version.
                basePath = new File(cwd).getAbsoluteFile().toPath();
            }
        }

        return basePath;
    }

    /**
     * Get the Basedir for the project as a URI
     * 
     * @return the URI for the project basedir
     */
    public static URI getBaseURI()
    {
        return getBasePath().toUri();
    }

    /**
     * Get the {@link File} reference to the <code>/target</code> directory for this project.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetPath().toFile()</code>
     * 
     * @return the directory path to the target directory.
     * @see #getTargetPath()
     */
    public static File getTargetDir()
    {
        return getTargetPath().toFile();
    }

    /**
     * Get the {@link Path} reference to the <code>/target</code> directory for this project.
     * <p>
     * This is roughly equivalent to the <code>${project.build.directory}</code> property.
     * <p>
     * Note: this implementation does not inspect the <code>pom.xml</code> for non-standard locations
     * of the <code>${project.build.directory}</code> property. (it always assumes <code>/target</code>) 
     * 
     * @return the directory path to the <code>/target</code> directory.
     */
    public static Path getTargetPath()
    {
        if (targetPath == null)
        {
            targetPath = getBasePath().resolve("target");
            PathAssert.assertDirExists("Target Dir",targetPath);
        }
        return targetPath;
    }

    /**
     * Create a {@link File} object for a path in the /target directory.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetPath("foo").toFile()</code>
     * 
     * @param path
     *            the path desired, no validation of existence is performed.
     * @return the File to the path.
     * @see #getTargetPath(String)
     */
    public static File getTargetFile(String path)
    {
        return getTargetPath(path).toFile();
    }

    /**
     * Create a {@link Path} object for a path in the /target directory.
     * 
     * @param path
     *            the path desired, no validation of existence is performed.
     * @return the File to the path.
     */
    public static Path getTargetPath(String path)
    {
        Path targetPath = getTargetPath();
        FileSystem fs = targetPath.getFileSystem();
        return fs.getPath(targetPath.toString(),path);
    }
    
    /**
     * Get a {@link File} reference to the maven <code>${basedir}/target/tests/</code> directory.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetTestingPath().toFile()</code>
     * 
     * @return the maven <code>${basedir}/target/tests/</code> directory.
     *         Note: will not validate that the directory exists, or create the directory)
     */
    public static File getTargetTestingDir()
    {
        return getTargetTestingPath().toFile();
    }

    /**
     * Get a {@link Path} reference to the maven <code>${basedir}/target/tests/</code> path.
     * 
     * @return the maven <code>${basedir}/target/tests/</code> directory.
     *         Note: will not validate that the directory exists, or create the directory)
     */
    public static Path getTargetTestingPath()
    {
        return getTargetPath().resolve("tests");
    }

    /**
     * Get a {@link File} reference to the maven <code>${basedir}/target/tests/test-${testname}</code> using
     * the supplied testname
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetTestingPath(testname).toFile()</code>
     * 
     * @param testname
     *            the testname to create directory against.
     * @return the maven <code>${basedir}/target/tests/test-${testname}</code> directory
     */
    public static File getTargetTestingDir(String testname)
    {
        return getTargetTestingPath(testname).toFile();
    }

    /**
     * Get a {@link Path} reference to the maven <code>${basedir}/target/tests/test-${testname}</code> using
     * the supplied testname
     * 
     * @param testname
     *            the testname to create directory against.
     * @return the maven <code>${basedir}/target/tests/test-${testname}</code> directory
     */
    public static Path getTargetTestingPath(String testname)
    {
        return getTargetTestingPath().resolve("test-" + testname);
    }

    /**
     * Get a {@link File} reference to the <code>${basedir}/target/tests/test-${testname}</code> directory.
     * Uses the JUnit 3.x {@link TestCase#getName()} to make a unique directory name per test.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetTestingPath(TestCase.getName()).toFile()</code>
     * 
     * @param test
     *            the junit 3.x testcase to base this new directory on.
     * @return the maven <code>${basedir}/target/tests/test-${testname}</code> directory.
     */
    public static File getTargetTestingDir(TestCase test)
    {
        return getTargetTestingPath(test.getName()).toFile();
    }

    /**
     * Get a {@link Path} reference to the <code>${basedir}/target/tests/test-${testname}</code> directory.
     * Uses the JUnit 3.x {@link TestCase#getName()} to make a unique directory name per test.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetTestingPath(TestCase.getName())</code>
     * 
     * @param test
     *            the junit 3.x testcase to base this new directory on.
     * @return the maven <code>${basedir}/target/tests/test-${testname}</code> directory.
     * @see #getTargetTestingPath(String)
     */
    public static Path getTargetTestingPath(TestCase test)
    {
        return getTargetTestingPath(test.getName());
    }

    /**
     * Get a URI reference to a path (File or Dir) within the maven "${basedir}/target" directory.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetPath(path).toUri()</code>
     * 
     * @param path
     *            the relative path to use
     * @return the URI reference to the target path
     */
    public static URI getTargetURI(String path)
    {
        return getTargetPath(path).toUri();
    }

    /**
     * Get a URL reference to a path (File or Dir) within the maven "${basedir}/target" directory.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetURI(path).toURL()</code>
     * 
     * @param path
     *            the relative path to use
     * @return the URL reference to the target path
     * @throws MalformedURLException
     *             if unable to create a new target url due to URL error.
     */
    public static URL getTargetURL(String path) throws MalformedURLException
    {
        return getTargetURI(path).toURL();
    }

    /**
     * Obtain a testing directory reference in maven
     * <code>${basedir}/target/tests/${condensed-classname}/${methodname}</code> path that uses an condensed directory
     * name based on the testclass and subdirectory based on the testmethod being run.
     * <p>
     * Note: the &#064;Rule {@link TestingDir} is a better choice in most cases.
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTargetTestingDir(testclass, testmethodname).toFile()</code>
     * 
     * @param testclass
     *            the class for the test case
     * @param testmethodname
     *            the test method name
     * @return the File path to the testname specific testing directory underneath the
     *         <code>${basedir}/target/tests/</code> sub directory
     * @see FS
     * @see TestingDir
     */
    public static File getTargetTestingDir(final Class<?> testclass, final String testmethodname)
    {
        return getTargetTestingPath(testclass,testmethodname).toFile();
    }
    
    /**
     * Obtain a testing directory reference in maven
     * <code>${basedir}/target/tests/${condensed-classname}/${methodname}</code> path that uses an condensed directory
     * name based on the testclass and subdirectory based on the testmethod being run.
     * <p>
     * Note: the &#064;Rule {@link TestingDir} is a better choice in most cases.
     * 
     * @param testclass
     *            the class for the test case
     * @param testmethodname
     *            the test method name
     * @return the File path to the testname specific testing directory underneath the
     *         <code>${basedir}/target/tests/</code> sub directory
     * @see FS
     * @see TestingDir
     */
    public static Path getTargetTestingPath(final Class<?> testclass, final String testmethodname)
    {
        String classname = testclass.getName();
        String methodname = testmethodname;

        classname = StringMangler.condensePackageString(classname);

        if (OS.IS_WINDOWS)
        {
            /* Condense the directory names to make them more friendly for the 
             * 255 character pathname limitations that exist on windows.
             */
            methodname = StringMangler.maxStringLength(30,methodname);
        }

        Path testdir = getTargetTestingPath().resolve(methodname);
        FS.ensureDirExists(testdir);
        return testdir;
    }

    private static class TestID
    {
        public String classname;
        public String methodname;
    }

    /**
     * Using Junit 3.x test naming standards, attempt to discover a suitable test directory name
     * based on the execution stack when this method is called.
     * 
     * @return the testing directory name (only the name, not the full path)
     * @deprecated Upgrade to Junit 4.x and use the {@link TestingDir} &#064;Rule instead
     */
    @Deprecated
    public static String getTestIDAsPath()
    {
        TestID id = getTestID();

        id.classname = StringMangler.condensePackageString(id.classname);

        if (OS.IS_WINDOWS)
        {
            /* Condense the directory names to make them more friendly for the 
             * 255 character pathname limitations that exist on windows.
             */
            id.methodname = StringMangler.maxStringLength(30,id.methodname);
        }

        return id.classname + File.separatorChar + id.methodname;
    }

    /**
     * Get a {@link File} reference to a required file in the project module path, based on relative
     * path references from maven ${basedir}.
     * <p>
     * Note: will throw assertion error if path does point to an existing file
     * <p>
     * Convenience method for <code>MavenTestingUtils.getProjectFilePath(path).toFile()</code>
     * 
     * @param path
     *            the relative path to reference
     * @return the file reference (must exist)
     */
    public static File getProjectFile(String path)
    {
        return getProjectFilePath(path).toFile();
    }

    /**
     * Get a {@link Path} reference to a required file in the project module path, based on relative
     * path references from maven ${basedir}.
     * <p>
     * Note: will throw assertion error if path does point to an existing file
     * 
     * @param path
     *            the relative path to reference
     * @return the file reference (must exist)
     */
    public static Path getProjectFilePath(String path)
    {
        Path file = getBasePath().resolve(path);
        PathAssert.assertFileExists("Project File",file);
        return file;
    }

    /**
     * Get a directory reference to a required directory in the project module path, based on relative
     * path references from maven ${basedir}.
     * <p>
     * Note: will throw assertion error if path does point to an existing directory
     * <p>
     * Convenience method for <code>MavenTestingUtils.getProjectDirPath(path).toFile()</code>
     * 
     * @param path
     *            the relative path to reference
     * @return the directory reference (must exist)
     */
    public static File getProjectDir(String path)
    {
        return getProjectDirPath(path).toFile();
    }

    /**
     * Get a {@link Path} reference to a required directory in the project module path, based on relative
     * path references from maven ${basedir}.
     * <p>
     * Note: will throw assertion error if path does point to an existing directory
     * 
     * @param path
     *            the relative path to reference
     * @return the directory reference (must exist)
     */
    public static Path getProjectDirPath(String path)
    {
        Path dir = getBasePath().resolve(path);
        PathAssert.assertDirExists("Project Dir",dir);
        return dir;
    }

    /**
     * Using junit 3.x naming standards for unit tests and test method names, attempt to discover the unit test name
     * from the execution stack.
     * 
     * @return the unit test id found via execution stack and junit 3.8 naming conventions.
     * @see #getTestIDAsPath()
     */
    private static TestID getTestID()
    {
        StackTraceElement stacked[] = new Throwable().getStackTrace();

        for (StackTraceElement stack : stacked)
        {
            if (stack.getClassName().endsWith("Test"))
            {
                if (stack.getMethodName().startsWith("test"))
                {
                    TestID testid = new TestID();
                    testid.classname = stack.getClassName();
                    testid.methodname = stack.getMethodName();
                    return testid;
                }
            }
        }
        // If we have reached this point, we have failed to find the test id
        String LN = System.getProperty("line.separator");
        StringBuilder err = new StringBuilder();
        err.append("Unable to find a TestID from a testcase that ");
        err.append("doesn't follow the standard naming rules.");
        err.append(LN);
        err.append("Test class name must end in \"*Test\".");
        err.append(LN);
        err.append("Test method name must start in \"test*\".");
        err.append(LN);
        err.append("Call to ").append(MavenTestingUtils.class.getSimpleName());
        err.append(".getTestID(), must occur from within stack frame of ");
        err.append("test method, not @Before, @After, @BeforeClass, ");
        err.append("@AfterClass, or Constructors of test case.");
        Assert.fail(err.toString());
        return null;
    }

    /**
     * Get the {@link File} reference to the maven <code>${basedir}/src/test/resources</code> directory
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTestResourcesPath().toFile()</code>
     * 
     * @return the directory {@link File} to the maven <code>${basedir}/src/test/resources</code> directory
     */
    public static File getTestResourcesDir()
    {
        return getTestResourcesPath().toFile();
    }

    /**
     * Get the {@link Path} reference to the maven <code>${basedir}/src/test/resources</code> directory
     * 
     * @return the directory {@link Path} to the maven <code>${basedir}/src/test/resources</code> directory
     */
    public static Path getTestResourcesPath()
    {
        if (testResourcesPath == null)
        {
            testResourcesPath = getBasePath().resolve("src/test/resources");
            PathAssert.assertDirExists("Test Resources Dir",testResourcesPath);
        }
        return testResourcesPath;
    }

    /**
     * Get a dir from the maven <code>${basedir}/src/test/resource</code> directory.
     * <p>
     * Note: will throw assertion error if path does point to an existing directory
     * <p>
     * Convenience method for <code>MavenTestingUtils.getTestResourcesPathDir(name).toFile()</code>
     * 
     * @param name
     *            the name of the path to get (it must exist as a dir)
     * @return the dir in the maven <code>${basedir}/src/test/resource</code> path
     */
    public static File getTestResourceDir(String name)
    {
        return getTestResourcePathDir(name).toFile();
    }

    /**
     * Get a dir from the maven <code>${basedir}/src/test/resource</code> directory.
     * <p>
     * Note: will throw assertion error if path does point to an existing directory
     * 
     * @param name
     *            the name of the path to get (it must exist as a dir)
     * @return the dir in the maven <code>${basedir}/src/test/resource</code> path
     */
    public static Path getTestResourcePathDir(String name)
    {
        Path dir = getTestResourcesPath().resolve(name);
        PathAssert.assertDirExists("Test Resource Dir",dir);
        return dir;
    }

    /**
     * Get a file from the maven <code>${basedir}/src/test/resource</code> directory.
     * <p>
     * Note: will throw assertion error if path does point to an existing file
     * 
     * @param name
     *            the name of the path to get (it must exist as a file)
     * @return the file in maven <code>${basedir}/src/test/resource</code>
     */
    public static File getTestResourceFile(String name)
    {
        File file = new File(getTestResourcesDir(),OS.separators(name));
        PathAssert.assertFileExists("Test Resource File",file);
        return file;
    }

    /**
     * Get a file from the maven <code>${basedir}/src/test/resource</code> directory.
     * <p>
     * Note: will throw assertion error if path does point to an existing file
     * 
     * @param name
     *            the name of the path to get (it must exist as a file)
     * @return the file in maven <code>${basedir}/src/test/resource</code>
     */
    public static Path getTestResourcePathFile(String name)
    {
        Path file = getTestResourcesPath().resolve(name);
        PathAssert.assertFileExists("Test Resource File",file);
        return file;
    }

    /**
     * Get a path resource (File or Dir) from the maven <code>${basedir}/src/test/resource</code> directory.
     * 
     * @param name
     *            the name of the path to get (it must exist)
     * @return the path in maven <code>${basedir}/src/test/resource</code>
     */
    public static Path getTestResourcePath(String name)
    {
        Path path = getTestResourcesPath().resolve(name);
        PathAssert.assertPathExists("Test Resource Path",path);
        return path;
    }
}

Back to the top