lucid 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. data/.gitignore +30 -10
  2. data/.rspec +1 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +15 -0
  6. data/Gemfile +4 -2
  7. data/HISTORY.md +22 -0
  8. data/{LICENSE.txt → LICENSE} +6 -3
  9. data/README.md +22 -8
  10. data/Rakefile +2 -1
  11. data/bin/lucid +10 -10
  12. data/bin/lucid-gen +4 -0
  13. data/lib/autotest/discover.rb +11 -0
  14. data/lib/autotest/lucid.rb +6 -0
  15. data/lib/autotest/lucid_mixin.rb +135 -0
  16. data/lib/autotest/lucid_rails.rb +6 -0
  17. data/lib/autotest/lucid_rails_rspec.rb +6 -0
  18. data/lib/autotest/lucid_rails_rspec2.rb +6 -0
  19. data/lib/autotest/lucid_rspec.rb +6 -0
  20. data/lib/autotest/lucid_rspec2.rb +6 -0
  21. data/lib/lucid.rb +32 -1
  22. data/lib/lucid/ast.rb +20 -0
  23. data/lib/lucid/ast/background.rb +116 -0
  24. data/lib/lucid/ast/comment.rb +24 -0
  25. data/lib/lucid/ast/doc_string.rb +44 -0
  26. data/lib/lucid/ast/empty_background.rb +33 -0
  27. data/lib/lucid/ast/examples.rb +49 -0
  28. data/lib/lucid/ast/feature.rb +99 -0
  29. data/lib/lucid/ast/has_steps.rb +74 -0
  30. data/lib/lucid/ast/location.rb +41 -0
  31. data/lib/lucid/ast/multiline_argument.rb +31 -0
  32. data/lib/lucid/ast/names.rb +13 -0
  33. data/lib/lucid/ast/outline_table.rb +194 -0
  34. data/lib/lucid/ast/scenario.rb +103 -0
  35. data/lib/lucid/ast/scenario_outline.rb +144 -0
  36. data/lib/lucid/ast/specs.rb +38 -0
  37. data/lib/lucid/ast/step.rb +122 -0
  38. data/lib/lucid/ast/step_collection.rb +92 -0
  39. data/lib/lucid/ast/step_invocation.rb +196 -0
  40. data/lib/lucid/ast/table.rb +730 -0
  41. data/lib/lucid/ast/tags.rb +28 -0
  42. data/lib/lucid/ast/tdl_walker.rb +195 -0
  43. data/lib/lucid/cli/app.rb +78 -0
  44. data/lib/lucid/cli/configuration.rb +261 -0
  45. data/lib/lucid/cli/options.rb +463 -0
  46. data/lib/lucid/cli/profile.rb +101 -0
  47. data/lib/lucid/configuration.rb +53 -0
  48. data/lib/lucid/core_ext/disable_autorunners.rb +15 -0
  49. data/lib/lucid/core_ext/instance_exec.rb +70 -0
  50. data/lib/lucid/core_ext/proc.rb +36 -0
  51. data/lib/lucid/core_ext/string.rb +9 -0
  52. data/lib/lucid/errors.rb +40 -0
  53. data/lib/lucid/factory.rb +43 -0
  54. data/lib/lucid/formatter/ansicolor.rb +168 -0
  55. data/lib/lucid/formatter/console.rb +218 -0
  56. data/lib/lucid/formatter/debug.rb +33 -0
  57. data/lib/lucid/formatter/duration.rb +11 -0
  58. data/lib/lucid/formatter/gherkin_formatter_adapter.rb +94 -0
  59. data/lib/lucid/formatter/gpretty.rb +24 -0
  60. data/lib/lucid/formatter/html.rb +610 -0
  61. data/lib/lucid/formatter/interceptor.rb +66 -0
  62. data/lib/lucid/formatter/io.rb +31 -0
  63. data/lib/lucid/formatter/jquery-min.js +154 -0
  64. data/lib/lucid/formatter/json.rb +19 -0
  65. data/lib/lucid/formatter/json_pretty.rb +10 -0
  66. data/lib/lucid/formatter/junit.rb +177 -0
  67. data/lib/lucid/formatter/lucid.css +283 -0
  68. data/lib/lucid/formatter/lucid.sass +244 -0
  69. data/lib/lucid/formatter/ordered_xml_markup.rb +24 -0
  70. data/lib/lucid/formatter/progress.rb +95 -0
  71. data/lib/lucid/formatter/rerun.rb +91 -0
  72. data/lib/lucid/formatter/standard.rb +235 -0
  73. data/lib/lucid/formatter/stepdefs.rb +14 -0
  74. data/lib/lucid/formatter/steps.rb +49 -0
  75. data/lib/lucid/formatter/summary.rb +35 -0
  76. data/lib/lucid/formatter/unicode.rb +53 -0
  77. data/lib/lucid/formatter/usage.rb +132 -0
  78. data/lib/lucid/generator.rb +21 -0
  79. data/lib/lucid/generators/project.rb +70 -0
  80. data/lib/lucid/generators/project/Gemfile.tt +6 -0
  81. data/lib/lucid/generators/project/browser-symbiont.rb +24 -0
  82. data/lib/lucid/generators/project/driver-symbiont.rb +4 -0
  83. data/lib/lucid/generators/project/errors.rb +26 -0
  84. data/lib/lucid/generators/project/events-symbiont.rb +36 -0
  85. data/lib/lucid/generators/project/lucid-symbiont.yml +6 -0
  86. data/lib/lucid/interface.rb +8 -0
  87. data/lib/lucid/interface_methods.rb +125 -0
  88. data/lib/lucid/interface_rb/matcher.rb +108 -0
  89. data/lib/lucid/interface_rb/rb_hook.rb +18 -0
  90. data/lib/lucid/interface_rb/rb_language.rb +190 -0
  91. data/lib/lucid/interface_rb/rb_lucid.rb +119 -0
  92. data/lib/lucid/interface_rb/rb_step_definition.rb +122 -0
  93. data/lib/lucid/interface_rb/rb_transform.rb +57 -0
  94. data/lib/lucid/interface_rb/rb_world.rb +136 -0
  95. data/lib/lucid/interface_rb/regexp_argument_matcher.rb +21 -0
  96. data/lib/lucid/load_path.rb +13 -0
  97. data/lib/lucid/parser.rb +2 -126
  98. data/lib/lucid/platform.rb +27 -0
  99. data/lib/lucid/rspec/allow_doubles.rb +20 -0
  100. data/lib/lucid/rspec/disallow_options.rb +27 -0
  101. data/lib/lucid/runtime.rb +200 -0
  102. data/lib/lucid/runtime/facade.rb +60 -0
  103. data/lib/lucid/runtime/interface_io.rb +60 -0
  104. data/lib/lucid/runtime/orchestrator.rb +218 -0
  105. data/lib/lucid/runtime/results.rb +64 -0
  106. data/lib/lucid/runtime/specs_loader.rb +79 -0
  107. data/lib/lucid/spec_file.rb +112 -0
  108. data/lib/lucid/step_definition_light.rb +20 -0
  109. data/lib/lucid/step_definitions.rb +13 -0
  110. data/lib/lucid/step_match.rb +99 -0
  111. data/lib/lucid/tdl_builder.rb +282 -0
  112. data/lib/lucid/term/ansicolor.rb +118 -0
  113. data/lib/lucid/unit.rb +11 -0
  114. data/lib/lucid/wire_support/configuration.rb +38 -0
  115. data/lib/lucid/wire_support/connection.rb +61 -0
  116. data/lib/lucid/wire_support/request_handler.rb +32 -0
  117. data/lib/lucid/wire_support/wire_exception.rb +32 -0
  118. data/lib/lucid/wire_support/wire_language.rb +54 -0
  119. data/lib/lucid/wire_support/wire_packet.rb +34 -0
  120. data/lib/lucid/wire_support/wire_protocol.rb +43 -0
  121. data/lib/lucid/wire_support/wire_protocol/requests.rb +125 -0
  122. data/lib/lucid/wire_support/wire_step_definition.rb +26 -0
  123. data/lucid.gemspec +25 -14
  124. metadata +220 -12
  125. data/lib/lucid/app.rb +0 -103
  126. data/lib/lucid/options.rb +0 -168
  127. data/lib/lucid/version.rb +0 -3
  128. data/lucid.yml +0 -8
@@ -0,0 +1,13 @@
1
+ module Lucid
2
+ module LoadPath
3
+ def add_dirs(*dirs)
4
+ dirs.each do |dir|
5
+ $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir)
6
+ end
7
+ end
8
+
9
+ module_function :add_dirs
10
+ end
11
+ end
12
+
13
+ Lucid::LoadPath.add_dirs('lib')
data/lib/lucid/parser.rb CHANGED
@@ -1,126 +1,2 @@
1
- module Lucid
2
- class Parser
3
-
4
- def initialize(options)
5
- @options = options
6
- end
7
-
8
- def specs
9
- return [] if @options[:pattern].nil?
10
-
11
- set_of_specs = gather_specs_by_glob
12
-
13
- return set_of_specs.any? ? set_of_specs : nil
14
- end
15
-
16
- def tags
17
- tags = {
18
- :or => [],
19
- :and => [],
20
- :not => []
21
- }
22
-
23
- return '' if @options[:tags].nil?
24
-
25
- @options[:tags].split(',').each do |tag|
26
- # Tags that are numeric can be ranged.
27
- if tag =~ /^(~)?([0-9]+)-([0-9]+)$/
28
- x = $2.to_i
29
- y = $3.to_i
30
- exclude = $1
31
-
32
- # Make sure numeric tags are in numerical order.
33
- if x > y
34
- hold_x = x.dup
35
- x = y.dup
36
- y = hold_x.dup
37
- end
38
-
39
- (x..y).each do |capture|
40
- if exclude
41
- tags[:not] << "#{capture}"
42
- else
43
- tags[:or] << "#{capture}"
44
- end
45
- end
46
- else
47
- if tag =~ /^~(.+)/
48
- tags[:not] << $1
49
- elsif tag =~ /^\+(.+)/
50
- tags[:and] << $1
51
- else
52
- tags[:or] << tag
53
- end
54
- end
55
- end # each
56
-
57
- [:and, :or, :not].each { |type| tags[type].uniq! }
58
-
59
- intersection = tags[:or] & tags[:not]
60
- tags[:or] -= intersection
61
- tags[:not] -= intersection
62
-
63
- intersection = tags[:and] & tags[:not]
64
- tags[:and] -= intersection
65
- tags[:not] -= intersection
66
-
67
- tags[:or].each_with_index { |tag, i| tags[:or][i] = "@#{tag}" }
68
- tags[:and].each_with_index { |tag, i| tags[:and][i] = "@#{tag}" }
69
- tags[:not].each_with_index { |tag, i| tags[:not][i] = "~@#{tag}" }
70
-
71
- tag_builder = ''
72
- tag_builder += "-t #{tags[:or].join(',')} " if tags[:or].any?
73
- tag_builder += "-t #{tags[:and].join(' -t ')} " if tags[:and].any?
74
- tag_builder += "-t #{tags[:not].join(' -t ')}" if tags[:not].any?
75
-
76
- tag_builder.gsub!('@@', '@')
77
- tag_builder
78
- end # method: tags
79
-
80
- private
81
-
82
- def gather_specs_by_glob
83
- only = []
84
- except = []
85
- specs_to_include = []
86
- specs_to_exclude = []
87
-
88
- pattern = @options[:pattern].dup
89
-
90
- # Determine if some specs were indicated to be excluded
91
- # and mark those separately. This also handles when only
92
- # specific specs are to be executed.
93
- pattern.split(',').each do |f|
94
- if f[0].chr == '~'
95
- except << f[1..f.length]
96
- else
97
- only << f
98
- end
99
- end
100
-
101
- # If there are exceptions, then all specs should be
102
- # gathered by default. Unless, that is, the command
103
- # indicates that only certain specs should be run.
104
- pattern = '**/*' if except.any?
105
- pattern = nil if only.any?
106
-
107
- if only.any?
108
- only.each do |f|
109
- #specs_to_include += Dir.glob("#{@options[:spec_path]}/#{f}.feature")
110
- specs_to_include += Dir.glob("#{f}")
111
- end
112
- else
113
- specs_to_include += Dir.glob("#{@options[:spec_path]}/#{pattern}.feature")
114
- end
115
-
116
- if except.any?
117
- except.each do |f|
118
- specs_to_exclude = Dir.glob("#{@options[:spec_path]}/#{f}.feature")
119
- end
120
- end
121
-
122
- (specs_to_include - specs_to_exclude).uniq
123
- end
124
-
125
- end # class: Parser
126
- end # module: Lucid
1
+ require 'lucid/platform'
2
+ require 'lucid/ast'
@@ -0,0 +1,27 @@
1
+ require 'rbconfig'
2
+
3
+ module Lucid
4
+ unless defined?(Lucid::VERSION)
5
+ VERSION = '0.0.5'
6
+ BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/lucid')
7
+ LIBDIR = File.expand_path(File.dirname(__FILE__) + '/../../lib')
8
+ JRUBY = defined?(JRUBY_VERSION)
9
+ IRONRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == "ironruby"
10
+ WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
11
+ OS_X = RbConfig::CONFIG['host_os'] =~ /darwin/
12
+ WINDOWS_MRI = WINDOWS && !JRUBY && !IRONRUBY
13
+ RAILS = defined?(Rails)
14
+ RUBY_BINARY = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
15
+ RUBY_2_0 = RUBY_VERSION =~ /^2\.0/
16
+ RUBY_1_9 = RUBY_VERSION =~ /^1\.9/
17
+
18
+ class << self
19
+ attr_accessor :use_full_backtrace
20
+
21
+ def file_mode(m, encoding="UTF-8")
22
+ "#{m}:#{encoding}"
23
+ end
24
+ end
25
+ self.use_full_backtrace = false
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ require 'rspec/core'
2
+
3
+ # This file allows you to use all of RSpec's mocking frameworks. This
4
+ # essentially allows you to create test doubles which are used to
5
+ # stand in place of a production object during execution.
6
+
7
+ RSpec.configuration.configure_mock_framework
8
+ Domain(RSpec::Core::MockFrameworkAdapter)
9
+
10
+ Before do
11
+ RSpec::Mocks::setup(self)
12
+ end
13
+
14
+ After do
15
+ begin
16
+ RSpec::Mocks::verify
17
+ ensure
18
+ RSpec::Mocks::teardown
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ require 'optparse'
2
+
3
+ module Spec #:nodoc:
4
+ module Runner #:nodoc:
5
+ # Lucid uses OptionParser in order to parse any command line options.
6
+ # If RSpec is being used in any way with Lucid, then what will happen
7
+ # is that RSpec's option parser will kick in and try to parse ARGV.
8
+ # Since the command line arguments will be specific to Lucid, RSpec
9
+ # will not know what to do with them and will fail. So what this bit
10
+ # of logic is doing is making sure that the option parser for RSpec
11
+ # will not be operative.
12
+ class OptionParser < ::OptionParser #:nodoc:
13
+ MODDED_RSPEC = Object.new
14
+ def MODDED_RSPEC.method_missing(m, *args); self; end
15
+
16
+ def self.method_added(m)
17
+ unless @__modding_rspec
18
+ @__modding_rspec = true
19
+ define_method(m) do |*a|
20
+ MODDED_RSPEC
21
+ end
22
+ @__modding_rspec = false
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,200 @@
1
+ require 'fileutils'
2
+ require 'multi_json'
3
+ require 'gherkin/rubify'
4
+ require 'gherkin/i18n'
5
+ require 'lucid/configuration'
6
+ require 'lucid/load_path'
7
+ require 'lucid/interface_methods'
8
+ require 'lucid/formatter/duration'
9
+ require 'lucid/runtime/interface_io'
10
+ require 'lucid/runtime/specs_loader'
11
+ require 'lucid/runtime/results'
12
+ require 'lucid/runtime/orchestrator'
13
+
14
+ module Lucid
15
+ class Runtime
16
+ attr_reader :results
17
+
18
+ include Formatter::Duration
19
+ include Runtime::InterfaceIO
20
+
21
+ def initialize(configuration = Configuration.default)
22
+ require 'lucid/core_ext/disable_autorunners'
23
+ @current_scenario = nil
24
+ @configuration = Configuration.parse(configuration)
25
+ @orchestrator = Orchestrator.new(self, @configuration)
26
+ @results = Results.new(@configuration)
27
+ end
28
+
29
+ # Allows you to take an existing runtime and change it's configuration
30
+ def configure(new_configuration)
31
+ @configuration = Configuration.parse(new_configuration)
32
+ @orchestrator.configure(@configuration)
33
+ @results.configure(@configuration)
34
+ end
35
+
36
+ def load_code_language(language)
37
+ @orchestrator.load_code_language(language)
38
+ end
39
+
40
+ def run
41
+ load_execution_context
42
+ fire_after_configuration_hook
43
+
44
+ tdl_walker = @configuration.establish_tdl_walker(self)
45
+ self.visitor = tdl_walker # Ugly circular dependency, but needed to support Domain#puts
46
+
47
+ tdl_walker.visit_features(specs)
48
+ end
49
+
50
+ def features_paths
51
+ @configuration.spec_source
52
+ end
53
+
54
+ def step_visited(step) #:nodoc:
55
+ @results.step_visited(step)
56
+ end
57
+
58
+ def scenarios(status = nil)
59
+ @results.scenarios(status)
60
+ end
61
+
62
+ def steps(status = nil)
63
+ @results.steps(status)
64
+ end
65
+
66
+ def step_match(step_name, name_to_report=nil) #:nodoc:
67
+ @orchestrator.step_match(step_name, name_to_report)
68
+ end
69
+
70
+ def unmatched_step_definitions
71
+ @orchestrator.unmatched_step_definitions
72
+ end
73
+
74
+ def matcher_text(step_keyword, step_name, multiline_arg_class) #:nodoc:
75
+ @orchestrator.matcher_text(Gherkin::I18n.code_keyword_for(step_keyword), step_name, multiline_arg_class)
76
+ end
77
+
78
+ def with_hooks(scenario, skip_hooks=false)
79
+ around(scenario, skip_hooks) do
80
+ before_and_after(scenario, skip_hooks) do
81
+ yield scenario
82
+ end
83
+ end
84
+ end
85
+
86
+ def around(scenario, skip_hooks=false, &block) #:nodoc:
87
+ if skip_hooks
88
+ yield
89
+ return
90
+ end
91
+
92
+ @orchestrator.around(scenario, block)
93
+ end
94
+
95
+ def before_and_after(scenario, skip_hooks=false) #:nodoc:
96
+ before(scenario) unless skip_hooks
97
+ yield scenario
98
+ after(scenario) unless skip_hooks
99
+ @results.scenario_visited(scenario)
100
+ end
101
+
102
+ def before(scenario) #:nodoc:
103
+ return if @configuration.dry_run? || @current_scenario
104
+ @current_scenario = scenario
105
+ @orchestrator.fire_hook(:before, scenario)
106
+ end
107
+
108
+ def after(scenario) #:nodoc:
109
+ @current_scenario = nil
110
+ return if @configuration.dry_run?
111
+ @orchestrator.fire_hook(:after, scenario)
112
+ end
113
+
114
+ def after_step #:nodoc:
115
+ return if @configuration.dry_run?
116
+ @orchestrator.fire_hook(:execute_after_step, @current_scenario)
117
+ end
118
+
119
+ def unknown_programming_language?
120
+ @orchestrator.unknown_programming_language?
121
+ end
122
+
123
+ def write_stepdefs_json
124
+ if(@configuration.testdefs)
125
+ stepdefs = []
126
+ @orchestrator.step_definitions.sort{|a,b| a.to_hash['source'] <=> a.to_hash['source']}.each do |stepdef|
127
+ stepdef_hash = stepdef.to_hash
128
+ steps = []
129
+ features.each do |feature|
130
+ feature.feature_elements.each do |feature_element|
131
+ feature_element.raw_steps.each do |step|
132
+ args = stepdef.arguments_from(step.name)
133
+ if(args)
134
+ steps << {
135
+ 'name' => step.name,
136
+ 'args' => args.map do |arg|
137
+ {
138
+ 'offset' => arg.offset,
139
+ 'val' => arg.val
140
+ }
141
+ end
142
+ }
143
+ end
144
+ end
145
+ end
146
+ end
147
+ stepdef_hash['file_colon_line'] = stepdef.file_colon_line
148
+ stepdef_hash['steps'] = steps.uniq.sort {|a,b| a['name'] <=> b['name']}
149
+ stepdefs << stepdef_hash
150
+ end
151
+ if !File.directory?(@configuration.testdefs)
152
+ FileUtils.mkdir_p(@configuration.testdefs)
153
+ end
154
+ File.open(File.join(@configuration.testdefs, 'testdefs.json'), 'w') do |io|
155
+ io.write(MultiJson.dump(stepdefs, :pretty => true))
156
+ end
157
+ end
158
+ end
159
+
160
+ # Returns AST::DocString for +string_without_triple_quotes+.
161
+ def doc_string(string_without_triple_quotes, content_type='', line_offset=0)
162
+ AST::DocString.new(string_without_triple_quotes,content_type)
163
+ end
164
+
165
+ private
166
+
167
+ def fire_after_configuration_hook #:nodoc
168
+ @orchestrator.fire_hook(:after_configuration, @configuration)
169
+ end
170
+
171
+ # The specs is used to begin loading the executable specs. This is as
172
+ # opposed to loading the execution context (code files), which was
173
+ # already handled. A SpecsLoader instance is created and this is what
174
+ # makes sure that a spec file can be turned into a code construct
175
+ # (a SpecFile instance) which in turn can be broken down into an AST.
176
+ def specs
177
+ @loader ||= Runtime::SpecsLoader.new(
178
+ @configuration.spec_files,
179
+ @configuration.filters,
180
+ @configuration.tag_expression)
181
+ @loader.specs
182
+ end
183
+
184
+ # Loading the execution context means getting all of the loadable files
185
+ # in the spec repository. Loadable files means any code language type
186
+ # files. These files are sent to an orchestrator instance that will be
187
+ # responsible for loading them. The loading of these files provides the
188
+ # execution context for Lucid as it runs executable specs.
189
+ def load_execution_context
190
+ files = @configuration.library_context + @configuration.definition_context
191
+ log.info("Runtime Load Execution Context: #{files}")
192
+ @orchestrator.load_files(files)
193
+ end
194
+
195
+ def log
196
+ Lucid.logger
197
+ end
198
+ end
199
+
200
+ end
@@ -0,0 +1,60 @@
1
+ require 'forwardable'
2
+
3
+ module Lucid
4
+ class Runtime
5
+ # This is what a programming language will consider to be a runtime.
6
+ #
7
+ # It's a thin class that directs the handul of methods needed by the
8
+ # programming languages to the right place.
9
+ class Facade
10
+ extend Forwardable
11
+
12
+ def initialize(orchestrator, interface)
13
+ @orchestrator, @interface = orchestrator, interface
14
+ end
15
+
16
+ def_delegators :@interface,
17
+ :embed,
18
+ :ask,
19
+ :puts,
20
+ :features_paths,
21
+ :step_match
22
+
23
+ def_delegators :@orchestrator,
24
+ :invoke_steps,
25
+ :invoke,
26
+ :load_code_language
27
+
28
+ # Returns a Lucid::AST::Table for +text_or_table+, which can either
29
+ # be a String:
30
+ #
31
+ # table(%{
32
+ # | account | description | amount |
33
+ # | INT-100 | Taxi | 114 |
34
+ # | CUC-101 | Peeler | 22 |
35
+ # })
36
+ #
37
+ # or a 2D Array:
38
+ #
39
+ # table([
40
+ # %w{ account description amount },
41
+ # %w{ INT-100 Taxi 114 },
42
+ # %w{ CUC-101 Peeler 22 }
43
+ # ])
44
+ #
45
+ def table(text_or_table, file=nil, line_offset=0)
46
+ if Array === text_or_table
47
+ AST::Table.new(text_or_table)
48
+ else
49
+ AST::Table.parse(text_or_table, file, line_offset)
50
+ end
51
+ end
52
+
53
+ # Returns AST::DocString for +string_without_triple_quotes+.
54
+ #
55
+ def doc_string(string_without_triple_quotes, content_type='', line_offset=0)
56
+ AST::DocString.new(string_without_triple_quotes,content_type)
57
+ end
58
+ end
59
+ end
60
+ end