Skip to content

Commit ed2077a

Browse files
closes #11 - generate utPLSQL unit tests via oddgen
all into single file (worksheet) or each package specification and package body in a dedicated file, including a install script
1 parent aa90909 commit ed2077a

File tree

1 file changed

+262
-0
lines changed

1 file changed

+262
-0
lines changed
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/*
2+
* Copyright 2018 Philipp Salvisberg <[email protected]>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.utplsql.sqldev.oddgen
17+
18+
import java.io.File
19+
import java.sql.Connection
20+
import java.util.ArrayList
21+
import java.util.HashMap
22+
import java.util.LinkedHashMap
23+
import java.util.List
24+
import oracle.ide.config.Preferences
25+
import org.oddgen.sqldev.generators.OddgenGenerator2
26+
import org.oddgen.sqldev.generators.model.Node
27+
import org.oddgen.sqldev.generators.model.NodeTools
28+
import org.oddgen.sqldev.plugin.templates.TemplateTools
29+
import org.utplsql.sqldev.dal.UtplsqlDao
30+
import org.utplsql.sqldev.model.preference.PreferenceModel
31+
import org.utplsql.sqldev.resources.UtplsqlResources
32+
import org.utplsql.sqldev.oddgen.model.GenContext
33+
34+
class TestGenerator implements OddgenGenerator2 {
35+
36+
public static val YES = "Yes"
37+
public static val NO = "No"
38+
39+
public static var GENERATE_FILES = "Generate files?"
40+
public static var OUTPUT_DIRECTORY = "Output directory"
41+
public static var TEST_PACKAGE_PREFIX = UtplsqlResources.getString("PREF_TEST_PACKAGE_PREFIX_LABEL")
42+
public static var TEST_PACKAGE_SUFFIX = UtplsqlResources.getString("PREF_TEST_PACKAGE_SUFFIX_LABEL")
43+
public static var TEST_UNIT_PREFIX = UtplsqlResources.getString("PREF_TEST_UNIT_PREFIX_LABEL")
44+
public static var TEST_UNIT_SUFFIX = UtplsqlResources.getString("PREF_TEST_UNIT_SUFFIX_LABEL")
45+
public static var NUMBER_OF_TESTS_PER_UNIT = UtplsqlResources.getString("PREF_NUMBER_OF_TESTS_PER_UNIT_LABEL")
46+
public static var GENERATE_COMMENTS = "Generate comments?"
47+
public static var DISABLE_TESTS = "Disable tests?"
48+
public static var SUITE_PATH = "Suite Path"
49+
public static var INDENT_SPACES = "Indent Spaces"
50+
51+
val extension NodeTools nodeTools = new NodeTools
52+
val extension TemplateTools templateTools = new TemplateTools
53+
val consoleOutput = new ArrayList<String>();
54+
55+
private def toContext(Node node) {
56+
val context = new GenContext()
57+
context.objectType = node.toObjectType
58+
context.objectName = node.toObjectName
59+
context.generateFiles = node.params.get(GENERATE_FILES) == YES
60+
context.outputDirectory = node.params.get(OUTPUT_DIRECTORY)
61+
context.testPackagePrefix = node.params.get(TEST_PACKAGE_PREFIX).toLowerCase
62+
context.testPackageSuffix = node.params.get(TEST_PACKAGE_SUFFIX).toLowerCase
63+
context.testUnitPrefix = node.params.get(TEST_UNIT_PREFIX).toLowerCase
64+
context.testUnitSuffix = node.params.get(TEST_UNIT_SUFFIX).toLowerCase
65+
context.numberOfTestsPerUnit = Integer.valueOf(node.params.get(NUMBER_OF_TESTS_PER_UNIT))
66+
context.generateComments = node.params.get(GENERATE_COMMENTS) == YES
67+
context.disableTests = node.params.get(DISABLE_TESTS) == YES
68+
context.suitePath = node.params.get(SUITE_PATH).toLowerCase
69+
context.indentSpaces = Integer.valueOf(node.params.get(INDENT_SPACES))
70+
return context
71+
}
72+
73+
private def void resetConsoleOutput() {
74+
consoleOutput.clear
75+
}
76+
77+
private def void saveConsoleOutput(String s) {
78+
consoleOutput.add(s)
79+
}
80+
81+
private def String deleteFile(File file) {
82+
var String ret
83+
try {
84+
if (file.delete) {
85+
ret = '''«file.absoluteFile» deleted.'''
86+
} else {
87+
ret = '''Cannot delete file «file.absoluteFile».'''
88+
}
89+
} catch (Exception e) {
90+
ret = '''Cannot delete file «file.absoluteFile». Got the following error message: «e.message».'''
91+
}
92+
return ret
93+
}
94+
95+
private def deleteFiles(String directory) '''
96+
«val dir = new File(directory
97+
«FOR file: dir.listFiles»
98+
«IF !file.directory»
99+
«IF file.name.endsWith(".pks") || file.name.endsWith(".pkb")»
100+
«file.deleteFile»
101+
«ENDIF»
102+
«ENDIF»
103+
«ENDFOR»
104+
'''
105+
106+
override isSupported(Connection conn) {
107+
var ret = false
108+
if (conn !== null) {
109+
if (conn.metaData.databaseProductName.startsWith("Oracle")) {
110+
if (conn.metaData.databaseMajorVersion == 11) {
111+
if (conn.metaData.databaseMinorVersion >= 2) {
112+
ret = true
113+
}
114+
} else if (conn.metaData.databaseMajorVersion > 11) {
115+
ret = true
116+
}
117+
}
118+
}
119+
return ret
120+
}
121+
122+
override getName(Connection conn) {
123+
return "Generate test"
124+
}
125+
126+
override getDescription(Connection conn) {
127+
return "Generates utPLSQL test packages for public units in packages, types, functions and procedures found in the current schema."
128+
}
129+
130+
override getFolders(Connection conn) {
131+
val preferences = PreferenceModel.getInstance(Preferences.preferences)
132+
val folders = new ArrayList<String>
133+
for (f : preferences.rootFolderInOddgenView.split(",").filter[!it.empty]) {
134+
folders.add(f.trim)
135+
}
136+
return folders
137+
}
138+
139+
override getHelp(Connection conn) {
140+
return "<p>not yet available</p>"
141+
}
142+
143+
override getNodes(Connection conn, String parentNodeId) {
144+
val preferences = PreferenceModel.getInstance(Preferences.preferences)
145+
val params = new LinkedHashMap<String, String>()
146+
params.put(GENERATE_FILES, if (preferences.generateFiles) {YES} else {NO})
147+
params.put(OUTPUT_DIRECTORY, preferences.outputDirectory)
148+
params.put(TEST_PACKAGE_PREFIX, preferences.testPackagePrefix)
149+
params.put(TEST_PACKAGE_SUFFIX, preferences.testPackageSuffix)
150+
params.put(TEST_UNIT_PREFIX, preferences.testUnitPrefix)
151+
params.put(TEST_UNIT_SUFFIX, preferences.testUnitSuffix)
152+
params.put(NUMBER_OF_TESTS_PER_UNIT, String.valueOf(preferences.numberOfTestsPerUnit))
153+
params.put(GENERATE_COMMENTS, if(preferences.generateComments) {YES} else {NO})
154+
params.put(DISABLE_TESTS, if (preferences.disableTests) {YES} else {NO})
155+
params.put(SUITE_PATH, preferences.suitePath)
156+
params.put(INDENT_SPACES, String.valueOf(preferences.indentSpaces))
157+
if (parentNodeId === null || parentNodeId.empty) {
158+
val packageNode = new Node
159+
packageNode.id = "PACKAGE"
160+
packageNode.params = params
161+
packageNode.leaf = false
162+
packageNode.generatable = true
163+
packageNode.multiselectable = true
164+
val typeNode = new Node
165+
typeNode.id = "TYPE"
166+
typeNode.params = params
167+
typeNode.leaf = false
168+
typeNode.generatable = true
169+
typeNode.multiselectable = true
170+
val functionNode = new Node
171+
functionNode.id = "FUNCTION"
172+
functionNode.params = params
173+
functionNode.leaf = false
174+
functionNode.generatable = true
175+
functionNode.multiselectable = true
176+
val procedureNode = new Node
177+
procedureNode.id = "PROCEDURE"
178+
procedureNode.params = params
179+
procedureNode.leaf = false
180+
procedureNode.generatable = true
181+
procedureNode.multiselectable = true
182+
return #[packageNode, typeNode, functionNode, procedureNode]
183+
} else {
184+
val UtplsqlDao dao = new UtplsqlDao(conn)
185+
val nodes = dao.testables(parentNodeId)
186+
for (node : nodes) {
187+
node.params = params
188+
}
189+
return nodes
190+
}
191+
}
192+
193+
override getLov(Connection conn, LinkedHashMap<String, String> params, List<Node> nodes) {
194+
val lov = new HashMap<String, List<String>>()
195+
lov.put(NUMBER_OF_TESTS_PER_UNIT, #["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"])
196+
lov.put(INDENT_SPACES, #["1", "2", "3", "4", "5", "6", "7", "8"])
197+
lov.put(GENERATE_COMMENTS, #[YES, NO])
198+
lov.put(DISABLE_TESTS, #[YES, NO])
199+
lov.put(GENERATE_FILES, #[YES, NO])
200+
return lov
201+
}
202+
203+
override getParamStates(Connection conn, LinkedHashMap<String, String> params, List<Node> nodes) {
204+
val paramStates = new HashMap<String, Boolean>
205+
paramStates.put(OUTPUT_DIRECTORY, params.get(GENERATE_FILES) == YES)
206+
return paramStates
207+
}
208+
209+
override generateProlog(Connection conn, List<Node> nodes) '''
210+
«val generateFiles = nodes.get(0).params.get(GENERATE_FILES) == YES»
211+
«val outputDirectory = nodes.get(0).params.get(OUTPUT_DIRECTORY
212+
«IF generateFiles»
213+
«resetConsoleOutput»
214+
«outputDirectory.mkdirs.saveConsoleOutput»
215+
«deleteFiles(outputDirectory).toString.saveConsoleOutput»
216+
--
217+
-- install generated utPLSQL test packages
218+
--
219+
«ENDIF»
220+
«FOR node : nodes»
221+
«val context = node.toContext»
222+
«context.conn = conn»
223+
«val testTemplate = new TestTemplate(context
224+
«IF generateFiles»
225+
«val packageName = '''«context.testPackagePrefix»«node.toObjectName»«context.testPackageSuffix»'''»
226+
«writeToFile('''«outputDirectory»«File.separator»«packageName».pks'''.toString,testTemplate.generateSpec).saveConsoleOutput»
227+
«writeToFile('''«outputDirectory»«File.separator»«packageName».pkb'''.toString,testTemplate.generateBody).saveConsoleOutput»
228+
@«outputDirectory»«File.separator»«packageName».pks
229+
@«outputDirectory»«File.separator»«packageName».pkb
230+
«ELSE»
231+
«testTemplate.generate»
232+
233+
«ENDIF»
234+
«ENDFOR»
235+
«IF generateFiles && consoleOutput.size > 0»
236+
237+
--
238+
-- console output produced during the generation of this script
239+
--
240+
/*
241+
242+
«FOR line : consoleOutput»
243+
«line»
244+
«ENDFOR»
245+
246+
*/
247+
«ENDIF»
248+
'''
249+
250+
override generateSeparator(Connection conn) {
251+
return ""
252+
}
253+
254+
override generateEpilog(Connection conn, List<Node> nodes) {
255+
return ""
256+
}
257+
258+
override generate(Connection conn, Node node) {
259+
return ""
260+
}
261+
262+
}

0 commit comments

Comments
 (0)