##### Coverage Report - org.jbehave.core.io.LoadFromRelativeFile

Classes in this File | Line Coverage | Branch Coverage | Complexity
LoadFromRelativeFile |
72% | 24/33
50% | 4/8
| 2.0;2
LoadFromRelativeFile$StoryFilePath |
100% | 5/5
N/A | N/A
| 2.0;2

1 |  |
     package org.jbehave.core.io;
2 |  |
3 |  |
     import java.io.File;
4 |  |
     import java.io.FileInputStream;
5 |  |
     import java.net.URL;
6 |  |
     import java.util.ArrayList;
7 |  |
     import java.util.List;
8 |  |
9 |  |
     /**
10 |  |
      * Loads story resources from relative file paths that are
11 |  |
      * traversal to a given location.
12 |  |
      *
13 |  |
      * StoryLoader loader = new
14 |  |
      * LoadFromRelativeFile(codeLocationFromClass(YourStory.class));
15 |  |
      *
16 |  |
      * By default, it uses traversal directory
17 |  |
      * 'target/test-classes' with source dir in 'src/test/java'.
18 |  |
      *
19 |  |
      * Other traversal locations can be specified via the varargs constructor:
20 |  |
      *
21 |  |
      * StoryLoader loader = new
22 |  |
      * LoadFromRelativeFile(codeLocationFromClass(YourStory.class),
23 |  |
      * mavenModuleTestStoryFilePath("src/test/java"),
24 |  |
      * intellijProjectTestStoryFilePath("src/test/java"));
25 |  |
      *
26 |  |
      * Convenience methods : {@link LoadFromRelativeFile#mavenModuleStoryFilePath},
27 |  |
      * {@link LoadFromRelativeFile#mavenModuleTestStoryFilePath}
28 |  |
      * {@link LoadFromRelativeFile#intellijProjectStoryFilePath}
29 |  |
      * {@link LoadFromRelativeFile#intellijProjectTestStoryFilePath}
30 |  |
      *
31 |  |
      * @see {@link CodeLocations#codeLocationFromClass(Class)}
32 |  |
      *
33 |  |
      */
34 | 20 |
     public class LoadFromRelativeFile implements ResourceLoader, StoryLoader {
35 |  |
36 |  |
         private final StoryFilePath[] traversals;
37 |  |
         private final URL location;
38 |  |
39 |  |
         public LoadFromRelativeFile(URL location) {
40 | 6 |
             this(location, mavenModuleStoryFilePath("src/test/java"));
41 | 6 |
         }
42 |  |
43 | 8 |
         public LoadFromRelativeFile(URL location, StoryFilePath... traversals) {
44 | 8 |
             this.traversals = traversals;
45 | 8 |
             this.location = location;
46 | 8 |
         }
47 |  |
48 |  |
         public String loadResourceAsText(String resourcePath) {
49 | 0 |
             List<String> traversalPaths = new ArrayList<String>();
50 | 0 |
             String locationPath = normalise(new File(CodeLocations.getPathFromURL(location)).getAbsolutePath());
51 | 0 |
             for (StoryFilePath traversal : traversals) {
52 | 0 |
                 String filePath = locationPath.replace(traversal.toRemove, traversal.relativePath) + "/" + resourcePath;
53 | 0 |
                 File file = new File(filePath);
54 | 0 |
                 if (file.exists()) {
55 | 0 |
                     return loadContent(filePath);
56 |  |
                 } else {
57 | 0 |
                     traversalPaths.add(filePath);
58 |  |
                 }
59 |  |
             }
60 | 0 |
             throw new StoryResourceNotFound(resourcePath, traversalPaths);
61 |  |
         }
62 |  |
63 |  |
         public String loadStoryAsText(String storyPath) {
64 | 7 |
             List<String> traversalPaths = new ArrayList<String>();
65 | 7 |
             String locationPath = new File(CodeLocations.getPathFromURL(location)).getAbsolutePath();
66 | 8 |
             for (StoryFilePath traversal : traversals) {
67 | 6 |
                 String filePath = locationPath.replace(traversal.toRemove, traversal.relativePath) + "/" + storyPath;
68 | 6 |
                 File file = new File(filePath);
69 | 6 |
                 if (file.exists()) {
70 | 5 |
                     return loadContent(filePath);
71 |  |
                 } else {
72 | 1 |
                     traversalPaths.add(filePath);
73 |  |
                 }
74 |  |
             }
75 | 2 |
             throw new StoryResourceNotFound(storyPath, traversalPaths);
76 |  |
         }
77 |  |
78 |  |
         protected String loadContent(String path) {
79 |  |
             try {
80 | 6 |
                 return IOUtils.toString(new FileInputStream(new File(path)), true);
81 | 1 |
             } catch (Exception e) {
82 | 1 |
                 throw new InvalidStoryResource(path, e);
83 |  |
             }
84 |  |
         }
85 |  |
86 |  |
         private static String normalise(String path) {
87 | 20 |
             return path.replace('\\', '/');
88 |  |
         }
89 |  |
90 |  |
         /**
91 |  |
          * For use the the varargs constructor of {@link LoadFromRelativeFile}, to
92 |  |
          * allow a range of possibilities for locating Story file paths
93 |  |
          */
94 | 12 |
         public static class StoryFilePath {
95 |  |
             private final String toRemove;
96 |  |
             private final String relativePath;
97 |  |
98 | 10 |
             public StoryFilePath(String toRemove, String relativePath) {
99 | 10 |
                 this.toRemove = normalise(toRemove);
100 | 10 |
                 this.relativePath = normalise(relativePath);
101 | 10 |
             }
102 |  |
103 |  |
         }
104 |  |
105 |  |
         /**
106 |  |
          * Maven by default, has its PRODUCTION classes in target/classes. This
107 |  |
          * story file path is relative to that.
108 |  |
          *
109 |  |
          * @param relativePath
110 |  |
          *            the path to the stories' base-dir inside the module
111 |  |
          * @return the resulting StoryFilePath
112 |  |
          */
113 |  |
         public static StoryFilePath mavenModuleStoryFilePath(String relativePath) {
114 | 7 |
             return new StoryFilePath("target/classes", relativePath);
115 |  |
         }
116 |  |
117 |  |
         /**
118 |  |
          * Maven by default, has its TEST classes in target/test-classes. This story
119 |  |
          * file path is relative to that.
120 |  |
          *
121 |  |
          * @param relativePath
122 |  |
          *            the path to the stories' base-dir inside the module
123 |  |
          * @return the resulting StoryFilePath
124 |  |
          */
125 |  |
         public static StoryFilePath mavenModuleTestStoryFilePath(String relativePath) {
126 | 1 |
             return new StoryFilePath("target/test-classes", relativePath);
127 |  |
         }
128 |  |
129 |  |
         /**
130 |  |
          * Intellij by default, has its PRODUCTION classes in classes/production.
131 |  |
          * This story file path is relative to that.
132 |  |
          *
133 |  |
          * @param relativePath
134 |  |
          *            the path to the stories' base-dir inside the module
135 |  |
          * @return the resulting StoryFilePath
136 |  |
          */
137 |  |
         public static StoryFilePath intellijProjectStoryFilePath(String relativePath) {
138 | 1 |
             return new StoryFilePath("classes/production", relativePath);
139 |  |
         }
140 |  |
141 |  |
         /**
142 |  |
          * Intellij by default, has its TEST classes in classes/test. This story
143 |  |
          * file path is relative to that.
144 |  |
          *
145 |  |
          * @param relativePath
146 |  |
          *            the path to the stories' base-dir inside the module
147 |  |
          * @return the resulting StoryFilePath
148 |  |
          */
149 |  |
         public static StoryFilePath intellijProjectTestStoryFilePath(String relativePath) {
150 | 1 |
             return new StoryFilePath("classes/test", relativePath);
151 |  |
         }
152 |  |
153 |  |
     }