File: helpers.rb

package info (click to toggle)
ruby-cucumber-core 1.5.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 580 kB
  • sloc: ruby: 5,763; makefile: 2
file content (173 lines) | stat: -rw-r--r-- 4,129 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
module Cucumber
  module Core
    module Gherkin
      module Writer

        module HasOptionsInitializer
          def self.included(base)
            base.extend HasDefaultKeyword
          end

          attr_reader :name, :options
          private :name, :options

          def initialize(*args)
            @comments = args.shift if args.first.is_a?(Array)
            @comments ||= []
            @options = args.pop if args.last.is_a?(Hash)
            @options ||= {}
            @name = args.first
          end

          private

          def comments_statement
            @comments
          end

          def keyword
            options.fetch(:keyword) { self.class.keyword }
          end

          def name_statement
            "#{keyword}: #{name}".strip
          end

          def tag_statement
            tags
          end

          def tags
            options[:tags]
          end

          module HasDefaultKeyword
            def default_keyword(keyword)
              @keyword = keyword
            end

            def keyword
              @keyword
            end
          end
        end

        module AcceptsComments
          def comment(line)
            comment_lines << "# #{line}"
          end

          def comment_lines
            @comment_lines ||= []
          end

          def slurp_comments
            comment_lines.tap { @comment_lines = nil }
          end
        end

        module HasElements
          include AcceptsComments

          def self.included(base)
            base.extend HasElementBuilders
          end

          def build(source = [])
            elements.inject(source + statements) { |acc, el| el.build(acc) }
          end

          private
          def elements
            @elements ||= []
          end

          module HasElementBuilders
            def elements(*names)
              names.each { |name| element(name) }
            end

            private
            def element(name)
              define_method name do |*args, &source|
                factory_name = String(name).split("_").map(&:capitalize).join
                factory = Writer.const_get(factory_name)
                factory.new(slurp_comments, *args).tap do |builder|
                  builder.instance_exec(&source) if source
                  elements << builder
                end
                self
              end
            end
          end
        end

        module Indentation
          def self.level(number)
            Module.new do
              define_method :indent do |string, amount=nil|
                amount ||= number
                return string if string.nil? || string.empty?
                (' ' * amount) + string
              end

              define_method :indent_level do
                number
              end

              define_method :prepare_statements do |*statements|
                statements.flatten.compact.map { |s| indent(s) }
              end
            end
          end
        end

        module HasDescription
          private
          def description
            options.fetch(:description) { '' }.split("\n").map(&:strip)
          end

          def description_statement
            description.map { |s| indent(s,2) } unless description.empty?
          end
        end

        module HasRows
          def row(*cells)
            rows << cells
          end

          def rows
            @rows ||= []
          end

          private

          def row_statements(indent=nil)
            rows.map { |row| indent(table_row(row), indent) }
          end

          def table_row(row)
            padded = pad(row)
            "| #{padded.join(' | ')} |"
          end

          def pad(row)
            row.map.with_index { |text, position| justify_cell(text, position) }
          end

          def column_length(column)
            lengths = rows.transpose.map { |r| r.map(&:length).max }
            lengths[column]
          end

          def justify_cell(cell, position)
            cell.ljust(column_length(position))
          end
        end
      end

    end
  end
end