class GherkinReadability

gherkin readability

Public Class Methods

new() click to toggle source
# File lib/gherkin_readability.rb, line 18
def initialize
  @readability_by_file = {}
end

Public Instance Methods

analyze(files, verbose = false) click to toggle source
# File lib/gherkin_readability.rb, line 22
def analyze(files, verbose = false)
  files.each do |file|
    sentences = extract_sentences parse(file)
    sentences.each do |sentence|
      puts "#{readability([sentence]).round} - #{sentence.tr("\n", ' ').strip}"
    end if verbose
    @readability_by_file[file] = readability sentences
  end
end
expand_outlines(sentence, example) click to toggle source
# File lib/gherkin_readability.rb, line 148
def expand_outlines(sentence, example)
  result = []
  headers = example[:tableHeader][:cells].map { |cell| cell[:value] }

  example[:tableBody].each do |row|
    modified_sentence = sentence.dup
    values = row[:cells].map { |cell| cell[:value] }
    headers.zip(values).map { |key, value| modified_sentence.gsub!("<#{key}>", value) }
    result.push modified_sentence
  end
  result
end
extract_examples(examples, prototype) click to toggle source
# File lib/gherkin_readability.rb, line 134
def extract_examples(examples, prototype)
  examples.map do |example|
    sentences = []
    sentences.push example[:name] unless example[:name].empty?
    sentences.push example[:description] if example.key? :description
    sentences += expand_outlines(prototype, example)
    sentences
  end.flatten
end
extract_sentences(input) click to toggle source
# File lib/gherkin_readability.rb, line 80
def extract_sentences(input)
  sentences = []

  sentences.push input[:name] unless input[:name].empty?
  sentences.push input[:description] if input.key? :description
  sentences.push input[:background][:name] if input.key?(:background) && !input[:background][:name].empty?
  sentences += scenario_names input
  sentences += sentences input
  sentences.map { |sentence| sentence.gsub(/ «.+»/, '') }
end
extract_terms_from_scenario(steps, background) click to toggle source
# File lib/gherkin_readability.rb, line 124
def extract_terms_from_scenario(steps, background)
  steps.map do |step|
    keyword = step[:keyword]
    keyword = 'and ' unless background.empty? || keyword != 'Given '
    terms = [keyword, step[:text]].join
    terms = uncapitalize(terms) unless background.empty?
    background = terms
  end.flatten
end
parse(file) click to toggle source
# File lib/gherkin_readability.rb, line 75
def parse(file)
  content = File.read file
  Gherkin::Parser.new.parse content
end
readability(sentences) click to toggle source
# File lib/gherkin_readability.rb, line 63
def readability(sentences)
  require 'syllables'

  total_words = 0
  total_syllabels = 0
  Syllables.new(sentences.join('\n')).to_h.each do |_word, syllabels|
    total_words += 1
    total_syllabels += syllabels
  end
  206.835 - 1.015 * (total_words / sentences.length) - 84.6 * (total_syllabels / total_words)
end
report() click to toggle source
# File lib/gherkin_readability.rb, line 48
def report
  @readability_by_file.sort { |lhs, rhs| lhs[1] <=> rhs[1] }.reverse_each do |file, rating|
    puts "#{rating.round}: #{file}"
  end
end
scenario_names(input) click to toggle source
# File lib/gherkin_readability.rb, line 91
def scenario_names(input)
  scenarios = []

  input[:scenarioDefinitions].each do |scenario|
    scenarios.push scenario[:name]
    scenarios.push scenario[:description] if scenario.key? :description
  end
  scenarios
end
select_above!(threshold) click to toggle source
# File lib/gherkin_readability.rb, line 40
def select_above!(threshold)
  filtered = {}
  @readability_by_file.each do |file, rating|
    filtered[file] = rating if rating >= threshold
  end
  @readability_by_file = filtered
end
select_below!(threshold) click to toggle source
# File lib/gherkin_readability.rb, line 32
def select_below!(threshold)
  filtered = {}
  @readability_by_file.each do |file, rating|
    filtered[file] = rating if rating <= threshold
  end
  @readability_by_file = filtered
end
sentences(input) click to toggle source
# File lib/gherkin_readability.rb, line 101
def sentences(input)
  sentences = []
  background = []

  if input.key?(:background) && input[:background].key?(:steps)
    background = extract_terms_from_scenario(input[:background][:steps], [])
  end

  input[:scenarioDefinitions].each do |scenario|
    next unless scenario.key? :steps
    terms = background.dup

    terms.push extract_terms_from_scenario(scenario[:steps], background)
    sentence = terms.join(' ').strip
    if scenario.key? :examples
      sentences += extract_examples(scenario[:examples], sentence)
    else
      sentences.push sentence
    end
  end
  sentences
end
summary() click to toggle source
# File lib/gherkin_readability.rb, line 54
def summary
  average_readability = 0
  @readability_by_file.each do |_, rating|
    average_readability += rating
  end
  average_readability /= @readability_by_file.length
  puts "\n#{@readability_by_file.length} files analyzed. Average readability is #{average_readability.round}"
end
uncapitalize(term) click to toggle source
# File lib/gherkin_readability.rb, line 144
def uncapitalize(term)
  term[0, 1].downcase + term[1..-1]
end