4 def get_file_text(path):
5 """ Returns file text by path"""
6 file_io = open(path, "r")
12 def get_file_output(encoding="utf-8", path=sys.argv[-1], arg_string=""):
14 Returns answer file output
15 :param encoding: to decode output in python3
16 :param path: path of file to execute
17 :return: list of strings
21 proc = subprocess.Popen([sys.executable, path], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
22 stderr=subprocess.STDOUT)
24 for arg in arg_string.split("\n"):
25 proc.stdin.write(bytearray(str(arg) + "\n", encoding))
28 return list(map(lambda x: str(x.decode(encoding)), proc.communicate()[0].splitlines()))
31 def test_file_importable():
32 """ Tests there is no obvious syntax errors"""
34 if not path.endswith(".py"):
37 parent = os.path.abspath(os.path.join(path, os.pardir))
38 python_files = [f for f in os.listdir(parent) if os.path.isfile(os.path.join(parent, f)) and f.endswith(".py")]
39 for python_file in python_files:
40 if python_file == "tests.py":
42 check_importable_path(os.path.join(parent, python_file))
44 check_importable_path(path)
47 def check_importable_path(path):
48 """ Checks that file is importable.
49 Reports failure otherwise.
51 saved_input = patch_input()
55 failed("The file contains syntax errors", test_file_importable.__name__)
58 revert_input(saved_input)
60 passed(test_file_importable.__name__)
67 if sys.version_info[0] == 3:
69 save_input = builtins.input
70 builtins.input = mock_fun
72 elif sys.version_info[0] == 2:
74 save_input = __builtin__.raw_input
75 __builtin__.raw_input = mock_fun
76 __builtin__.input = mock_fun
80 def revert_input(saved_input):
81 if sys.version_info[0] == 3:
83 builtins.input = saved_input
84 elif sys.version_info[0] == 2:
86 __builtins__.raw_input = saved_input
87 __builtin__.input = saved_input
90 def import_file(path):
91 """ Returns imported file """
92 if sys.version_info[0] == 2 or sys.version_info[1] < 3:
95 return imp.load_source("tmp", path)
96 elif sys.version_info[0] == 3:
97 import importlib.machinery
99 return importlib.machinery.SourceFileLoader("tmp", path).load_module("tmp")
102 def import_task_file():
103 """ Returns imported file.
104 Imports file from which check action was run
107 return import_file(path)
110 def test_is_not_empty():
112 Checks that file is not empty
115 file_text = get_file_text(path)
117 if len(file_text) > 0:
120 failed("The file is empty. Please, reload the task and try again.")
123 def test_is_initial_text(error_text="You should modify the file"):
125 Checks that file was modified
128 text = get_initial_text(path)
129 file_text = get_file_text(path)
131 if file_text.strip() == text.strip():
137 def get_initial_text(path):
139 Returns the initial task text
141 course_lib = sys.argv[-2]
144 # path format is "project_root/lessonX/taskY/file.py"
145 task_index = path.rfind(os.sep, 0, path.rfind(os.sep))
146 index = path.rfind(os.sep, 0, task_index)
147 relative_path = path[index + 1:]
148 initial_file_path = os.path.join(course_lib, relative_path)
149 return get_file_text(initial_file_path)
152 def test_text_equals(text, error_text):
154 Checks that answer equals text.
157 file_text = get_file_text(path)
159 if file_text.strip() == text:
165 def test_answer_placeholders_text_deleted(error_text="Don't just delete task text"):
167 Checks that all answer placeholders are not empty
169 windows = get_answer_placeholders()
171 for window in windows:
178 def set_congratulation_message(message):
179 """ Overrides default 'Congratulations!' message """
180 print("#educational_plugin CONGRATS_MESSAGE " + message)
183 def failed(message="Please, reload the task and try again.", name=None):
184 """ Reports failure """
186 name = sys._getframe().f_back.f_code.co_name
187 print("#educational_plugin " + name + " FAILED + " + message)
190 def passed(name=None):
191 """ Reports success """
193 name = sys._getframe().f_back.f_code.co_name
194 print("#educational_plugin " + name + " test OK")
197 def get_answer_placeholders():
199 Returns all answer placeholders text
201 prefix = "#educational_plugin_window = "
205 file_name_without_extension = os.path.splitext(path)[0]
206 windows_path = file_name_without_extension + "_windows"
208 f = open(windows_path, "r")
211 for line in f.readlines():
212 if line.startswith(prefix):
214 windows.append(window_text.strip())
217 window_text = line[len(prefix):]
222 windows.append(window_text.strip())
228 def check_samples(samples=()):
230 Check script output for all samples. Sample is a two element list, where the first is input and
231 the second is output.
233 for sample in samples:
235 output = get_file_output(arg_string=str(sample[0]))
236 if "\n".join(output) != sample[1]:
238 "Test from samples failed: \n \n"
243 "Your result:\n{}".format(str.strip(sample[0]), str.strip(sample[1]), "\n".join(output)))
245 set_congratulation_message("All test from samples passed. Now we are checking your solution on Stepic server.")
250 def run_common_tests(error_text="Please, reload file and try again"):
251 test_is_initial_text()
253 test_answer_placeholders_text_deleted()
254 test_file_importable()