]> git.openstreetmap.org Git - rails.git/blobdiff - vendor/gems/rspec-1.1.2/lib/spec/runner/spec_parser.rb
added RSpec and RSpec on Rails
[rails.git] / vendor / gems / rspec-1.1.2 / lib / spec / runner / spec_parser.rb
diff --git a/vendor/gems/rspec-1.1.2/lib/spec/runner/spec_parser.rb b/vendor/gems/rspec-1.1.2/lib/spec/runner/spec_parser.rb
new file mode 100644 (file)
index 0000000..5ce51e3
--- /dev/null
@@ -0,0 +1,53 @@
+module Spec
+  module Runner
+    # Parses a spec file and finds the nearest example for a given line number.
+    class SpecParser
+      def spec_name_for(io, line_number)
+        source  = io.read
+        example_group, example_group_line = example_group_at_line(source, line_number)
+        example, example_line = example_at_line(source, line_number)
+        if example_group && example && (example_group_line < example_line)
+          "#{example_group} #{example}"
+        elsif example_group
+          example_group
+        else
+          nil
+        end
+      end
+
+    protected
+
+      def example_group_at_line(source, line_number)
+        find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/)
+      end
+
+      def example_at_line(source, line_number)
+        find_above(source, line_number, /^\s*(specify|it)\s+(.*)\s+do/)
+      end
+
+      # Returns the context/describe or specify/it name and the line number
+      def find_above(source, line_number, pattern)
+        lines_above_reversed(source, line_number).each_with_index do |line, n|
+          return [parse_description($2), line_number-n] if line =~ pattern
+        end
+        nil
+      end
+
+      def lines_above_reversed(source, line_number)
+        lines = source.split("\n")
+        lines[0...line_number].reverse
+      end
+      
+      def parse_description(str)
+        return str[1..-2] if str =~ /^['"].*['"]$/
+        if matches = /^['"](.*)['"](,.*)?$/.match(str)
+          return ::Spec::Example::ExampleGroupMethods.description_text(matches[1])
+        end
+        if matches = /^(.*)\s*,\s*['"](.*)['"](,.*)?$/.match(str)
+          return ::Spec::Example::ExampleGroupMethods.description_text(matches[1], matches[2])
+        end
+        return str
+      end
+    end
+  end
+end