Class: Chop::Diff

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

Direct Known Subclasses

DefinitionList, Table

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Diff.



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

def initialize selector = nil, table = nil, session = Capybara.current_session, timeout = Capybara.default_max_wait_time, 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

Returns:

  • (Object)

    the current value of block



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

def block
  @block
end

#header_transformationsObject

Returns the value of attribute header_transformations.



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

def header_transformations
  @header_transformations
end

#selectorObject

Returns the value of attribute selector

Returns:

  • (Object)

    the current value of selector



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

def selector
  @selector
end

#sessionObject

Returns the value of attribute session

Returns:

  • (Object)

    the current value of session



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

def session
  @session
end

#tableObject

Returns the value of attribute table

Returns:

  • (Object)

    the current value of table



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

def table
  @table
end

#timeoutObject

Returns the value of attribute timeout

Returns:

  • (Object)

    the current value of timeout



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

def timeout
  @timeout
end

#transformationsObject

Returns the value of attribute transformations.



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

def transformations
  @transformations
end

Class Method Details

.diff!(selector, table, session: Capybara.current_session, timeout: Capybara.default_max_wait_time, errors: [], **kwargs, &block) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/chop/diff.rb', line 8

def self.diff! selector, table, session: Capybara.current_session, timeout: Capybara.default_max_wait_time, errors: [], **kwargs, &block
  errors += session.driver.invalid_element_errors
  errors += [Cucumber::MultilineArgument::DataTable::Different]
  session.document.synchronize timeout, errors: errors do
    new(selector, table, session, timeout, block).diff! **kwargs
  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

#cell_to_image_filename(cell) ⇒ Object



16
17
18
19
20
# File 'lib/chop/diff.rb', line 16

def cell_to_image_filename cell
  cell.all("img").map do |img|
    File.basename(img[:src] || "").split("?")[0].sub(/-[0-9a-f]{64}/, '')
  end.first
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, **kwargs) ⇒ Object



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

def diff! cucumber_table = table, **kwargs
  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, **kwargs
  elsif cucumber_table.raw.flatten != actual.flatten
    raise Cucumber::MultilineArgument::DataTable::Different.new(cucumber_table)
  end
end

#field(key) ⇒ Object



85
86
87
88
89
90
91
# File 'lib/chop/diff.rb', line 85

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

#hash_transformation(&block) ⇒ Object



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

def hash_transformation &block
  transformation do |rows|
    header = rows[0]
    keys = header.to_a.map.with_index do |cell, index|
      key = cell.text.parameterize.underscore
      next key if key.present?
      next cell.text if cell.text.present?
      index + 1
    end
    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



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

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



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

def header_transformation &block
  header_transformations << block
end

#image(*keys) ⇒ Object



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

def image *keys
  keys.each do |key|
    field(key) do |cell|
      cell_to_image_filename(cell)
    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



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

def transformation &block
  transformations << block
end