-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* added html generator * Update html.rb * added docs * Update html.md * resolved comments * added version & exclude argument * docs fixes
- Loading branch information
1 parent
d0ebdbe
commit f7146f0
Showing
3 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Faker::HTML | ||
|
||
Available since version 3.2.1. | ||
|
||
The `Faker::HTML` module provides methods for generating random HTML content. | ||
|
||
```ruby | ||
# heading - Produces a random HTML heading format. | ||
Faker::HTML.heading #=> "<h5>Autem</h5>" | ||
|
||
# paragraph - Produces a string representing an HTML paragraph. | ||
Faker::HTML.paragraph #=> "<p>Incidunt atque quis</p>" | ||
|
||
# emphasis - Produces a random emphasis formatting on a random sentence. | ||
Faker::HTML.emphasis #=> "<em>repellat id impedit.</em> | ||
|
||
# ordered_list - Produces a random ordered list of items between 1 and 10 in HTML format. | ||
Faker::HTML.ordered_list #=> "<ol>\n<li>Qui reiciendis non consequatur atque.</li>\n<li>Quo doloremque veritatis tempora aut.</li>\n<li>Aspernatur.</li>\n<li>Ea ab.</li>\n<li>Qui.</li>\n<li>Sit pariatur nemo eveniet.</li>\n<li>Molestiae aut.</li>\n<li>Nihil molestias iure placeat.</li>\n<li>Dolore autem quisquam.</li>\n</ol>" | ||
|
||
# unordered_list - Produces a random unordered list of items between 1 and 10 in HTML format. | ||
Faker::HTML.unordered_list #=> "<ul>\n<li>Voluptatum aliquid tempora molestiae facilis non sed.</li>\n<li>Nostrum omnis iste impedit voluptatum dolor.</li>\n<li>Esse quidem et facere.</li>\n</ul>" | ||
|
||
# code - Produces a random code block formatted in HTML. | ||
Faker::HTML.code #=> "<pre>\n<code>Eos quasi qui.</code>\n</pre>" | ||
|
||
# table - Produces a random HTML table with 3 rows and 3 columns. | ||
Faker::HTML.table #=> "<table>\n<thead>\n<th>ad</th>\n<th>similique</th>\n<th>voluptatem</th>\n</thead>\n<tbody>\n<td>corrupti</td>\n<td>est</td>\n<td>rerum</td>\n<td>molestiae</td>\n<td>quidem</td>\n<td>et</td>\n<td>in</td>\n<td>tempora</td>\n<td>at</td>\n<\tbody>\n<tfoot>\n<td>voluptatem</td>\n<td>debitis</td>\n<td>rem</td>\n</tfoot>\n</table>" | ||
|
||
# script - Generates a random <script> tag with the src attribute set to a random URL. | ||
Faker::HTML.script #=> "<script src=\"http://gulgowski.name/jordan.weimann.js\"></script>" | ||
|
||
# link - Generates a random <link> tag with the rel attribute set to "stylesheet" and the href attribute set to a random URL. | ||
Faker::HTML.link #=> "<link rel=\"stylesheet\" href=\"http://fay.io/darryl.barrows.css\">" | ||
Faker::HTML.link(rel: 'icon') #=> "<link rel=\"icon\" href=\"http://fay.io/darryl.barrows.css\">" | ||
|
||
# element - Generates HTML content with customizable attributes for any HTML tag. | ||
Faker::HTML.element(tag: 'div', content: "This is a div with XSS attributes.", attributes: {class: 'xss', onclick: "alert('XSS')"}) #=> "<div class=\"xss\" onclick=\"alert('XSS')\">This is a div with XSS attributes.</div>" | ||
|
||
# random - Produces a random output from one of the methods outlined above, excluding the methods listed in the arguments. | ||
Faker::HTML.random #=> returns output from a single method outlined above | ||
Faker::HTML.random(exclude: [:table]) #=> returns output from any single method outlined above except for "table" | ||
Faker::HTML.random(exclude: [:ordered_list, :unordered_list]) #=> returns output from any single method outlined above except for ordered_list and unordered_list | ||
|
||
# sandwich - Generates a random sandwich-style HTML content with customizable attributes. | ||
Faker::HTML.sandwich #=> returns sandwich-style HTML content as a string | ||
Faker::HTML.sandwich(sentences: 5, repeat: 3) #=> returns sandwich-style HTML content with 5 sentences per paragraph and repeated 3 times | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
# frozen_string_literal: true | ||
|
||
module Faker | ||
class HTML < Base | ||
class << self | ||
## | ||
# Produces a random HTML header format. | ||
# | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.heading #=> "<h5>Autem</h5>" | ||
# | ||
# @faker.version 3.2.1 | ||
def heading | ||
level = rand(1..6) | ||
"<h#{level}>#{Lorem.word.capitalize}</h#{level}>" | ||
end | ||
|
||
## | ||
# Produces a random HTML paragraph format. | ||
# | ||
# @param sentence_count [Integer] The number of sentences in the paragraph. | ||
# @param supplemental [Boolean] Include supplemental text. | ||
# @param random_sentences_to_add [Integer] The number of random sentences to add to the paragraph. | ||
# @param exclude_words [Array<String>] Words to exclude from the generated paragraph. | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.paragraph #=> "<p>Incidunt atque quis</p>" | ||
# | ||
# @faker.version 3.2.1 | ||
def paragraph(sentence_count: 3, supplemental: false, random_sentences_to_add: 0, exclude_words: nil) | ||
"<p>#{Faker::Lorem.paragraph(sentence_count: sentence_count, supplemental: supplemental, random_sentences_to_add: random_sentences_to_add, exclude_words: exclude_words)}</p>" | ||
end | ||
|
||
## | ||
# Produces a random emphasis formatting on a random word in two HTML paragraphs. | ||
# | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.emphasis #=> "<em>repellat id impedit</em>" | ||
# | ||
# @faker.version 3.2.1 | ||
def emphasis | ||
"<em>#{Faker::Lorem.paragraph(sentence_count: 1)}</em>" | ||
end | ||
|
||
## | ||
# Produces a random ordered list in HTML format, with at least one element. | ||
# | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.ordered_list #=> "<ol>\n<li>Qui reiciendis non consequatur atque.</li>\n<li>Quo doloremque veritatis tempora aut.</li>\n<li>Aspernatur.</li>\n<li>Ea ab.</li>\n<li>Qui.</li>\n<li>Sit pariatur nemo eveniet.</li>\n<li>Molestiae aut.</li>\n<li>Nihil molestias iure placeat.</li>\n<li>Dolore autem quisquam.</li>\n</ol>" | ||
# | ||
# @faker.version 3.2.1 | ||
def ordered_list | ||
number = rand(1..10) | ||
|
||
items = [] | ||
number.times do | ||
items << "<li>#{Faker::Lorem.sentence(word_count: 1)}</li>" | ||
end | ||
|
||
"<ol>\n#{items.join("\n")}\n</ol>" | ||
end | ||
|
||
## | ||
# Produces a random unordered list of items between 1 and 10 randomly in HTML format. | ||
# | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.unordered_list #=> "<ul>\n<li>Voluptatum aliquid tempora molestiae facilis non sed.</li>\n<li>Nostrum omnis iste impedit voluptatum dolor.</li>\n<li>Esse quidem et facere.</li>\n</ul>" | ||
# | ||
# @faker.version 3.2.1 | ||
def unordered_list | ||
number = rand(1..10) | ||
|
||
items = [] | ||
number.times do | ||
items << "<li>#{Faker::Lorem.sentence(word_count: 1)}</li>" | ||
end | ||
|
||
"<ul>\n#{items.join("\n")}\n</ul>" | ||
end | ||
|
||
## | ||
# Produces a random code block formatted in HTML. | ||
# | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.code #=> "<code>Eos quasi qui.</code>" | ||
# | ||
# @faker.version 3.2.1 | ||
def code | ||
"<code>#{Lorem.sentence(word_count: 1)}</code>" | ||
end | ||
|
||
## | ||
# Produces a random HTML table. | ||
# | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.table #=> "<table>\n<thead>\n<th>ad</th>\n<th>similique</th>\n<th>voluptatem</th>\n</thead>\n<tbody>\n<td>corrupti</td>\n<td>est</td>\n<td>rerum</td>\n<td>molestiae</td>\n<td>quidem</td>\n<td>et</td>\n<td>in</td>\n<td>tempora</td>\n<td>at</td>\n<\tbody>\n<tfoot>\n<td>voluptatem</td>\n<td>debitis</td>\n<td>rem</td>\n</tfoot>\n</table>" | ||
# | ||
# @faker.version 3.2.1 | ||
def table | ||
header_row = generate_table_row('th', 3) | ||
footer_row = generate_table_row('td', 3) | ||
|
||
body_rows = [] | ||
3.times do | ||
row = generate_table_row('td', 3) | ||
body_rows << row | ||
end | ||
|
||
thead = "<thead>\n#{header_row}</thead>" | ||
tbody = "<tbody>\n#{body_rows.join("\n")}</tbody>" | ||
tfoot = "<tfoot>\n#{footer_row}</tfoot>" | ||
|
||
"<table>\n#{thead}\n#{tbody}\n#{tfoot}\n</table>" | ||
end | ||
|
||
## | ||
# Generates a random <script> tag with the `src` attribute set to a random URL. | ||
# | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.script #=> "<script src=\"http://gulgowski.name/jordan.weimann.js\"></script>" | ||
# | ||
# @faker.version 3.2.1 | ||
def script | ||
"<script src=\"#{Faker::Internet.url}.js\"></script>" | ||
end | ||
|
||
## | ||
# Generates a random <link> tag with the `rel` attribute set to "stylesheet" and the `href` attribute set to a random URL. | ||
# | ||
# @param rel [String] The rel of the link tag. | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.link #=> "<link rel=\"stylesheet\" href=\"http://fay.io/darryl.barrows.css\">" | ||
# | ||
# @faker.version 3.2.1 | ||
def link(rel: 'stylesheet') | ||
"<link rel=\"#{rel}\" href=\"#{Faker::Internet.url}.css\">" | ||
end | ||
|
||
## | ||
# Generates HTML content with customizable attributes for any HTML tag. | ||
# | ||
# @param tag [String] The HTML tag to generate. | ||
# @param content [String] The Content of the HTML tag. | ||
# @param attributes [Hash] The attributes to include in the tag. | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.element(tag: 'div', content: "This is a div with XSS attributes.", attributes: {class: 'xss', onclick: "alert('XSS')"}) #=> "<div class=\"xss\" onclick=\"alert('XSS')\">This is a div with XSS attributes.</div>" | ||
# | ||
# @faker.version 3.2.1 | ||
def element(tag: 'div', content: Lorem.sentence(word_count: 3), attributes: { class: Lorem.word, onclick: "#{Lorem.word}()" }) | ||
attribute_string = attributes.map { |key, value| "#{key}=\"#{value}\"" }.join(' ') | ||
"<#{tag} #{attribute_string}>#{content}</#{tag}>" | ||
end | ||
|
||
## | ||
# Produces a random method from the methods above, excluding the methods listed in the arguments. | ||
# | ||
# @overload random(methods) | ||
# @param methods [Symbol] Specify which methods to exclude. | ||
# | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.random #=> returns output from a single method outlined above | ||
# Faker::HTML.random(exclude: [:table]) #=> returns output from any single method outlined above except for "table" | ||
# Faker::HTML.random(exclude: [:ordered_list, :unordered_list]) #=> returns output from any single method outlined above except for either ordered_list and unordered_list | ||
# | ||
# @faker.version 3.2.1 | ||
def random(exclude: []) | ||
method_list = available_methods | ||
exclude.each { |ex| method_list.delete_if { |meth| meth == ex.to_sym } } | ||
send(method_list[Faker::Config.random.rand(0..method_list.length - 1)]) | ||
end | ||
|
||
## | ||
# Generates a random HTML content sandwich, starting with a header, followed by paragraphs, and random elements. | ||
# | ||
# @param sentences [Integer] The number of sentences in each paragraph. | ||
# @param repeat [Integer] The number of times to repeat the pattern (header, paragraph, random). | ||
# @return [String] | ||
# | ||
# @example | ||
# Faker::HTML.sandwich(sentences: 3, repeat: 2) #=> returns a sandwich of HTML content with 2 repetitions, each having a header, paragraph, and random element | ||
# | ||
# @faker.version 3.2.1 | ||
def sandwich(sentences: 3, repeat: 1) | ||
text_block = [] | ||
text_block << heading | ||
repeat.times do | ||
text_block << paragraph(sentence_count: sentences) | ||
text_block << random(exclude: %i[script link]) | ||
end | ||
text_block.join("\n") | ||
end | ||
|
||
private | ||
|
||
def available_methods | ||
(HTML.public_methods(false) - Base.methods).sort | ||
end | ||
|
||
def generate_table_row(tag, cell_count) | ||
row = "<tr>\n" | ||
cell_count.times do | ||
row += "<#{tag == 'th' ? 'th' : 'td'}>#{Lorem.word}</#{tag == 'th' ? 'th' : 'td'}>\n" | ||
end | ||
row += "</tr>\n" | ||
row | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative '../../test_helper' | ||
|
||
class TestFakerHTML < Test::Unit::TestCase | ||
def setup | ||
@tester = Faker::HTML | ||
end | ||
|
||
def test_heading | ||
header = @tester.heading | ||
level = header.match(/<h(\d)>/i)[1].to_i | ||
open_tag = "<h#{level}>" | ||
close_tag = "</h#{level}>" | ||
|
||
assert(header.start_with?(open_tag)) | ||
assert(header.end_with?(close_tag)) | ||
end | ||
|
||
def test_paragraph | ||
assert_match(/<p>.+<\/p>/, @tester.paragraph) | ||
end | ||
|
||
def test_emphasis | ||
assert_match(/<em>.*<\/em>/, @tester.emphasis) | ||
end | ||
|
||
def test_ordered_list | ||
assert_match(/<ol>.*<\/ol>/m, @tester.ordered_list) | ||
end | ||
|
||
def test_unordered_list | ||
assert_match(/<ul>.*<\/ul>/m, @tester.unordered_list) | ||
end | ||
|
||
def test_code | ||
assert_match(/<code>.+<\/code>/, @tester.code) | ||
end | ||
|
||
def test_table | ||
table_html = @tester.table | ||
|
||
assert(table_html.start_with?('<table>')) | ||
assert(table_html.end_with?('</table>')) | ||
|
||
assert_equal(1, count_occurrences(table_html, '<thead>')) | ||
assert_equal(1, count_occurrences(table_html, '<tbody>')) | ||
assert_equal(1, count_occurrences(table_html, '<tfoot>')) | ||
assert_equal(3, count_occurrences(table_html, '<th>')) | ||
assert_equal(5, count_occurrences(table_html, '<tr>')) | ||
assert_equal(12, count_occurrences(table_html, '<td>')) | ||
end | ||
|
||
def test_script | ||
assert_match(/<script src=".+"><\/script>/, @tester.script) | ||
end | ||
|
||
def test_link | ||
assert_match(/<link rel=".+" href=".+">/, @tester.link) | ||
assert_match(/<link rel="alternate" href=".+">/, @tester.link(rel: 'alternate')) | ||
end | ||
|
||
def test_element | ||
assert_match(/<div .+>.+<\/div>/, @tester.element) | ||
assert_match(/<span .+>.+<\/span>/, @tester.element(tag: 'span')) | ||
end | ||
|
||
def test_random | ||
assert_match(/<[^>]+>.*<\/[^>]+>|<link[^>]+>/, @tester.random) | ||
end | ||
|
||
def test_sandwich | ||
sandwich = @tester.sandwich(sentences: 2, repeat: 3) | ||
|
||
assert_match(/<h\d>[\w\s]+<\/h\d>/i, sandwich) | ||
assert_match(/<p>[\w\s.,!?]+<\/p>/i, sandwich) | ||
assert_match(/<[^>]+>[\w\s.,!?]*<\/[^>]+>/i, sandwich) | ||
end | ||
|
||
private | ||
|
||
def count_occurrences(text, substring) | ||
text.scan(substring).length | ||
end | ||
end |