diff --git a/test/test_parse_headers.py b/test/test_parse_headers.py new file mode 100644 index 0000000..9e41a75 --- /dev/null +++ b/test/test_parse_headers.py @@ -0,0 +1,83 @@ +import unittest +import makesite + + +class ParseHeadersTest(unittest.TestCase): + + def test_single_header(self): + """Test parsing a single header.""" + text = "\nContent here" + headers = list(makesite._parse_headers(text)) + self.assertEqual(len(headers), 1) + self.assertEqual(headers[0][0], "title") + self.assertEqual(headers[0][1], "My Post Title") + + def test_multiple_headers(self): + """Test parsing multiple headers.""" + text = """ + + +Content starts here""" + headers = list(makesite._parse_headers(text)) + self.assertEqual(len(headers), 3) + self.assertEqual(headers[0], ("title", "My Post", headers[0][2])) + self.assertEqual(headers[1], ("category", "Tech Python", headers[1][2])) + self.assertEqual(headers[2], ("tag", "blog tutorial", headers[2][2])) + + def test_headers_with_extra_whitespace(self): + """Test parsing headers with extra whitespace.""" + text = "\n\nContent" + headers = list(makesite._parse_headers(text)) + self.assertEqual(len(headers), 2) + self.assertEqual(headers[0][0], "title") + self.assertEqual(headers[0][1], "My Post") + self.assertEqual(headers[1][0], "category") + self.assertEqual(headers[1][1], "Tech") + + def test_no_headers(self): + """Test parsing content with no headers.""" + text = "Just regular content\nNo headers here" + headers = list(makesite._parse_headers(text)) + self.assertEqual(len(headers), 0) + + def test_headers_stop_at_content(self): + """Test that parsing stops when content (non-header) is found.""" + text = """ + +This is content +""" + headers = list(makesite._parse_headers(text)) + self.assertEqual(len(headers), 2) + # Should only get title and category, not the tag after content + + def test_header_with_special_characters(self): + """Test parsing headers with special characters in values.""" + text = "\nContent" + headers = list(makesite._parse_headers(text)) + self.assertEqual(len(headers), 1) + self.assertEqual(headers[0][1], "C'est l'été! Les accents: àéêô") + + def test_header_with_colon_in_value(self): + """Test parsing headers where the value contains colons.""" + text = "\nContent" + headers = list(makesite._parse_headers(text)) + self.assertEqual(len(headers), 1) + self.assertEqual(headers[0][1], "Docker: Configuration et Sécurité") + + def test_empty_header_value(self): + """Test parsing headers with empty values.""" + text = "\n\nContent" + headers = list(makesite._parse_headers(text)) + self.assertEqual(len(headers), 2) + # Empty value results in a single space due to regex whitespace handling + self.assertEqual(headers[0][1].strip(), "") + self.assertEqual(headers[1][1], "Tech") + + def test_end_index_tracking(self): + """Test that end index correctly tracks position after headers.""" + text = "\n\nContent starts" + headers = list(makesite._parse_headers(text)) + # The last header's end index should point to where content starts + last_end = headers[-1][2] + self.assertTrue(last_end > 0) + self.assertTrue(text[last_end:].startswith("Content") or text[last_end:].startswith("\nContent")) diff --git a/test/test_render.py b/test/test_render.py new file mode 100644 index 0000000..7ca52d2 --- /dev/null +++ b/test/test_render.py @@ -0,0 +1,100 @@ +import unittest +import makesite + + +class RenderTest(unittest.TestCase): + + def test_simple_substitution(self): + """Test basic template variable substitution.""" + template = "Hello {{ name }}!" + result = makesite.render(template, name="World") + self.assertEqual(result, "Hello World!") + + def test_multiple_variables(self): + """Test substitution of multiple variables.""" + template = "{{ greeting }} {{ name }}, welcome to {{ site }}!" + result = makesite.render(template, greeting="Hello", name="Alice", site="Blog") + self.assertEqual(result, "Hello Alice, welcome to Blog!") + + def test_same_variable_multiple_times(self): + """Test that the same variable can be used multiple times.""" + template = "{{ word }} {{ word }} {{ word }}" + result = makesite.render(template, word="echo") + self.assertEqual(result, "echo echo echo") + + def test_missing_variable_unchanged(self): + """Test that missing variables are left unchanged.""" + template = "Hello {{ name }}, your score is {{ score }}" + result = makesite.render(template, name="Bob") + self.assertEqual(result, "Hello Bob, your score is {{ score }}") + + def test_no_variables(self): + """Test template with no variables.""" + template = "Just plain text without variables" + result = makesite.render(template) + self.assertEqual(result, "Just plain text without variables") + + def test_variable_with_whitespace(self): + """Test variables with different whitespace patterns.""" + template = "{{name}} {{ name }} {{ name }}" + result = makesite.render(template, name="Test") + self.assertEqual(result, "Test Test Test") + + def test_numeric_values(self): + """Test substitution with numeric values.""" + template = "Price: {{ price }}, Quantity: {{ qty }}" + result = makesite.render(template, price=19.99, qty=5) + self.assertEqual(result, "Price: 19.99, Quantity: 5") + + def test_empty_string_value(self): + """Test substitution with empty string.""" + template = "Start {{ middle }} End" + result = makesite.render(template, middle="") + self.assertEqual(result, "Start End") + + def test_special_characters_in_value(self): + """Test substitution with special characters.""" + template = "Content: {{ text }}" + result = makesite.render(template, text=" & 'quotes' \"double\"") + self.assertEqual(result, "Content: & 'quotes' \"double\"") + + def test_multiline_template(self): + """Test template spanning multiple lines.""" + template = """
{{ content }}
+""" + result = makesite.render(template, title="Post", content="Text", author="Alice") + expected = """Text
+""" + self.assertEqual(result, expected) + + def test_nested_braces_not_matched(self): + """Test that nested braces are not mistakenly matched.""" + template = "Code: {{ code }}" + result = makesite.render(template, code="{key: value}") + self.assertEqual(result, "Code: {key: value}") + + def test_variable_name_with_underscore(self): + """Test variable names with underscores.""" + template = "{{ first_name }} {{ last_name }}" + result = makesite.render(template, first_name="John", last_name="Doe") + self.assertEqual(result, "John Doe") + + def test_extra_parameters_ignored(self): + """Test that extra parameters are ignored.""" + template = "Hello {{ name }}" + result = makesite.render(template, name="Alice", unused="value", extra=123) + self.assertEqual(result, "Hello Alice") + + def test_boolean_values(self): + """Test substitution with boolean values.""" + template = "Active: {{ active }}, Disabled: {{ disabled }}" + result = makesite.render(template, active=True, disabled=False) + self.assertEqual(result, "Active: True, Disabled: False") + + def test_none_value(self): + """Test substitution with None value.""" + template = "Value: {{ value }}" + result = makesite.render(template, value=None) + self.assertEqual(result, "Value: None") diff --git a/test/test_strip_html_tags.py b/test/test_strip_html_tags.py new file mode 100644 index 0000000..d805c47 --- /dev/null +++ b/test/test_strip_html_tags.py @@ -0,0 +1,118 @@ +import unittest +import makesite + + +class StripHtmlTagsTest(unittest.TestCase): + + def test_simple_tag(self): + """Test removing a simple HTML tag.""" + text = "Hello World
" + result = makesite._strip_html_tags(text) + self.assertEqual(result, "Hello World") + + def test_multiple_tags(self): + """Test removing multiple HTML tags.""" + text = "Paragraph
Nested content here
'
+ result = makesite._strip_html_tags(text)
+ self.assertEqual(result, "")
+
+ def test_no_tags(self):
+ """Test text with no HTML tags."""
+ text = "Just plain text without any tags"
+ result = makesite._strip_html_tags(text)
+ self.assertEqual(result, "Just plain text without any tags")
+
+ def test_empty_string(self):
+ """Test with empty string."""
+ text = ""
+ result = makesite._strip_html_tags(text)
+ self.assertEqual(result, "")
+
+ def test_only_tags(self):
+ """Test string with only tags and no text."""
+ text = ""
+ result = makesite._strip_html_tags(text)
+ self.assertEqual(result, "")
+
+ def test_mixed_content(self):
+ """Test realistic HTML content."""
+ text = "This is a bold statement with a link.
" + result = makesite._strip_html_tags(text) + self.assertEqual(result, "This is a bold statement with a link.") + + def test_malformed_tag_unclosed(self): + """Test with unclosed tag.""" + text = "Unclosed paragraph" + result = makesite._strip_html_tags(text) + self.assertEqual(result, "Unclosed paragraph") + + def test_tag_with_newlines(self): + """Test tags spanning multiple lines - function doesn't handle this case.""" + text = """
Special chars: & < > "
" + result = makesite._strip_html_tags(text) + self.assertEqual(result, "Special chars: & < > "") + + def test_html5_tags(self): + """Test removing HTML5 semantic tags.""" + text = "Text
" + result = makesite._strip_html_tags(text) + self.assertEqual(result, "body{color:red;}Textalert('hi');") + + def test_comment_like_text(self): + """Test HTML comments (not removed by this function).""" + text = "Text
" + result = makesite._strip_html_tags(text) + # Comments are not removed by strip_html_tags, only tags are + self.assertIn("Text", result) + + def test_tags_with_numbers(self): + """Test tags with numbers in the name.""" + text = "Word1 Word2\n Word3
" + result = makesite._strip_html_tags(text) + self.assertEqual(result, "Word1 Word2\n Word3") diff --git a/test/test_strip_tags_and_truncate.py b/test/test_strip_tags_and_truncate.py new file mode 100644 index 0000000..891b70f --- /dev/null +++ b/test/test_strip_tags_and_truncate.py @@ -0,0 +1,127 @@ +import unittest +import makesite + + +class StripTagsAndTruncateTest(unittest.TestCase): + + def test_truncate_plain_text(self): + """Test truncating plain text without HTML.""" + text = "This is a simple sentence with more than five words in it." + result = makesite._strip_tags_and_truncate(text, words=5) + self.assertEqual(result, "This is a simple sentence") + + def test_truncate_default_words(self): + """Test truncating with default word count (25).""" + text = " ".join([f"word{i}" for i in range(30)]) # 30 words + result = makesite._strip_tags_and_truncate(text) + words_result = result.split() + self.assertEqual(len(words_result), 25) + + def test_strip_and_truncate_html(self): + """Test stripping HTML tags and truncating.""" + text = "One two three
This is a bold paragraph with link.
+& < > " words here
" + result = makesite._strip_tags_and_truncate(text, words=3) + self.assertEqual(result, "& < >") + + def test_special_characters(self): + """Test with special characters and accents.""" + text = "Café résumé naïve élève über" + result = makesite._strip_tags_and_truncate(text, words=3) + self.assertEqual(result, "Café résumé naïve") + + def test_punctuation_preserved(self): + """Test that punctuation is preserved.""" + text = "Hello, world! How are you?" + result = makesite._strip_tags_and_truncate(text, words=3) + self.assertEqual(result, "Hello, world! How") + + def test_tabs_and_spaces(self): + """Test with tabs and various whitespace.""" + text = "word1\t\tword2\t word3 word4" + result = makesite._strip_tags_and_truncate(text, words=3) + self.assertEqual(result, "word1 word2 word3") + + def test_html_with_attributes(self): + """Test HTML with various attributes gets stripped correctly.""" + text = 'Word1 word2 word3
word4 word5' + result = makesite._strip_tags_and_truncate(text, words=4) + self.assertEqual(result, "Word1 word2 word3 word4") + + def test_zero_words(self): + """Test with zero words requested.""" + text = "Some text here" + result = makesite._strip_tags_and_truncate(text, words=0) + self.assertEqual(result, "") + + def test_leading_trailing_whitespace(self): + """Test that leading/trailing whitespace doesn't affect word count.""" + text = " word1 word2 word3 " + result = makesite._strip_tags_and_truncate(text, words=2) + self.assertEqual(result, "word1 word2")