# -*- encoding : utf-8 -*- require 'card/content' EXAMPLES = { :nests => { :content => [ "Some Literals: \\[{I'm not| a link]}, and ", "\\{{This Card|Is not Included}}", ", but ", "{{this is}}", ", and some tail" ].join(''), :rendered => [ "Some Literals: \\[{I'm not| a link]}, and ", "{{This Card|Is not Included}}", ", but ", {:options => {:inc_name=>"this is",:inc_syntax=>"this is"}}, ", and some tail" ], :classes => [String, :EscapedLiteral, String, :Include, String ] }, :links_and_nests => { :content => %(Some Links and includes: [[the card|the text]], and {{This Card|Is Included}}{{this too}} and [[http://external.wagn.org/path|link text]]{{Included|open}}), :rendered => [ "Some Links and includes: ", "the text", ", and ", { :options => { :view => "Is Included", :inc_name=>"This Card", :inc_syntax => "This Card|Is Included"}}, { :options => { :inc_name=>"this too", :inc_syntax=>"this too"}}, "\n and ", "link text", { :options => { :view=>"open", :inc_name=>"Included", :inc_syntax=>"Included|open" }} ], :classes => [String, :Link, String, :Include, :Include, String, :Link, :Include ] }, :uris_and_links => { :content => %(Some URIs and Links: http://a.url.com/ More urls: wagn.com/a/path/to.html http://localhost:2020/path?cgi=foo&bar=baz [[http://brain.org/Home|extra]] [ http://gerry.wagn.com/a/path ] { https://brain.org/more?args }), :rendered => [ "Some URIs and Links: ", 'http://a.url.com/', "\n More urls: ", "wagn.com/a/path/to.html", "\n ", "http://localhost:2020/path?cgi=foo&bar=baz", " ", "extra", "\n [ ", "http://gerry.wagn.com/a/path", " ]\n { ", "https://brain.org/more?args", " }" ], :text_rendered => [ "Some URIs and Links: ", 'http://a.url.com/', "\n More urls: ", "wagn.com/a/path/to.html[http://wagn.com/a/path/to.html]", "\n ", "http://localhost:2020/path?cgi=foo&bar=baz", " ", "extra[http://brain.org/Home]", "\n [ ", "http://gerry.wagn.com/a/path", " ]\n { ", "https://brain.org/more?args", " }" ], :classes => [String, :URI, String, :HostURI, String, :URI, String, :Link, String, :URI, String, :URI, String ] }, :uris_and_links_2 => { :content => %(Some URIs and Links: http://a.url.com More urls: wagn.com/a/path/to.html [ http://gerry.wagn.com/a/path ] { https://brain.org/more?args } http://localhost:2020/path?cgi=foo&bar=baz [[http://brain.org/Home|extra]]), :rendered => [ "Some URIs and Links: ","http://a.url.com", "\n More urls: ", "wagn.com/a/path/to.html", "\n [ ", "http://gerry.wagn.com/a/path", " ]\n { ", "https://brain.org/more?args", " }\n ", "http://localhost:2020/path?cgi=foo&bar=baz", " ", "extra" ], :classes => [String, :URI, String, :HostURI, String, :URI, String, :URI, String, :URI, String, :Link ] }, :no_chunks => { :content => "No chunks", :rendered => "No chunks" }, :single_nest => { :content => "{{one inclusion|size;large}}", :classes => [:Include] }, :css => { :content => %~ /* body text */ body { color: #444444; } /* page - background image and color */ body#wagn { background: #ffffff; } /* top bar background color; text colors */ #menu { background: #3260a0; } #menu a { color: #EEEEEE; } /* header text */ h1, h2 { color: #664444; } h1.page-header, h2.page-header { color: #222299; } ~ } } EXAMPLES.each do |key, val| if val[:classes] val[:classes] = val[:classes].map do |klass| Class === klass ? klass : Card::Chunk.const_get(klass) end end end describe Card::Content do context "instance" do before do @check_proc = Proc.new do |m, v| if Array===m wrong_class = m[0] != v.class is_last = m.size == 1 #warn "check M[#{is_last}]:#{wrong_class}, #{m[0]}, V#{v.inspect}" if wrong_class || is_last expect(wrong_class).to be_falsey wrong_class ? false : ( is_last ? true : m[1..-1] ) else false end end assert card = Card["One"] @card = card # non-nil valued opts only ... @render_block = Proc.new do |opts| {:options => opts.inject({}) {|i,v| !v[1].nil? && i[v[0]]=v[1]; i } } end end let(:example) { EXAMPLES[@example] } let(:cobj) { Card::Content.new example[:content], @card } let(:classes) { example[:classes] } let(:rendered) { example[:rendered] } let(:text_rendered) { example[:text_rendered] } let(:content) { example[:content] } describe 'parse' do def check_chunk_classes expect(cobj.inject(classes, &@check_proc)).to eq(true) clist = classes.find_all {|c| String != c } cobj.each_chunk do |chk| expect(chk).to be_instance_of clist.shift end expect(clist).to be_empty end it "finds all the chunks and strings" do # note the mixed [} that are considered matching, needs some cleanup ... @example = :nests expect(cobj.inject(classes, &@check_proc)).to eq(true) end it "gives just the chunks" do @example = :nests check_chunk_classes end it "finds all the chunks links and trasclusions" do @example = :links_and_nests expect(cobj.inject(classes, &@check_proc)).to eq(true) end it "finds uri chunks " do # tried some tougher cases that failed, don't know the spec, so hard to form better tests for URIs here @example = :uris_and_links check_chunk_classes end it "finds uri chunks (b)" do # tried some tougher cases that failed, don't know the spec, so hard to form better tests for URIs here @example = :uris_and_links_2 check_chunk_classes end it "parses just a string" do @example = :no_chunks expect(cobj).to eq(rendered) end it "parses a single chunk" do @example = :single_nest check_chunk_classes end it "leaves css alone" do @example = :css expect(cobj).to eq(content) end end describe "render" do it "renders all nests" do @example = :nests expect(cobj.as_json.to_s).to match /not rendered/ cobj.process_content_object &@render_block expect(rdr=cobj.as_json.to_json).not_to match /not rendered/ expect(rdr).to eq(rendered.to_json) end it "renders links and nests" do @example = :links_and_nests cobj.process_content_object &@render_block expect(rdr=cobj.as_json.to_json).not_to match /not rendered/ expect(rdr).to eq(rendered.to_json) end it "renders links correctly for text formatters" do @example = :uris_and_links card2 = Card[@card.id] format = card2.format :format => :text cobj = Card::Content.new content, format cobj.process_content_object &@render_block expect(cobj.as_json.to_json).to eq(text_rendered.to_json) end it "does not need rendering if no nests" do @example = :uris_and_links cobj.process_content_object &@render_block expect(cobj.as_json.to_json).to eq(rendered.to_json) end it "does not need rendering if no nests (b)" do @example = :uris_and_links_2 expect(rdr=cobj.as_json.to_json).to match /not rendered/ # links are rendered too, but not with a block cobj.process_content_object &@render_block expect(rdr=cobj.as_json.to_json).not_to match /not rendered/ expect(rdr).to eq(rendered.to_json) end end end UNTAGGED_CASES = [ ' [grrew][/wiki/grrew]ss ', ' {{this is a test}}, {{this|view|is:too}} and', ' so is http://foo.bar.come//', ' and foo="my attr, not int a tag" and more' ] context "class" do describe '#clean!' do it 'should not alter untagged content' do UNTAGGED_CASES.each do |test_case| assert_equal test_case,Card::Content.clean!(test_case) end end it 'should strip disallowed html class attributes' do assert_equal '

html

with
funky tags

', Card::Content.clean!('

html

with
funkytags

') assert_equal 'foo', Card::Content.clean!('foo') end it 'should not strip permitted_classes' do assert_equal 'foo', Card::Content.clean!('foo') assert_equal '

foo

', Card::Content.clean!('

foo

') end it 'should strip permitted_classes but not permitted ones when both are present' do assert_equal "foo", Card::Content.clean!("foo") assert_equal '

foo

', Card::Content.clean!('

foo

') assert_equal '

foo

', Card::Content.clean!('

foo

') end it 'should allow permitted attributes' do assert_equal '', Card::Content.clean!('') assert_equal "foo", Card::Content.clean!("foo") assert_equal '', Card::Content.clean!('') assert_equal '', Card::Content.clean!('') assert_equal '', Card::Content.clean!('') assert_equal '
', Card::Content.clean!('
') end it 'should not allow nonpermitted attributes' do assert_equal '', Card::Content.clean!('') assert_equal '

', Card::Content.clean!('

') end it 'should remove comments' do assert_equal 'yo', Card::Content.clean!('yo') assert_equal 'joe', Card::Content.clean!('joe') end it 'fixes regular nbsp order by default' do assert_equal 'space  test  two   space', Card::Content.clean!('space  test  two   space') end it 'doesn\'t fix regular nbsp order with setting' do # manually configure this setting, then make this one live (test above will then fail) pending "Can't set Card.config.space_last_in_multispace= false for one test" assert_equal 'space  test  two   space', Card::Content.clean!('space  test  two   space') end end end end