diff --git a/doc/default/html.md b/doc/default/html.md new file mode 100644 index 0000000000..ea1d631080 --- /dev/null +++ b/doc/default/html.md @@ -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 #=> "
Autem
" + +# paragraph - Produces a string representing an HTML paragraph. +Faker::HTML.paragraph #=> "

Incidunt atque quis

" + +# emphasis - Produces a random emphasis formatting on a random sentence. +Faker::HTML.emphasis #=> "repellat id impedit. + +# ordered_list - Produces a random ordered list of items between 1 and 10 in HTML format. +Faker::HTML.ordered_list #=> "
    \n
  1. Qui reiciendis non consequatur atque.
  2. \n
  3. Quo doloremque veritatis tempora aut.
  4. \n
  5. Aspernatur.
  6. \n
  7. Ea ab.
  8. \n
  9. Qui.
  10. \n
  11. Sit pariatur nemo eveniet.
  12. \n
  13. Molestiae aut.
  14. \n
  15. Nihil molestias iure placeat.
  16. \n
  17. Dolore autem quisquam.
  18. \n
" + +# unordered_list - Produces a random unordered list of items between 1 and 10 in HTML format. +Faker::HTML.unordered_list #=> "" + +# code - Produces a random code block formatted in HTML. +Faker::HTML.code #=> "
\nEos quasi qui.\n
" + +# table - Produces a random HTML table with 3 rows and 3 columns. +Faker::HTML.table #=> "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<\tbody>\n\n\n\n\n\n
adsimiliquevoluptatem
corruptiestrerummolestiaequidemetintemporaat
voluptatemdebitisrem
" + +# script - Generates a random " + +# link - Generates a random tag with the rel attribute set to "stylesheet" and the href attribute set to a random URL. +Faker::HTML.link #=> "" +Faker::HTML.link(rel: 'icon') #=> "" + +# 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')"}) #=> "
This is a div with XSS attributes.
" + +# 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 +``` diff --git a/lib/faker/default/html.rb b/lib/faker/default/html.rb new file mode 100644 index 0000000000..06896ce413 --- /dev/null +++ b/lib/faker/default/html.rb @@ -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 #=> "
Autem
" + # + # @faker.version 3.2.1 + def heading + level = rand(1..6) + "#{Lorem.word.capitalize}" + 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] Words to exclude from the generated paragraph. + # @return [String] + # + # @example + # Faker::HTML.paragraph #=> "

Incidunt atque quis

" + # + # @faker.version 3.2.1 + def paragraph(sentence_count: 3, supplemental: false, random_sentences_to_add: 0, exclude_words: nil) + "

#{Faker::Lorem.paragraph(sentence_count: sentence_count, supplemental: supplemental, random_sentences_to_add: random_sentences_to_add, exclude_words: exclude_words)}

" + end + + ## + # Produces a random emphasis formatting on a random word in two HTML paragraphs. + # + # @return [String] + # + # @example + # Faker::HTML.emphasis #=> "repellat id impedit" + # + # @faker.version 3.2.1 + def emphasis + "#{Faker::Lorem.paragraph(sentence_count: 1)}" + end + + ## + # Produces a random ordered list in HTML format, with at least one element. + # + # @return [String] + # + # @example + # Faker::HTML.ordered_list #=> "
    \n
  1. Qui reiciendis non consequatur atque.
  2. \n
  3. Quo doloremque veritatis tempora aut.
  4. \n
  5. Aspernatur.
  6. \n
  7. Ea ab.
  8. \n
  9. Qui.
  10. \n
  11. Sit pariatur nemo eveniet.
  12. \n
  13. Molestiae aut.
  14. \n
  15. Nihil molestias iure placeat.
  16. \n
  17. Dolore autem quisquam.
  18. \n
" + # + # @faker.version 3.2.1 + def ordered_list + number = rand(1..10) + + items = [] + number.times do + items << "
  • #{Faker::Lorem.sentence(word_count: 1)}
  • " + end + + "
      \n#{items.join("\n")}\n
    " + end + + ## + # Produces a random unordered list of items between 1 and 10 randomly in HTML format. + # + # @return [String] + # + # @example + # Faker::HTML.unordered_list #=> "" + # + # @faker.version 3.2.1 + def unordered_list + number = rand(1..10) + + items = [] + number.times do + items << "
  • #{Faker::Lorem.sentence(word_count: 1)}
  • " + end + + "" + end + + ## + # Produces a random code block formatted in HTML. + # + # @return [String] + # + # @example + # Faker::HTML.code #=> "Eos quasi qui." + # + # @faker.version 3.2.1 + def code + "#{Lorem.sentence(word_count: 1)}" + end + + ## + # Produces a random HTML table. + # + # @return [String] + # + # @example + # Faker::HTML.table #=> "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<\tbody>\n\n\n\n\n\n
    adsimiliquevoluptatem
    corruptiestrerummolestiaequidemetintemporaat
    voluptatemdebitisrem
    " + # + # @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 = "\n#{header_row}" + tbody = "\n#{body_rows.join("\n")}" + tfoot = "\n#{footer_row}" + + "\n#{thead}\n#{tbody}\n#{tfoot}\n
    " + end + + ## + # Generates a random " + # + # @faker.version 3.2.1 + def script + "" + end + + ## + # Generates a random 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 #=> "" + # + # @faker.version 3.2.1 + def link(rel: 'stylesheet') + "" + 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')"}) #=> "
    This is a div with XSS attributes.
    " + # + # @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}" + 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 = "\n" + cell_count.times do + row += "<#{tag == 'th' ? 'th' : 'td'}>#{Lorem.word}\n" + end + row += "\n" + row + end + end + end +end diff --git a/test/faker/default/test_faker_html.rb b/test/faker/default/test_faker_html.rb new file mode 100644 index 0000000000..69235a03ed --- /dev/null +++ b/test/faker/default/test_faker_html.rb @@ -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(//i)[1].to_i + open_tag = "" + close_tag = "" + + assert(header.start_with?(open_tag)) + assert(header.end_with?(close_tag)) + end + + def test_paragraph + assert_match(/

    .+<\/p>/, @tester.paragraph) + end + + def test_emphasis + assert_match(/.*<\/em>/, @tester.emphasis) + end + + def test_ordered_list + assert_match(/

      .*<\/ol>/m, @tester.ordered_list) + end + + def test_unordered_list + assert_match(/
        .*<\/ul>/m, @tester.unordered_list) + end + + def test_code + assert_match(/.+<\/code>/, @tester.code) + end + + def test_table + table_html = @tester.table + + assert(table_html.start_with?('')) + assert(table_html.end_with?('
        ')) + + assert_equal(1, count_occurrences(table_html, '')) + assert_equal(1, count_occurrences(table_html, '')) + assert_equal(1, count_occurrences(table_html, '')) + assert_equal(3, count_occurrences(table_html, '')) + assert_equal(5, count_occurrences(table_html, '')) + assert_equal(12, count_occurrences(table_html, '')) + end + + def test_script + assert_match(/