Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
LoadFromRelativeFile |
|
| 1.7777777777777777;1.778 | ||||
LoadFromRelativeFile$StoryFilePath |
|
| 1.7777777777777777;1.778 |
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 | import org.apache.commons.io.IOUtils; | |
10 | ||
11 | /** | |
12 | * Defaults to working from classes compiled to Maven-style | |
13 | * 'target/test-classes', with story source in 'src/test/java' | |
14 | * | |
15 | * LoadFromRelativeFile loader = new | |
16 | * LoadFromRelativeFile(codeLocationFromClass(YourStory.class)); | |
17 | * | |
18 | * To work with something other than the default story locations, you will have | |
19 | * to specify them in 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 also {@link StoryLocation#codeLocationFromClass} | |
32 | * | |
33 | */ | |
34 | public class LoadFromRelativeFile implements StoryLoader { | |
35 | ||
36 | private final StoryFilePath[] traversals; | |
37 | private final URL location; | |
38 | ||
39 | public LoadFromRelativeFile(URL location) { | |
40 | 3 | this(location, mavenModuleStoryFilePath("src/test/java")); |
41 | 3 | } |
42 | ||
43 | 5 | public LoadFromRelativeFile(URL location, StoryFilePath... traversals) { |
44 | 5 | this.traversals = traversals; |
45 | 5 | this.location = location; |
46 | 5 | } |
47 | ||
48 | public String loadStoryAsText(String storyPath) { | |
49 | 4 | List<String> traversalPaths = new ArrayList<String>(); |
50 | 4 | String locationPath = new File(location.getFile()).getAbsolutePath(); |
51 | 5 | for (StoryFilePath traversal : traversals) { |
52 | 3 | String filePath = locationPath.replace(traversal.toRemove, traversal.relativePath) + "/" + storyPath; |
53 | 3 | File file = new File(filePath); |
54 | 3 | if (file.exists()) { |
55 | 2 | return loadContent(filePath); |
56 | } else { | |
57 | 1 | traversalPaths.add(filePath); |
58 | } | |
59 | } | |
60 | 2 | throw new StoryResourceNotFound(storyPath, traversalPaths); |
61 | ||
62 | } | |
63 | ||
64 | protected String loadContent(String path) { | |
65 | try { | |
66 | 3 | return IOUtils.toString(new FileInputStream(new File(path))); |
67 | 1 | } catch (Exception e) { |
68 | 1 | throw new InvalidStoryResource(path, e); |
69 | } | |
70 | } | |
71 | ||
72 | /** | |
73 | * For use the the varargs constructor of {@link LoadFromRelativeFile}, to | |
74 | * allow a range of possibilities for locating Story file paths | |
75 | */ | |
76 | 6 | public static class StoryFilePath { |
77 | private final String toRemove; | |
78 | private final String relativePath; | |
79 | ||
80 | 7 | public StoryFilePath(String toRemove, String relativePath) { |
81 | 7 | this.toRemove = toRemove.replace('\\', '/'); |
82 | 7 | this.relativePath = relativePath.replace('\\', '/'); |
83 | 7 | } |
84 | } | |
85 | ||
86 | /** | |
87 | * Maven by default, has its PRODUCTION classes in target/classes. This | |
88 | * story file path is relative to that. | |
89 | * | |
90 | * @param relativePath | |
91 | * the path to the stories' base-dir inside the module | |
92 | * @return the resulting StoryFilePath | |
93 | */ | |
94 | public static StoryFilePath mavenModuleStoryFilePath(String relativePath) { | |
95 | 4 | return new StoryFilePath("target/classes", relativePath); |
96 | } | |
97 | ||
98 | /** | |
99 | * Maven by default, has its TEST classes in target/test-classes. This story | |
100 | * file path is relative to that. | |
101 | * | |
102 | * @param relativePath | |
103 | * the path to the stories' base-dir inside the module | |
104 | * @return the resulting StoryFilePath | |
105 | */ | |
106 | public static StoryFilePath mavenModuleTestStoryFilePath(String relativePath) { | |
107 | 1 | return new StoryFilePath("target/test-classes", relativePath); |
108 | } | |
109 | ||
110 | /** | |
111 | * Intellij by default, has its PRODUCTION classes in classes/production. | |
112 | * This story file path is relative to that. | |
113 | * | |
114 | * @param relativePath | |
115 | * the path to the stories' base-dir inside the module | |
116 | * @return the resulting StoryFilePath | |
117 | */ | |
118 | public static StoryFilePath intellijProjectStoryFilePath(String relativePath) { | |
119 | 1 | return new StoryFilePath("classes/production", relativePath); |
120 | } | |
121 | ||
122 | /** | |
123 | * Intellij by default, has its TEST classes in classes/test. This story | |
124 | * file path is relative to that. | |
125 | * | |
126 | * @param relativePath | |
127 | * the path to the stories' base-dir inside the module | |
128 | * @return the resulting StoryFilePath | |
129 | */ | |
130 | public static StoryFilePath intellijProjectTestStoryFilePath(String relativePath) { | |
131 | 1 | return new StoryFilePath("classes/test", relativePath); |
132 | } | |
133 | ||
134 | } |