123 lines
3.1 KiB
Python
123 lines
3.1 KiB
Python
import ast
|
|
import glob
|
|
import os
|
|
import shutil
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
import frappe
|
|
from frappe.utils.boilerplate import make_boilerplate
|
|
|
|
|
|
class TestBoilerPlate(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
title = "Test App"
|
|
description = "This app's description contains 'single quotes' and \"double quotes\"."
|
|
publisher = "Test Publisher"
|
|
email = "example@example.org"
|
|
icon = "" # empty -> default
|
|
color = ""
|
|
app_license = "MIT"
|
|
|
|
cls.user_input = [
|
|
title,
|
|
description,
|
|
publisher,
|
|
email,
|
|
icon,
|
|
color,
|
|
app_license,
|
|
]
|
|
|
|
cls.bench_path = frappe.utils.get_bench_path()
|
|
cls.apps_dir = os.path.join(cls.bench_path, "apps")
|
|
cls.app_names = ("test_app", "test_app_no_git")
|
|
cls.gitignore_file = ".gitignore"
|
|
cls.git_folder = ".git"
|
|
|
|
cls.root_paths = [
|
|
"requirements.txt",
|
|
"README.md",
|
|
"setup.py",
|
|
"license.txt",
|
|
cls.git_folder,
|
|
cls.gitignore_file
|
|
]
|
|
cls.paths_inside_app = [
|
|
"__init__.py",
|
|
"hooks.py",
|
|
"patches.txt",
|
|
"templates",
|
|
"www",
|
|
"config",
|
|
"modules.txt",
|
|
"public"
|
|
]
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
test_app_dirs = (os.path.join(cls.bench_path, "apps", app_name) for app_name in cls.app_names)
|
|
for test_app_dir in test_app_dirs:
|
|
if os.path.exists(test_app_dir):
|
|
shutil.rmtree(test_app_dir)
|
|
|
|
def test_create_app(self):
|
|
with patch("builtins.input", side_effect=self.user_input):
|
|
make_boilerplate(self.apps_dir, self.app_names[0])
|
|
|
|
new_app_dir = os.path.join(self.bench_path, self.apps_dir, self.app_names[0])
|
|
|
|
paths = self.get_paths(new_app_dir, self.app_names[0])
|
|
for path in paths:
|
|
self.assertTrue(
|
|
os.path.exists(path),
|
|
msg=f"{path} should exist in {self.app_names[0]} app"
|
|
)
|
|
|
|
self.check_parsable_python_files(new_app_dir)
|
|
|
|
def test_create_app_without_git_init(self):
|
|
with patch("builtins.input", side_effect=self.user_input):
|
|
make_boilerplate(self.apps_dir, self.app_names[1], no_git=True)
|
|
|
|
new_app_dir = os.path.join(self.apps_dir, self.app_names[1])
|
|
|
|
paths = self.get_paths(new_app_dir, self.app_names[1])
|
|
for path in paths:
|
|
if os.path.basename(path) in (self.git_folder, self.gitignore_file):
|
|
self.assertFalse(
|
|
os.path.exists(path),
|
|
msg=f"{path} shouldn't exist in {self.app_names[1]} app"
|
|
)
|
|
else:
|
|
self.assertTrue(
|
|
os.path.exists(path),
|
|
msg=f"{path} should exist in {self.app_names[1]} app"
|
|
)
|
|
|
|
self.check_parsable_python_files(new_app_dir)
|
|
|
|
def get_paths(self, app_dir, app_name):
|
|
all_paths = list()
|
|
|
|
for path in self.root_paths:
|
|
all_paths.append(os.path.join(app_dir, path))
|
|
|
|
all_paths.append(os.path.join(app_dir, app_name))
|
|
|
|
for path in self.paths_inside_app:
|
|
all_paths.append(os.path.join(app_dir, app_name, path))
|
|
|
|
return all_paths
|
|
|
|
def check_parsable_python_files(self, app_dir):
|
|
# check if python files are parsable
|
|
python_files = glob.glob(app_dir + "**/*.py", recursive=True)
|
|
|
|
for python_file in python_files:
|
|
with open(python_file) as p:
|
|
try:
|
|
ast.parse(p.read())
|
|
except Exception as e:
|
|
self.fail(f"Can't parse python file in new app: {python_file}\n" + str(e))
|