saper 0.5.1 → 0.5.2

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 (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/Rakefile +6 -6
  4. data/bin/saper +17 -36
  5. data/lib/saper.rb +63 -20
  6. data/lib/saper/actions/append_with.rb +1 -1
  7. data/lib/saper/actions/convert_to_html.rb +1 -1
  8. data/lib/saper/actions/convert_to_json.rb +6 -2
  9. data/lib/saper/actions/convert_to_markdown.rb +1 -1
  10. data/lib/saper/actions/convert_to_time.rb +38 -1
  11. data/lib/saper/actions/convert_to_xml.rb +1 -1
  12. data/lib/saper/actions/create_atom.rb +6 -2
  13. data/lib/saper/actions/fetch.rb +3 -2
  14. data/lib/saper/actions/fetch_with_token.rb +18 -0
  15. data/lib/saper/actions/find.rb +1 -1
  16. data/lib/saper/actions/find_first.rb +1 -1
  17. data/lib/saper/actions/get_attribute.rb +7 -2
  18. data/lib/saper/actions/get_contents.rb +1 -1
  19. data/lib/saper/actions/get_text.rb +1 -1
  20. data/lib/saper/actions/nothing.rb +11 -0
  21. data/lib/saper/actions/prepend_with.rb +2 -2
  22. data/lib/saper/actions/remove_after.rb +2 -2
  23. data/lib/saper/actions/remove_before.rb +2 -2
  24. data/lib/saper/actions/remove_matching.rb +2 -2
  25. data/lib/saper/actions/remove_tags.rb +1 -1
  26. data/lib/saper/actions/replace.rb +1 -1
  27. data/lib/saper/actions/run_recipe.rb +2 -2
  28. data/lib/saper/actions/run_recipe_and_save.rb +3 -3
  29. data/lib/saper/actions/save.rb +2 -2
  30. data/lib/saper/actions/select_matching.rb +2 -2
  31. data/lib/saper/actions/set_input.rb +1 -1
  32. data/lib/saper/actions/skip_tags.rb +1 -1
  33. data/lib/saper/actions/split.rb +1 -1
  34. data/lib/saper/arguments/attribute.rb +6 -0
  35. data/lib/saper/arguments/recipe.rb +12 -6
  36. data/lib/saper/arguments/service.rb +12 -0
  37. data/lib/saper/arguments/text.rb +1 -0
  38. data/lib/saper/arguments/timezone.rb +2 -1
  39. data/lib/saper/arguments/url.rb +12 -0
  40. data/lib/saper/arguments/variable.rb +2 -1
  41. data/lib/saper/arguments/xpath.rb +2 -1
  42. data/lib/saper/core/action.rb +43 -13
  43. data/lib/saper/core/argument.rb +30 -14
  44. data/lib/saper/core/browser.rb +29 -28
  45. data/lib/saper/core/dsl.rb +14 -16
  46. data/lib/saper/core/error.rb +1 -1
  47. data/lib/saper/core/item.rb +2 -2
  48. data/lib/saper/core/keychain.rb +58 -5
  49. data/lib/saper/core/namespace.rb +15 -18
  50. data/lib/saper/core/recipe.rb +53 -12
  51. data/lib/saper/core/result.rb +72 -0
  52. data/lib/saper/core/runtime.rb +44 -177
  53. data/lib/saper/core/stack.rb +57 -0
  54. data/lib/saper/items/atom.rb +18 -1
  55. data/lib/saper/items/document.rb +39 -19
  56. data/lib/saper/items/html.rb +52 -7
  57. data/lib/saper/items/json.rb +19 -1
  58. data/lib/saper/items/markdown.rb +14 -4
  59. data/lib/saper/items/nothing.rb +6 -0
  60. data/lib/saper/items/text.rb +28 -3
  61. data/lib/saper/items/time.rb +25 -2
  62. data/lib/saper/items/url.rb +8 -2
  63. data/lib/saper/items/xml.rb +51 -11
  64. data/lib/{lib → saper/patches}/mechanize.rb +0 -0
  65. data/lib/{lib → saper/patches}/nokogiri.rb +0 -0
  66. data/lib/saper/version.rb +2 -2
  67. data/spec/actions/append_with_spec.rb +29 -52
  68. data/spec/actions/convert_to_html_spec.rb +13 -30
  69. data/spec/actions/convert_to_json_spec.rb +13 -30
  70. data/spec/actions/convert_to_markdown_spec.rb +17 -19
  71. data/spec/actions/convert_to_time_spec.rb +25 -43
  72. data/spec/actions/convert_to_xml_spec.rb +15 -11
  73. data/spec/actions/create_atom_spec.rb +11 -19
  74. data/spec/actions/fetch_spec.rb +3 -8
  75. data/spec/actions/find_first_spec.rb +38 -40
  76. data/spec/actions/find_spec.rb +23 -39
  77. data/spec/actions/get_attribute_spec.rb +30 -3
  78. data/spec/actions/{get_contents.rb → get_contents_spec.rb} +0 -0
  79. data/spec/actions/{get_text.rb → get_text_spec.rb} +0 -0
  80. data/spec/actions/nothing_spec.rb +7 -0
  81. data/spec/actions/prepend_with_spec.rb +31 -18
  82. data/spec/actions/{remove_after.rb → remove_after_spec.rb} +0 -0
  83. data/spec/actions/{remove_before.rb → remove_before_spec.rb} +0 -0
  84. data/spec/actions/remove_matching_spec.rb +7 -0
  85. data/spec/actions/remove_tags_spec.rb +7 -0
  86. data/spec/actions/run_recipe_and_save_spec.rb +7 -0
  87. data/spec/actions/run_recipe_spec.rb +7 -0
  88. data/spec/arguments/attribute_spec.rb +7 -0
  89. data/spec/arguments/recipe_spec.rb +7 -0
  90. data/spec/arguments/text_spec.rb +7 -0
  91. data/spec/arguments/timezone_spec.rb +7 -0
  92. data/spec/arguments/variable_spec.rb +7 -0
  93. data/spec/arguments/xpath_spec.rb +7 -0
  94. data/spec/core/action_spec.rb +13 -142
  95. data/spec/core/argument_spec.rb +38 -71
  96. data/spec/core/browser_spec.rb +18 -3
  97. data/spec/core/dsl_spec.rb +1 -1
  98. data/spec/core/item_spec.rb +1 -1
  99. data/spec/core/namespace_spec.rb +0 -11
  100. data/spec/core/recipe_spec.rb +54 -77
  101. data/spec/core/result_spec.rb +7 -0
  102. data/spec/core/runtime_spec.rb +20 -151
  103. data/spec/core/stack_spec.rb +7 -0
  104. data/spec/integration/simple_invalid_spec.rb +39 -0
  105. data/spec/integration/simple_valid_spec.rb +39 -0
  106. data/spec/items/atom_spec.rb +6 -1
  107. data/spec/items/document_spec.rb +93 -15
  108. data/spec/items/html_spec.rb +45 -28
  109. data/spec/items/json_spec.rb +10 -10
  110. data/spec/items/markdown_spec.rb +24 -3
  111. data/spec/items/nothing_spec.rb +1 -1
  112. data/spec/items/text_spec.rb +13 -41
  113. data/spec/items/time_spec.rb +25 -4
  114. data/spec/items/url_spec.rb +1 -7
  115. data/spec/items/xml_spec.rb +46 -39
  116. data/spec/spec_helper.rb +2 -21
  117. metadata +63 -60
  118. data/lib/lib/json_search.rb +0 -54
  119. data/spec/actions/run_recipe_and_save_spec.tmp.rb +0 -52
  120. data/spec/actions/run_recipe_spec.tmp.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e3837b908a7c2e26f770d28ba24bc8e5ceb5beb
4
- data.tar.gz: 1a442deae6a10374bab445b695f1d83597ce37f7
3
+ metadata.gz: 7aba132c13d3bc80c0034121a49cb2c45841a5c2
4
+ data.tar.gz: 12e4ca23e2d339a1951e2495f7791444160f3daa
5
5
  SHA512:
6
- metadata.gz: 55844e966392ebd596d8a62ace3a9fc70831ea7b60ebfb2df81fc7ddbaad2aacac9c431adc5ff4dbd504fbe7b951670780c2778395473111adbbda2ca9c3e3d5
7
- data.tar.gz: 3da6224447204cd0784d7abcc4806a68aa086ea89fe23401cde51eb3d5968b8b83a307be80ffcd4506979791b6c22f01cf99e1dc704a71c4b86c9e9c7623d884
6
+ metadata.gz: 0ff6858a582e44d4e61682a014e351d688d9b303870b516a897dd48c50ab66efddd42d3077d2cc87470da4cd4173faeefbc13f3375df214353ce1d17869d13f7
7
+ data.tar.gz: f8cc29550eaa47a9040fbebbf659dddd627b470dfbcd4d2a42998741d5d4aab187b2b49bcfe813279b2e3eff3989be4fdc0ccb36d47e5e3f9b0a63777cdd0414
data/README.md CHANGED
@@ -9,6 +9,9 @@ Common use scenarios:
9
9
  - create an RSS feed for a website or a web application
10
10
  - create an API for a website that doesn't have one
11
11
 
12
+ [![Gem Version](https://badge.fury.io/rb/saper.svg)](http://badge.fury.io/rb/saper)
13
+ [![Build Status](https://travis-ci.org/merimond/saper.svg?branch=master)](https://travis-ci.org/merimond/saper)
14
+
12
15
  ## Installing
13
16
 
14
17
  Make sure you have Ruby and RubyGems, then run:
data/Rakefile CHANGED
@@ -1,19 +1,19 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
- require 'rspec/core/rake_task'
3
+ require 'rake/testtask'
4
4
  require 'yard'
5
5
 
6
6
  Bundler.require
7
7
  Bundler::GemHelper.install_tasks
8
8
 
9
- desc "Run specs"
10
- RSpec::Core::RakeTask.new do |t|
11
- # nothing
9
+ desc "Run tests"
10
+ Rake::TestTask.new do |t|
11
+ t.test_files = FileList['spec/**/*_spec.rb']
12
12
  end
13
13
 
14
14
  desc "Generate docs"
15
15
  YARD::Rake::YardocTask.new do |t|
16
- t.files = ['lib/saper/**/*.rb']
16
+ t.files = ['lib/saper/**/*.rb']
17
17
  end
18
18
 
19
- task :default => :spec
19
+ task :default => :test
data/bin/saper CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "saper"
4
- require 'trollop'
3
+ require_relative "../lib/saper"
4
+ require "trollop"
5
5
 
6
6
  opts = Trollop::options do
7
7
  banner <<-EOS
@@ -10,51 +10,32 @@ Usage: saper <filename> [options]
10
10
 
11
11
  Options are ...
12
12
  EOS
13
- opt :input, "Recipe input", :type => :string
14
- opt :recipe, "Recipe name", :type => :string
13
+ opt :recipe, "Recipe name", :type => :string
14
+ opt :input, "Recipe input", :type => :string
15
+ opt :agent, "User-Agent", :type => :string
16
+ opt :keychain, "Keychain file", :type => :string
15
17
  end
16
18
 
17
- unless ARGV.size == 1
18
- Trollop::die "Please specify filename"
19
+ if opts[:recipe].nil?
20
+ Trollop::die "Recipe name missing"
19
21
  end
20
22
 
21
- path = File.expand_path(ARGV.first)
22
-
23
- unless File.exists?(path) && File.file?(path)
24
- Trollop::die("File not found")
23
+ unless ARGV.size == 1
24
+ Trollop::die "Please specify filename"
25
25
  end
26
26
 
27
27
  begin
28
- data = File.read(path)
29
- rescue
30
- Trollop::die("File cannot be read")
31
- end
32
-
33
- begin
34
- space = Saper::Namespace.parse(data)
28
+ puts Saper.run_from_file(ARGV.first, opts.delete(:recipe), opts.delete(:input), opts).serialize
29
+ rescue Errno::ENOENT => e
30
+ Trollop::die("File not found: %s" % ARGV.first)
35
31
  rescue NoMethodError => e
36
32
  Trollop::die("Invalid command: %s" % e.message.match(/`(\w+)'/)[1])
37
- end
38
-
39
- if opts[:recipe].nil?
40
- if space.run_by_default.nil?
41
- Trollop::die("Recipe name undefined")
42
- end
43
- opts[:recipe] = space.run_by_default
44
- end
45
-
46
- begin
47
- recipe = space[opts[:recipe]]
48
33
  rescue Saper::RecipeNotFound => e
49
- Trollop::die("`%s` recipe not found" % opts[:input])
34
+ Trollop::die("Recipe not found: %s" % opts[:input])
50
35
  rescue Saper::ActionNotFound => e
51
36
  Trollop::die("Invalid action: %s" % e.message)
52
37
  rescue Saper::InvalidArgument => e
53
- Trolltop::die("Invalid action argument")
54
- end
55
-
56
- if opts[:input].nil? && recipe.input_required?
57
- Trollop::die("No input specified, action requires %s" % recipe.input_required.inspect)
38
+ Trollop::die("Invalid action argument")
39
+ rescue Exception => e
40
+ puts e.backtrace
58
41
  end
59
-
60
- puts recipe.run(opts[:input]).results
@@ -1,37 +1,80 @@
1
1
  module Saper
2
2
 
3
- def self.require_multiple(dir)
4
- Dir[File.dirname(__FILE__) + "/" + dir].each { |file| require file }
5
- end
6
-
3
+ require 'bundler/setup'
7
4
  require 'reverse_markdown'
8
5
  require 'json'
9
6
  require 'vremya'
10
7
  require 'nokogiri'
11
8
  require 'securerandom'
12
9
  require 'mechanize'
10
+ require 'jpath'
13
11
 
14
- require_relative "lib/json_search"
15
- require_relative "lib/mechanize"
16
- require_relative "lib/nokogiri"
17
-
18
- require_relative "saper/version"
12
+ require_relative "saper/patches/mechanize"
13
+ require_relative "saper/patches/nokogiri"
19
14
  require_relative "saper/version"
20
- require_relative "saper/core/item"
21
- require_multiple "saper/items/*.rb"
22
- require_relative "saper/core/argument"
23
- require_multiple "saper/arguments/*.rb"
15
+
24
16
  require_relative "saper/core/action"
25
- require_multiple "saper/actions/*.rb"
26
- require_relative "saper/core/error"
27
- require_relative "saper/core/namespace"
28
- require_relative "saper/core/type"
29
- require_relative "saper/core/recipe"
17
+ require_relative "saper/core/argument"
18
+ require_relative "saper/core/browser"
19
+ require_relative "saper/core/dsl"
30
20
  require_relative "saper/core/error"
21
+ require_relative "saper/core/item"
31
22
  require_relative "saper/core/keychain"
32
- require_relative "saper/core/dsl"
33
- require_relative "saper/core/browser"
34
23
  require_relative "saper/core/logger"
24
+ require_relative "saper/core/namespace"
25
+ require_relative "saper/core/recipe"
26
+ require_relative "saper/core/result"
35
27
  require_relative "saper/core/runtime"
28
+ require_relative "saper/core/stack"
29
+ require_relative "saper/core/type"
30
+
31
+ require_relative "saper/arguments/attribute"
32
+ require_relative "saper/arguments/recipe"
33
+ require_relative "saper/arguments/service"
34
+ require_relative "saper/arguments/text"
35
+ require_relative "saper/arguments/timezone"
36
+ require_relative "saper/arguments/url"
37
+ require_relative "saper/arguments/variable"
38
+ require_relative "saper/arguments/xpath"
39
+
40
+ require_relative "saper/items/atom"
41
+ require_relative "saper/items/document"
42
+ require_relative "saper/items/html"
43
+ require_relative "saper/items/json"
44
+ require_relative "saper/items/markdown"
45
+ require_relative "saper/items/nothing"
46
+ require_relative "saper/items/text"
47
+ require_relative "saper/items/time"
48
+ require_relative "saper/items/url"
49
+ require_relative "saper/items/xml"
50
+
51
+ require_relative "saper/actions/append_with"
52
+ require_relative "saper/actions/convert_to_html"
53
+ require_relative "saper/actions/convert_to_json"
54
+ require_relative "saper/actions/convert_to_markdown"
55
+ require_relative "saper/actions/convert_to_time"
56
+ require_relative "saper/actions/convert_to_xml"
57
+ require_relative "saper/actions/create_atom"
58
+ require_relative "saper/actions/fetch"
59
+ require_relative "saper/actions/fetch_with_token"
60
+ require_relative "saper/actions/find"
61
+ require_relative "saper/actions/find_first"
62
+ require_relative "saper/actions/get_attribute"
63
+ require_relative "saper/actions/get_contents"
64
+ require_relative "saper/actions/get_text"
65
+ require_relative "saper/actions/nothing"
66
+ require_relative "saper/actions/prepend_with"
67
+ require_relative "saper/actions/remove_after"
68
+ require_relative "saper/actions/remove_before"
69
+ require_relative "saper/actions/remove_matching"
70
+ require_relative "saper/actions/remove_tags"
71
+ require_relative "saper/actions/replace"
72
+ require_relative "saper/actions/run_recipe"
73
+ require_relative "saper/actions/run_recipe_and_save"
74
+ require_relative "saper/actions/save"
75
+ require_relative "saper/actions/select_matching"
76
+ require_relative "saper/actions/set_input"
77
+ require_relative "saper/actions/skip_tags"
78
+ require_relative "saper/actions/split"
36
79
 
37
80
  end
@@ -5,7 +5,7 @@ module Saper
5
5
  argument :text
6
6
  accepts :text, :returns => :text
7
7
 
8
- run do |input, string|
8
+ run do |runtime, input, string|
9
9
  Items::Text.new "%s%s" % [input, string]
10
10
  end
11
11
 
@@ -5,7 +5,7 @@ module Saper
5
5
  accepts :text, :returns => :html
6
6
  accepts :document, :returns => :html
7
7
 
8
- run do |input|
8
+ run do |runtime, input|
9
9
  input.to_html
10
10
  end
11
11
 
@@ -5,8 +5,12 @@ module Saper
5
5
  accepts :text, :returns => :json
6
6
  accepts :document, :returns => :json
7
7
 
8
- run do |input|
9
- input.to_json
8
+ run do |runtime, input|
9
+ begin
10
+ input.to_json
11
+ rescue Saper::InvalidItem
12
+ nil
13
+ end
10
14
  end
11
15
 
12
16
  end
@@ -4,7 +4,7 @@ module Saper
4
4
 
5
5
  accepts :html, :returns => :markdown
6
6
 
7
- run do |input|
7
+ run do |runtime, input|
8
8
  input.to_markdown
9
9
  end
10
10
 
@@ -6,10 +6,47 @@ module Saper
6
6
  argument :text, :optional => true
7
7
  accepts :text, :returns => :time
8
8
 
9
- run do |input, format, tz|
9
+ run do |runtime, input, format, tz|
10
+ tz = nil if tz && tz.empty?
10
11
  input.to_time(format, tz)
11
12
  end
12
13
 
14
+ # Format elements
15
+ # %Y - Year with century (can be negative, 4 digits at least)
16
+ # %C - year / 100 (round down. 20 in 2009)
17
+ # %y - year % 100 (00..99)
18
+ # %m - Month of the year, zero-padded (01..12)
19
+ # %-m - Month of the year, no-padded (1..12)
20
+ # %B - The full month name (``January'')
21
+ # %^B - Month name uppercased (``JANUARY'')
22
+ # %b - Abbreviated month name (``Jan'')
23
+ # %^b - Abbreviated uppercased month (``JAN'')
24
+ # %d - Day of the month, zero-padded (01..31)
25
+ # %-d - Day of the month, no-padded (1..31)
26
+ # %e - Day of the month, blank-padded ( 1..31)
27
+ # %j - Day of the year (001..366)
28
+ # %H - Hour of the day, 24-hour clock, zero-padded (00..23)
29
+ # %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
30
+ # %I - Hour of the day, 12-hour clock, zero-padded (01..12)
31
+ # %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
32
+ # %P - Meridian indicator, lowercase (``am'' or ``pm'')
33
+ # %p - Meridian indicator, uppercase (``AM'' or ``PM'')
34
+ # %M - Minute of the hour (00..59)
35
+ # %S - Second of the minute (00..59)
36
+ # %L - Millisecond of the second (000..999)
37
+ # %N - Fractional seconds digits, default is 9 digits (nanosecond)
38
+ # %z - Time zone as hour and minute offset from UTC (e.g. +0900)
39
+ # %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
40
+ # %Z - Time zone abbreviation name
41
+ # %A - The full weekday name (``Sunday'')
42
+ # %^A - Weekday, uppercased (``SUNDAY'')
43
+ # %a - Weekday, abbreviated (``Sun'')
44
+ # %^a - Weekday, uppercased (``SUN'')
45
+ # %u - Day of the week (Monday is 1, 1..7)
46
+ # %w - Day of the week (Sunday is 0, 0..6)
47
+ # %s - Number of seconds since 1970-01-01 00:00:00 UTC.
48
+ # %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.
49
+
13
50
  end
14
51
  end
15
52
  end
@@ -5,7 +5,7 @@ module Saper
5
5
  accepts :text, :returns => :xml
6
6
  accepts :document, :returns => :xml
7
7
 
8
- run do |input|
8
+ run do |runtime, input|
9
9
  input.to_xml
10
10
  end
11
11
 
@@ -4,8 +4,12 @@ module Saper
4
4
 
5
5
  accepts :anything, :returns => :atom
6
6
 
7
- run do |input|
8
- Items::Atom.new(variables)
7
+ run do |runtime, input|
8
+ if runtime.is_a?(Runtime)
9
+ Items::Atom.new(runtime.variables)
10
+ else
11
+ raise RuntimeMissing
12
+ end
9
13
  end
10
14
 
11
15
  # Overrides default logic
@@ -2,11 +2,12 @@ module Saper
2
2
  module Actions
3
3
  class Fetch < Action
4
4
 
5
+ accepts :text, :returns => :document
5
6
  accepts :url, :returns => :document
6
7
 
7
- run do |input|
8
+ run do |runtime, input|
8
9
  begin
9
- browser.get(input)
10
+ runtime.browser.get(input)
10
11
  rescue SocketError
11
12
  raise(UnreachableURL, input)
12
13
  end
@@ -0,0 +1,18 @@
1
+ module Saper
2
+ module Actions
3
+ class FetchWithToken < Action
4
+
5
+ argument :url
6
+ argument :service
7
+
8
+ run do |runtime, input, url, service|
9
+ begin
10
+ runtime.browser.post_with_bearer_token(url, input.to_native.to_s, runtime.keychain.token(service))
11
+ rescue SocketError
12
+ raise(UnreachableURL, input)
13
+ end
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -9,7 +9,7 @@ module Saper
9
9
  accepts :xml, :returns => :xml
10
10
  accepts :json, :returns => :json
11
11
 
12
- run do |input, xpath|
12
+ run do |runtime, input, xpath|
13
13
  input.find_all(xpath)
14
14
  end
15
15
 
@@ -7,7 +7,7 @@ module Saper
7
7
  accepts :xml, :returns => :xml
8
8
  accepts :json, :returns => :json
9
9
 
10
- run do |input, xpath|
10
+ run do |runtime, input, xpath|
11
11
  input.find(xpath)
12
12
  end
13
13
 
@@ -6,8 +6,13 @@ module Saper
6
6
  accepts :xml, :returns => :text
7
7
  accepts :html, :returns => :text
8
8
 
9
- run do |input, name|
10
- input[name]
9
+ run do |runtime, input, name|
10
+ value = input[name]
11
+ if value.nil?
12
+ Items::Nothing.new
13
+ else
14
+ Items::Text.new value
15
+ end
11
16
  end
12
17
 
13
18
  end
@@ -5,7 +5,7 @@ module Saper
5
5
  accepts :xml, :returns => :text
6
6
  accepts :html, :returns => :text
7
7
 
8
- run do |input|
8
+ run do |runtime, input|
9
9
  input.inner_html
10
10
  end
11
11
 
@@ -5,7 +5,7 @@ module Saper
5
5
  accepts :xml, :returns => :text
6
6
  accepts :html, :returns => :text
7
7
 
8
- run do |input|
8
+ run do |runtime, input|
9
9
  input.inner_text
10
10
  end
11
11
 
@@ -0,0 +1,11 @@
1
+ module Saper
2
+ module Actions
3
+ class Nothing < Action
4
+
5
+ run do |runtime, input|
6
+ input
7
+ end
8
+
9
+ end
10
+ end
11
+ end