ihp-ide-1.5.0: Test/IDE/CodeGeneration/ViewGenerator.hs
{-|
Module: Test.IDE.CodeGeneration.ViewGenerator
Copyright: (c) digitally induced GmbH, 2020
-}
module Test.IDE.CodeGeneration.ViewGenerator where
import Test.Hspec
import IHP.Prelude
import qualified IHP.IDE.CodeGen.ViewGenerator as ViewGenerator
import IHP.IDE.CodeGen.Types
import IHP.Postgres.Types
tests = do
describe "View Generator Tests:" do
let schema = [
StatementCreateTable (table "pages") {
columns = [
(col "id" PUUID) { defaultValue = Just (CallExpression "uuid_generate_v4" []), notNull = True }
]
, primaryKeyConstraint = PrimaryKeyConstraint ["id"]
}
]
it "should build a view with name \"EditView\"" do
let rawViewName = "EditView"
let viewName = tableNameToViewName rawViewName
let rawControllerName = "Pages"
let controllerName = tableNameToControllerName rawControllerName
let modelName = tableNameToModelName rawControllerName
let applicationName = "Web"
let paginationEnabled = False
let config = ViewGenerator.ViewConfig { .. }
let builtPlan = ViewGenerator.buildPlan' schema config
builtPlan `shouldBe`
[ EnsureDirectory {directory = "Web/View/Pages"},CreateFile {filePath = "Web/View/Pages/Edit.hs", fileContent = "module Web.View.Pages.Edit where\nimport Web.View.Prelude\n\ndata EditView = EditView { page :: Page }\n\ninstance View EditView where\n html EditView { .. } = [hsx|\n {breadcrumb}\n <h1>Edit Page</h1>\n {renderForm page}\n |]\n where\n breadcrumb = renderBreadcrumb\n [ breadcrumbLink \"Pages\" PagesAction\n , breadcrumbText \"Edit Page\"\n ]\n\nrenderForm :: Page -> Html\nrenderForm page = formFor page [hsx|\n \n {submitButton}\n\n|]"},AddImport {filePath = "Web/Controller/Pages.hs", fileContent = "import Web.View.Pages.Edit"}
]
it "should build a view with name \"edit_view\"" do
let rawViewName = "edit_view"
let viewName = tableNameToViewName rawViewName
let rawControllerName = "Pages"
let controllerName = tableNameToControllerName rawControllerName
let modelName = tableNameToModelName rawControllerName
let applicationName = "Web"
let paginationEnabled = False
let config = ViewGenerator.ViewConfig { .. }
let builtPlan = ViewGenerator.buildPlan' schema config
builtPlan `shouldBe`
[ EnsureDirectory {directory = "Web/View/Pages"},CreateFile {filePath = "Web/View/Pages/Edit.hs", fileContent = "module Web.View.Pages.Edit where\nimport Web.View.Prelude\n\ndata EditView = EditView { page :: Page }\n\ninstance View EditView where\n html EditView { .. } = [hsx|\n {breadcrumb}\n <h1>Edit Page</h1>\n {renderForm page}\n |]\n where\n breadcrumb = renderBreadcrumb\n [ breadcrumbLink \"Pages\" PagesAction\n , breadcrumbText \"Edit Page\"\n ]\n\nrenderForm :: Page -> Html\nrenderForm page = formFor page [hsx|\n \n {submitButton}\n\n|]"},AddImport {filePath = "Web/Controller/Pages.hs", fileContent = "import Web.View.Pages.Edit"}
]
it "should build a view with name \"editView\"" do
let rawViewName = "editView"
let viewName = tableNameToViewName rawViewName
let rawControllerName = "Pages"
let controllerName = tableNameToControllerName rawControllerName
let modelName = tableNameToModelName rawControllerName
let applicationName = "Web"
let paginationEnabled = False
let config = ViewGenerator.ViewConfig { .. }
let builtPlan = ViewGenerator.buildPlan' schema config
builtPlan `shouldBe`
[ EnsureDirectory {directory = "Web/View/Pages"},CreateFile {filePath = "Web/View/Pages/Edit.hs", fileContent = "module Web.View.Pages.Edit where\nimport Web.View.Prelude\n\ndata EditView = EditView { page :: Page }\n\ninstance View EditView where\n html EditView { .. } = [hsx|\n {breadcrumb}\n <h1>Edit Page</h1>\n {renderForm page}\n |]\n where\n breadcrumb = renderBreadcrumb\n [ breadcrumbLink \"Pages\" PagesAction\n , breadcrumbText \"Edit Page\"\n ]\n\nrenderForm :: Page -> Html\nrenderForm page = formFor page [hsx|\n \n {submitButton}\n\n|]"},AddImport {filePath = "Web/Controller/Pages.hs", fileContent = "import Web.View.Pages.Edit"}
]
it "should build a view with name \"Edit\"" do
let rawViewName = "Edit"
let viewName = tableNameToViewName rawViewName
let rawControllerName = "Pages"
let controllerName = tableNameToControllerName rawControllerName
let modelName = tableNameToModelName rawControllerName
let applicationName = "Web"
let paginationEnabled = False
let config = ViewGenerator.ViewConfig { .. }
let builtPlan = ViewGenerator.buildPlan' schema config
builtPlan `shouldBe`
[ EnsureDirectory {directory = "Web/View/Pages"},CreateFile {filePath = "Web/View/Pages/Edit.hs", fileContent = "module Web.View.Pages.Edit where\nimport Web.View.Prelude\n\ndata EditView = EditView { page :: Page }\n\ninstance View EditView where\n html EditView { .. } = [hsx|\n {breadcrumb}\n <h1>Edit Page</h1>\n {renderForm page}\n |]\n where\n breadcrumb = renderBreadcrumb\n [ breadcrumbLink \"Pages\" PagesAction\n , breadcrumbText \"Edit Page\"\n ]\n\nrenderForm :: Page -> Html\nrenderForm page = formFor page [hsx|\n \n {submitButton}\n\n|]"},AddImport {filePath = "Web/Controller/Pages.hs", fileContent = "import Web.View.Pages.Edit"}
]
it "should build a view with name \"Test\"" do
let rawViewName = "Test"
let viewName = tableNameToViewName rawViewName
let rawControllerName = "Pages"
let controllerName = tableNameToControllerName rawControllerName
let modelName = tableNameToModelName rawControllerName
let applicationName = "Web"
let paginationEnabled = False
let config = ViewGenerator.ViewConfig { .. }
let builtPlan = ViewGenerator.buildPlan' schema config
builtPlan `shouldBe`
[ EnsureDirectory {directory = "Web/View/Pages"},CreateFile {filePath = "Web/View/Pages/Test.hs", fileContent = "module Web.View.Pages.Test where\nimport Web.View.Prelude\ndata TestView = TestView\n\ninstance View TestView where\n html TestView { .. } = [hsx|\n {breadcrumb}\n <h1>TestView</h1>\n |]\n where\n breadcrumb = renderBreadcrumb\n [ breadcrumbLink \"Tests\" PagesAction\n , breadcrumbText \"TestView\"\n ]"},AddImport {filePath = "Web/Controller/Pages.hs", fileContent = "import Web.View.Pages.Test"}
]
it "should generate type-aware form fields for a rich schema" do
let richSchema = [
StatementCreateTable (table "projects") {
columns = [
(col "id" PUUID) { defaultValue = Just (CallExpression "uuid_generate_v4" []), notNull = True }
, (col "title" PText) { notNull = True }
, (col "is_active" PBoolean) { notNull = True }
, (col "budget" PInt) { notNull = False }
, (col "started_on" PDate) { notNull = False }
, (col "user_id" PUUID) { notNull = True }
]
, primaryKeyConstraint = PrimaryKeyConstraint ["id"]
, constraints = [
ForeignKeyConstraint { name = Nothing, columnName = "user_id", referenceTable = "users", referenceColumn = Nothing, onDelete = Nothing }
]
}
]
let viewName = "NewView"
let rawControllerName = "projects"
let controllerName = tableNameToControllerName rawControllerName
let modelName = tableNameToModelName rawControllerName
let applicationName = "Web"
let paginationEnabled = False
let config = ViewGenerator.ViewConfig { .. }
let builtPlan = ViewGenerator.buildPlan' richSchema config
let (EnsureDirectory {}):((CreateFile { fileContent = newViewContent }):_) = builtPlan
-- Type-aware form fields
(cs newViewContent :: String) `shouldContain` "{(textField #title)}"
(cs newViewContent :: String) `shouldContain` "{(checkboxField #isActive)}"
(cs newViewContent :: String) `shouldContain` "{(numberField #budget)}"
(cs newViewContent :: String) `shouldContain` "{(dateField #startedOn)}"
-- FK field should have a TODO comment
(cs newViewContent :: String) `shouldContain` "{- userId needs to be a selectField -}"
it "should generate dl-based show view for a rich schema" do
let richSchema = [
StatementCreateTable (table "projects") {
columns = [
(col "id" PUUID) { defaultValue = Just (CallExpression "uuid_generate_v4" []), notNull = True }
, (col "title" PText) { notNull = True }
, (col "is_active" PBoolean) { notNull = True }
]
, primaryKeyConstraint = PrimaryKeyConstraint ["id"]
}
]
let viewName = "ShowView"
let rawControllerName = "projects"
let controllerName = tableNameToControllerName rawControllerName
let modelName = tableNameToModelName rawControllerName
let applicationName = "Web"
let paginationEnabled = False
let config = ViewGenerator.ViewConfig { .. }
let builtPlan = ViewGenerator.buildPlan' richSchema config
let (EnsureDirectory {}):((CreateFile { fileContent = showViewContent }):_) = builtPlan
(cs showViewContent :: String) `shouldContain` "<dl>"
(cs showViewContent :: String) `shouldContain` "<dt>Title</dt><dd>{project.title}</dd>"
(cs showViewContent :: String) `shouldContain` "<dt>Is Active</dt><dd>{project.isActive}</dd>"
it "should generate column-based index view for a rich schema" do
let richSchema = [
StatementCreateTable (table "projects") {
columns = [
(col "id" PUUID) { defaultValue = Just (CallExpression "uuid_generate_v4" []), notNull = True }
, (col "title" PText) { notNull = True }
, (col "is_active" PBoolean) { notNull = True }
]
, primaryKeyConstraint = PrimaryKeyConstraint ["id"]
}
]
let viewName = "IndexView"
let rawControllerName = "projects"
let controllerName = tableNameToControllerName rawControllerName
let modelName = tableNameToModelName rawControllerName
let applicationName = "Web"
let paginationEnabled = False
let config = ViewGenerator.ViewConfig { .. }
let builtPlan = ViewGenerator.buildPlan' richSchema config
let (EnsureDirectory {}):((CreateFile { fileContent = indexViewContent }):_) = builtPlan
(cs indexViewContent :: String) `shouldContain` "<th>Title</th>"
(cs indexViewContent :: String) `shouldContain` "<th>Is Active</th>"
(cs indexViewContent :: String) `shouldContain` "<td>{project.title}</td>"
(cs indexViewContent :: String) `shouldContain` "<td>{project.isActive}</td>"