summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--ext/psych/lib/psych/handler.rb13
-rw-r--r--ext/psych/lib/psych/handlers/recorder.rb39
-rw-r--r--test/psych/handlers/test_recorder.rb25
4 files changed, 87 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 5ce5bcbf14b..77320834763 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Mon Oct 29 10:22:00 2012 Aaron Patterson <aaron@tenderlovemaking.com>
+
+ * ext/psych/lib/psych/handlers/recorder.rb: added a class for
+ recording YAML parse and emit events.
+
+ * ext/psych/lib/psych/handler.rb: adding a list of events so that
+ handler classes can more easily be meta-programmed.
+
+ * test/psych/handlers/test_recorder.rb: tests for the change.
+
Mon Oct 29 05:48:52 2012 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
* lib/ostruct.rb: Add [] and []=, base on a patch by Thomas Sawyer.
diff --git a/ext/psych/lib/psych/handler.rb b/ext/psych/lib/psych/handler.rb
index d3b99636c4f..c55afe745f7 100644
--- a/ext/psych/lib/psych/handler.rb
+++ b/ext/psych/lib/psych/handler.rb
@@ -25,6 +25,19 @@ module Psych
# Default dumping options
OPTIONS = DumperOptions.new
+ # Events that a Handler should respond to.
+ EVENTS = [ :alias,
+ :empty,
+ :end_document,
+ :end_mapping,
+ :end_sequence,
+ :end_stream,
+ :scalar,
+ :start_document,
+ :start_mapping,
+ :start_sequence,
+ :start_stream ]
+
###
# Called with +encoding+ when the YAML stream starts. This method is
# called once per stream. A stream may contain multiple documents.
diff --git a/ext/psych/lib/psych/handlers/recorder.rb b/ext/psych/lib/psych/handlers/recorder.rb
new file mode 100644
index 00000000000..4eae62e5f93
--- /dev/null
+++ b/ext/psych/lib/psych/handlers/recorder.rb
@@ -0,0 +1,39 @@
+require 'psych/handler'
+
+module Psych
+ module Handlers
+ ###
+ # This handler will capture an event and record the event. Recorder events
+ # are available vial Psych::Handlers::Recorder#events.
+ #
+ # For example:
+ #
+ # recorder = Psych::Handlers::Recorder.new
+ # parser = Psych::Parser.new recorder
+ # parser.parse '--- foo'
+ #
+ # recorder.events # => [list of events]
+ #
+ # # Replay the events
+ #
+ # emitter = Psych::Emitter.new $stdout
+ # recorder.events.each do |m, args|
+ # emitter.send m, *args
+ # end
+
+ class Recorder < Psych::Handler
+ attr_reader :events
+
+ def initialize
+ @events = []
+ super
+ end
+
+ EVENTS.each do |event|
+ define_method event do |*args|
+ @events << [event, args]
+ end
+ end
+ end
+ end
+end
diff --git a/test/psych/handlers/test_recorder.rb b/test/psych/handlers/test_recorder.rb
new file mode 100644
index 00000000000..96b8eac1fc6
--- /dev/null
+++ b/test/psych/handlers/test_recorder.rb
@@ -0,0 +1,25 @@
+require 'psych/helper'
+require 'psych/handlers/recorder'
+
+module Psych
+ module Handlers
+ class TestRecorder < TestCase
+ def test_replay
+ yaml = "--- foo\n...\n"
+ output = StringIO.new
+
+ recorder = Psych::Handlers::Recorder.new
+ parser = Psych::Parser.new recorder
+ parser.parse yaml
+
+ assert_equal 5, recorder.events.length
+
+ emitter = Psych::Emitter.new output
+ recorder.events.each do |m, args|
+ emitter.send m, *args
+ end
+ assert_equal yaml, output.string
+ end
+ end
+ end
+end