keating / think-aloud-microblog

sample_app
sample_app
0 stars 0 forks source link

test #1

Open keating opened 12 years ago

keating commented 12 years ago
require 'digest/md5'

def gfm(text)
  # Extract pre blocks
  extractions = {}
  text.gsub!(%r{<pre>.*?</pre>}m) do |match|
    md5 = Digest::MD5.hexdigest(match)
    extractions[md5] = match
    "{gfm-extraction-#{md5}}"
  end

  # prevent foo_bar_baz from ending up with an italic word in the middle
  text.gsub!(/(^(?! {4}|\t)\w+_\w+_\w[\w_]*)/) do |x|
    x.gsub('_', '\_') if x.split('').sort.to_s[0..1] == '__'
  end

  # in very clear cases, let newlines become <br /> tags
  text.gsub!(/^[\w\<][^\n]*\n+/) do |x|
    x =~ /\n{2}/ ? x : (x.strip!; x << "  \n")
  end

  # Insert pre block extractions
  text.gsub!(/\{gfm-extraction-([0-9a-f]{32})\}/) do
    "\n\n" + extractions[$1]
  end

  text
end

if $0 == __FILE__
  require 'test/unit'
  require 'shoulda'

  class GFMTest < Test::Unit::TestCase
    context "GFM" do
      should "not touch single underscores inside words" do
        assert_equal "foo_bar", gfm("foo_bar")
      end

      should "not touch underscores in code blocks" do
        assert_equal "    foo_bar_baz", gfm("    foo_bar_baz")
      end

      should "not touch underscores in pre blocks" do
        assert_equal "\n\n<pre>\nfoo_bar_baz\n</pre>", gfm("<pre>\nfoo_bar_baz\n</pre>")
      end

      should "not treat pre blocks with pre-text differently" do
        a = "\n\n<pre>\nthis is `a\\_test` and this\\_too\n</pre>"
        b = "hmm<pre>\nthis is `a\\_test` and this\\_too\n</pre>"
        assert_equal gfm(a)[2..-1], gfm(b)[3..-1]
      end

      should "escape two or more underscores inside words" do
        assert_equal "foo\\_bar\\_baz", gfm("foo_bar_baz")
      end

      should "turn newlines into br tags in simple cases" do
        assert_equal "foo  \nbar", gfm("foo\nbar")
      end

      should "convert newlines in all groups" do
        assert_equal "apple  \npear  \norange\n\nruby  \npython  \nerlang",
                     gfm("apple\npear\norange\n\nruby\npython\nerlang")
      end

      should "convert newlines in even long groups" do
        assert_equal "apple  \npear  \norange  \nbanana\n\nruby  \npython  \nerlang",
                     gfm("apple\npear\norange\nbanana\n\nruby\npython\nerlang")
      end

      should "not convert newlines in lists" do
        assert_equal "# foo\n# bar", gfm("# foo\n# bar")
        assert_equal "* foo\n* bar", gfm("* foo\n* bar")
      end
    end
  end
end

aaaaaaaaaa

keating commented 12 years ago
u = User.new(:name => "jiwen")

begin
  User.transaction do
    u.save
    u.save
    raise "exception"
  end
rescue
end

u.instance_eval { puts @new_record }

I get the output "false" in the above code. This is a problem. For example, when I create an object in the new page, save the object and then update some attributes with the above code, I will be token to be the edit page. So an error happens, for "cannot find record with the object's id in the database". I see the code in the transaction file,

def remember_transaction_record_state
    @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
    @_start_transaction_state[:new_record] = @new_record
    @_start_transaction_state[:destroyed] = @destroyed
    @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
end

So, to resolve this problem, just need to change this method to

def remember_transaction_record_state
    @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
    unless @_start_transaction_state.include?(:new_record)
      @_start_transaction_state[:new_record] = @new_record
    end
    unless @_start_transaction_state.include?(:destroyed)
      @_start_transaction_state[:destroyed] = @destroyed
    end
    @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
end

But see this commit, * SHA: 44d1804b0a86de02865c48c552bbc57da3dc7836 which just do the opposite thing for "Fix transaction state not changing when after record gets commited", so this approach is not comfortable to resolve the problem. I think there maybe need a 'state_before_transaction' to record the sate of an object before the transaction and which should be restore to when the transaction roll back.