hydra-0.15.0: src/main/haskell/Hydra/Java/Testing.hs
-- Note: this is an automatically generated file. Do not edit.
-- | Java test code generation codec for JUnit-based generation tests
module Hydra.Java.Testing where
import qualified Hydra.Constants as Constants
import qualified Hydra.Formatting as Formatting
import qualified Hydra.Lib.Eithers as Eithers
import qualified Hydra.Lib.Equality as Equality
import qualified Hydra.Lib.Lists as Lists
import qualified Hydra.Lib.Logic as Logic
import qualified Hydra.Lib.Maybes as Maybes
import qualified Hydra.Lib.Strings as Strings
import qualified Hydra.Packaging as Packaging
import qualified Hydra.Testing as Testing
import qualified Hydra.Util as Util
import Prelude hiding (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
import qualified Data.Scientific as Sci
-- | Build the complete Java test module content
buildJavaTestModule :: Packaging.Module -> Testing.TestGroup -> String -> String
buildJavaTestModule testModule testGroup testBody =
let ns_ = Packaging.moduleNamespace testModule
parts = Strings.splitOn "." (Packaging.unNamespace ns_)
packageName = Strings.intercalate "." (Maybes.fromMaybe [] (Lists.maybeInit parts))
className_ = Strings.cat2 (Formatting.capitalize (Maybes.fromMaybe "" (Lists.maybeLast parts))) "Test"
groupName_ = Testing.testGroupName testGroup
standardImports =
[
"import org.junit.jupiter.api.Test;",
"import static org.junit.jupiter.api.Assertions.*;",
"import java.util.*;",
"import hydra.util.*;"]
header =
Strings.cat [
Strings.cat2 "// " Constants.warningAutoGeneratedFile,
"\n",
(Strings.cat2 "// " groupName_),
"\n\n",
(Strings.cat [
"package ",
packageName,
";\n\n"]),
(Strings.intercalate "\n" standardImports),
"\n\n",
(Strings.cat [
"public class ",
className_,
" {\n\n"])]
in (Strings.cat [
header,
testBody,
"\n}\n"])
-- | Standard imports for Java JUnit test files
findJavaImports :: [String]
findJavaImports =
[
"import org.junit.jupiter.api.Test;",
"import static org.junit.jupiter.api.Assertions.*;",
"import java.util.*;"]
-- | Format a test name for Java (PascalCase method name with 'test' prefix)
formatJavaTestName :: String -> String
formatJavaTestName name =
let replaced =
Strings.intercalate " Neg" (Strings.splitOn "-" (Strings.intercalate "Dot" (Strings.splitOn "." (Strings.intercalate " Plus" (Strings.splitOn "+" (Strings.intercalate " Div" (Strings.splitOn "/" (Strings.intercalate " Mul" (Strings.splitOn "*" (Strings.intercalate " Num" (Strings.splitOn "#" name)))))))))))
sanitized = Formatting.nonAlnumToUnderscores replaced
pascal_ = Formatting.convertCase Util.CaseConventionLowerSnake Util.CaseConventionPascal sanitized
in (Strings.cat2 "test" pascal_)
-- | Generate a single JUnit test case from a test case with metadata
generateJavaTestCase :: [String] -> Testing.TestCaseWithMetadata -> Either t0 [String]
generateJavaTestCase groupPath tcm =
let name_ = Testing.testCaseWithMetadataName tcm
tcase = Testing.testCaseWithMetadataCase tcm
in case tcase of
Testing.TestCaseUniversal v0 ->
let actual_ = Testing.universalTestCaseActual v0
expected_ = Testing.universalTestCaseExpected v0
fullName = Logic.ifElse (Lists.null groupPath) name_ (Strings.intercalate "_" (Lists.concat2 groupPath [
name_]))
formattedName = formatJavaTestName fullName
in (Right [
" @Test",
(Strings.cat [
" public void ",
formattedName,
"() {"]),
" assertEquals(",
(Strings.cat [
" ",
expected_,
","]),
(Strings.cat [
" ",
actual_,
");"]),
" }"])
-- | Generate a Java test file for a test group
generateJavaTestFile :: Packaging.Module -> Testing.TestGroup -> t0 -> Either t1 (String, String)
generateJavaTestFile testModule testGroup _g = generateTestFileWithJavaCodec testModule testGroup
-- | Generate test hierarchy for Java with nested subgroups
generateJavaTestGroupHierarchy :: [String] -> Testing.TestGroup -> Either t0 String
generateJavaTestGroupHierarchy groupPath testGroup =
let cases_ = Testing.testGroupCases testGroup
subgroups = Testing.testGroupSubgroups testGroup
in (Eithers.bind (Eithers.map (\lines_ -> Strings.intercalate "\n\n" (Lists.concat lines_)) (Eithers.mapList (\tc -> generateJavaTestCase groupPath tc) cases_)) (\testCasesStr -> Eithers.map (\subgroupsStr -> Strings.cat [
testCasesStr,
(Logic.ifElse (Logic.or (Equality.equal testCasesStr "") (Equality.equal subgroupsStr "")) "" "\n\n"),
subgroupsStr]) (Eithers.map (\blocks -> Strings.intercalate "\n\n" blocks) (Eithers.mapList (\subgroup ->
let groupName = Testing.testGroupName subgroup
header = Strings.cat2 " // " groupName
in (Eithers.map (\content -> Strings.cat [
header,
"\n\n",
content]) (generateJavaTestGroupHierarchy (Lists.concat2 groupPath [
groupName]) subgroup))) subgroups))))
-- | Generate a complete test file for Java
generateTestFileWithJavaCodec :: Packaging.Module -> Testing.TestGroup -> Either t0 (String, String)
generateTestFileWithJavaCodec testModule testGroup =
Eithers.map (\testBody ->
let testModuleContent = buildJavaTestModule testModule testGroup testBody
ns_ = Packaging.moduleNamespace testModule
parts = Strings.splitOn "." (Packaging.unNamespace ns_)
dirParts = Lists.drop 1 (Maybes.fromMaybe [] (Lists.maybeInit parts))
className_ = Strings.cat2 (Formatting.capitalize (Maybes.fromMaybe "" (Lists.maybeLast parts))) "Test"
fileName = Strings.cat2 className_ ".java"
filePath =
Strings.cat [
Strings.intercalate "/" dirParts,
"/",
fileName]
in (filePath, testModuleContent)) (generateJavaTestGroupHierarchy [] testGroup)
-- | Convert namespace to Java class name
namespaceToJavaClassName :: Packaging.Namespace -> String
namespaceToJavaClassName ns_ =
Strings.intercalate "." (Lists.map Formatting.capitalize (Strings.splitOn "." (Packaging.unNamespace ns_)))