Class: Chop::Diff

Inherits:
Struct
  • Object
show all
Defined in:
lib/chop/diff.rb

Direct Known Subclasses

DefinitionList, Table, UnorderedList

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(selector = nil, table = nil, session = Capybara.current_session, block = nil, &other_block) ⇒ Diff



31
32
33
34
35
36
37
38
# File 'lib/chop/diff.rb', line 31

def initialize selector = nil, table = nil, session = Capybara.current_session, block = nil, &other_block
  super
  self.selector ||= default_selector
  self.header_transformations = []
  self.transformations = []
  instance_eval &block if block.respond_to?(:call)
  instance_eval &other_block if block_given?
end

Instance Attribute Details

#blockObject

Returns the value of attribute block



7
8
9
# File 'lib/chop/diff.rb', line 7

def block
  @block
end

#header_transformationsObject

Returns the value of attribute header_transformations.



29
30
31
# File 'lib/chop/diff.rb', line 29

def header_transformations
  @header_transformations
end

#selectorObject

Returns the value of attribute selector



7
8
9
# File 'lib/chop/diff.rb', line 7

def selector
  @selector
end

#sessionObject

Returns the value of attribute session



7
8
9
# File 'lib/chop/diff.rb', line 7

def session
  @session
end

#tableObject

Returns the value of attribute table



7
8
9
# File 'lib/chop/diff.rb', line 7

def table
  @table
end

#transformationsObject

Returns the value of attribute transformations.



29
30
31
# File 'lib/chop/diff.rb', line 29

def transformations
  @transformations
end

Class Method Details

.diff!(selector, table, session: Capybara.current_session, &block) ⇒ Object



8
9
10
# File 'lib/chop/diff.rb', line 8

def self.diff! selector, table, session: Capybara.current_session, &block
  new(selector, table, session, block).diff!
end

.text_or_image_alt_finderObject



18
19
20
21
22
23
24
25
26
27
# File 'lib/chop/diff.rb', line 18

def self.text_or_image_alt_finder
  ->(cell) do
    text = cell.text
    if text.blank? && image = cell.first("img")
      image["alt"]
    else
      text
    end
  end
end

Instance Method Details

#allow_not_foundObject



113
114
115
# File 'lib/chop/diff.rb', line 113

def allow_not_found
  @allow_not_found = true
end

#cells(&block) ⇒ Object



105
106
107
# File 'lib/chop/diff.rb', line 105

def cells &block
  self.cells_finder = block
end

#diff!(cucumber_table = table) ⇒ Object



142
143
144
145
146
147
148
149
150
# File 'lib/chop/diff.rb', line 142

def diff! cucumber_table = table
  actual = to_a
  # FIXME should just delegate to Cucumber's #diff!. Cucumber needs to handle empty tables better.
  if !cucumber_table.raw.flatten.empty? && !actual.flatten.empty?
    cucumber_table.diff! actual
  elsif cucumber_table.raw.flatten != actual.flatten
    raise Cucumber::MultilineArgument::DataTable::Different.new(cucumber_table)
  end
end

#field(key) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/chop/diff.rb', line 81

def field key
  hash_transformation do |hashes|
    hashes.map! do |row|
      row.merge key => yield(row[key])
    end
  end
end

#hash_transformation(&block) ⇒ Object



70
71
72
73
74
75
76
77
78
79
# File 'lib/chop/diff.rb', line 70

def hash_transformation &block
  transformation do |rows|
    header = rows[0]
    keys = header.to_a.map { |cell| cell.text.parameterize.underscore }
    body = rows[1..-1]
    hashes = body.map { |row| HashWithIndifferentAccess[keys.zip(row)] }
    yield hashes
    [header] + hashes.map(&:values)
  end
end

#header(index = nil, &block) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/chop/diff.rb', line 44

def header index=nil, &block
  if index
    header_transformation do |row|
      if index.is_a?(Symbol)
        index = row.index do |cell|
          text_finder.call(cell).parameterize.underscore.to_sym == index
        end
      end
      row[index] = yield(row[index])
      row
    end
  else
    if block.arity.zero?
      @new_header = yield
    else
      header_transformation do |row|
        yield(row)
      end
    end
  end
end

#header_transformation(&block) ⇒ Object



40
41
42
# File 'lib/chop/diff.rb', line 40

def header_transformation &block
  header_transformations << block
end

#image(*keys) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/chop/diff.rb', line 89

def image *keys
  keys.each do |key|
    field(key) do |cell|
      if image = cell.first("img")
        image["alt"]
      else
        cell
      end
    end
  end
end

#rows(&block) ⇒ Object



101
102
103
# File 'lib/chop/diff.rb', line 101

def rows &block
  self.rows_finder = block
end

#text(&block) ⇒ Object



109
110
111
# File 'lib/chop/diff.rb', line 109

def text &block
  self.text_finder = block
end

#to_aObject



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/chop/diff.rb', line 117

def to_a
  rows = rows_finder.call(root).map { |row| cells_finder.call(row).to_a }
  rows = normalize(rows)

  header = @new_header ? normalize([@new_header]).first : rows.shift || []
  header = header_transformations.reduce(header) do |header, transformation|
    header = transformation.call(header)
    normalize([header]).first
  end

  if header
    rows = [header] + rows
    rows = normalize(rows)
  end

  rows = transformations.reduce(rows) do |rows, transformation|
    rows = transformation.call(rows)
    normalize(rows)
  end

  rows.map do |row|
    row.map { |cell| text_finder.call(cell) }
  end
end

#transformation(&block) ⇒ Object



66
67
68
# File 'lib/chop/diff.rb', line 66

def transformation &block
  transformations << block
end