Class: GherkinReadability

Inherits:
Object
  • Object
show all
Defined in:
lib/gherkin_readability.rb

Overview

gherkin readability

Instance Method Summary collapse

Constructor Details

#initializeGherkinReadability



18
19
20
# File 'lib/gherkin_readability.rb', line 18

def initialize
  @readability_by_file = {}
end

Instance Method Details

#analyze(files, verbose = false) ⇒ Object



22
23
24
25
26
27
28
29
30
# 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) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
# 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) ⇒ Object



134
135
136
137
138
139
140
141
142
# 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) ⇒ Object



80
81
82
83
84
85
86
87
88
89
# 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) ⇒ Object



124
125
126
127
128
129
130
131
132
# 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) ⇒ Object



75
76
77
78
# File 'lib/gherkin_readability.rb', line 75

def parse(file)
  content = File.read file
  Gherkin::Parser.new.parse content
end

#readability(sentences) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
# 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

#reportObject



48
49
50
51
52
# 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) ⇒ Object



91
92
93
94
95
96
97
98
99
# 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) ⇒ Object



40
41
42
43
44
45
46
# 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) ⇒ Object



32
33
34
35
36
37
38
# 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) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# 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

#summaryObject



54
55
56
57
58
59
60
61
# 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) ⇒ Object



144
145
146
# File 'lib/gherkin_readability.rb', line 144

def uncapitalize(term)
  term[0, 1].downcase + term[1..-1]
end