commit db1aa1429d96745b8a0c5f030a2170d71f8dfd86
parent 98d82009ec97951bfc55b6c5a1cc5785353bda49
Author: Whyme Lyu <callme5long@gmail.com>
Date: Tue, 28 May 2013 23:10:35 +0800
Support loading legacy YAML for now.
Diffstat:
3 files changed, 101 insertions(+), 8 deletions(-)
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -22,17 +22,29 @@ end
class Module
def yaml_properties *props
props = props.map { |p| p.to_s }
- vars = props.map { |p| "@#{p}" }
klass = self
- path = klass.name.gsub(/::/, "/")
klass.instance_eval do
- define_method(:to_yaml_properties) { vars }
- define_method(:to_yaml_type) { "!#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}" }
- end
+ def self.to_yaml_tag
+ path = name.gsub(/::/, "/")
+ "!#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}"
+ end
+
+ define_method(:to_yaml_type) { self.class.to_yaml_tag }
+ define_method :init_with do |coder|
+ initialize(*coder.map.values_at(*props))
+ end
+
+ define_method :encode_with do |coder|
+ coder.map = props.inject({}) do |hash, key|
+ hash[key] = instance_variable_get("@#{key}")
+ hash
+ end
+ end
- YAML.add_domain_type("#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}", path) do |type, val|
- klass.new(*props.map { |p| val[p] })
+ yaml_tag to_yaml_tag
+ path = name.gsub(/::/, "/")
+ Psych.load_tags["!#{Redwood::LEGACY_YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}"] = self
end
end
end
@@ -53,6 +65,7 @@ module Redwood
LOG_FN = File.join(BASE_DIR, "log")
YAML_DOMAIN = "supmua.org"
+ LEGACY_YAML_DOMAIN = "masanjin.net"
YAML_DATE = "2006-10-01"
## record exceptions thrown in threads nicely
diff --git a/lib/sup/modes/inbox_mode.rb b/lib/sup/modes/inbox_mode.rb
@@ -1,4 +1,4 @@
-require 'sup'
+require "sup/modes/thread_index_mode"
module Redwood
diff --git a/test/test_yaml_migration.rb b/test/test_yaml_migration.rb
@@ -0,0 +1,80 @@
+require "test_helper"
+
+require "sup"
+require "psych"
+
+describe "Sup's YAML util" do
+ describe "Module#yaml_properties" do
+ def build_class_with_name name, &b
+ Class.new do
+ meta_cls = class << self; self; end
+ meta_cls.send(:define_method, :name) { name }
+ class_exec(&b) unless b.nil?
+ end
+ end
+
+ after do
+ Psych.load_tags = {}
+ Psych.dump_tags = {}
+ end
+
+ it "defines YAML tag for class" do
+ cls = build_class_with_name 'Cls' do
+ yaml_properties
+ end
+
+ expected_yaml_tag = "!supmua.org,2006-10-01/Cls"
+
+ Psych.load_tags[expected_yaml_tag].must_equal cls
+ Psych.dump_tags[cls].must_equal expected_yaml_tag
+
+ end
+
+ it "Loads legacy YAML format as well" do
+ cls = build_class_with_name 'Cls' do
+ yaml_properties :id
+ attr_accessor :id
+ def initialize id
+ @id = id
+ end
+ end
+
+ Psych.load_tags["!masanjin.net,2006-10-01/Cls"].must_equal cls
+
+ yaml = <<EOF
+--- !masanjin.net,2006-10-01/Cls
+id: ID
+EOF
+ loaded = YAML.load(yaml)
+
+ loaded.id.must_equal 'ID'
+ loaded.must_be_kind_of cls
+ end
+
+ it "Dumps & loads w/ state re-initialized" do
+ cls = build_class_with_name 'Cls' do
+ yaml_properties :id
+ attr_accessor :id
+ attr_reader :flag
+
+ def initialize id
+ @id = id
+ @flag = true
+ end
+ end
+
+ instance = cls.new 'ID'
+
+ dumped = YAML.dump(instance)
+ loaded = YAML.load(dumped)
+
+ dumped.must_equal <<-EOF
+--- !supmua.org,2006-10-01/Cls
+id: ID
+ EOF
+
+ loaded.id.must_equal 'ID'
+ assert loaded.flag
+ end
+ end
+end