// ========================================================================== // Project: SproutCore - JavaScript Application Framework // Copyright: ©2006-2009 Sprout Systems, Inc. and contributors. // Portions ©2008-2009 Apple, Inc. All rights reserved. // License: Licened under MIT license (see license.js) // ========================================================================== /*global module test equals context ok */ var context = null; module("SC.RenderContext#end", { setup: function() { context = SC.RenderContext(); } }); test("should replace opening tag with string and add closing tag, leaving middle content in place", function() { context.push("line1").end(); equals(context.get(0), "<div>", "opening tag"); equals(context.get(1), "line1", "opening tag"); equals(context.get(2), "</div>", "closing tag"); }); test("should emit any CSS class names included in the tag opts.classNames array", function() { context.classNames("foo bar".w()).end(); ok(context.get(0).match(/class=\"foo bar\"/), '<div> has class attr') ; }); test("should emit id in tag opts.id", function() { context.id("foo").end(); ok(context.get(0).match(/id=\"foo\"/), "<div> has id attr"); }); test("should emit style in tag if opts.styles is defined", function() { context.styles({ alpha: "beta", foo: "bar" }).end(); ok(context.get(0).match(/style=\"alpha: beta; foo: bar\"/), '<div> has style="alpha: beta; foo: bar"'); }); test("should write arbitrary attrs has in opts", function() { context.attr({ foo: "bar", bar: "baz" }).end(); ok(context.get(0).match(/foo=\"bar\"/), 'has foo="bar"'); ok(context.get(0).match(/bar=\"baz\"/), 'has bar="baz"'); }); test("classNames should override attrs.class", function() { context.classNames("foo".w()).attr({ "class": "bar" }).end(); ok(context.get(0).match(/class=\"foo\"/), 'has class="foo"'); }); test("opts.id should override opts.attrs.id", function() { context.id("foo").attr({ id: "bar" }).end(); ok(context.get(0).match(/id=\"foo\"/), 'has id="foo"'); }); test("opts.styles should override opts.attrs.style", function() { context.styles({ foo: "foo" }).attr({ style: "bar: bar" }).end(); ok(context.get(0).match(/style=\"foo: foo\"/), 'has style="foo: foo"'); }); test("should return receiver if receiver has no prevObject", function() { ok(!context.prevObject, 'precondition - prevObject is null'); equals(context.end(), context, 'ends as self'); }); test("should return prevObject if receiver has prevObject", function() { var c2 = context.begin(); equals(c2.end(), context, "should return prevObject"); }); test("emits self closing tag if tag has no content and c._selfClosing !== NO", function() { var c2 = context.begin('input'); c2.end(); equals(c2.get(0), "<input />"); }); test("emits two tags even if tag has no content if opts.selfClosing == NO", function() { context._selfClosing = NO; context.end(); equals(context.length, 2, "has two lines"); equals(context.get(0), "<div>", "has opening tag"); equals(context.get(1), "</div>", "has closing tag"); }); test("does NOT emit self closing tag if it has content, even if opts.selfClosing == YES (because that would yield invalid HTML)", function() { context._selfClosing = YES; context.push("line").end(); equals(context.length, 3, "has 3 lines"); equals(context.get(2), "</div>", "has closing tag"); }); test("it should make sure to clear reused temporary attributes object", function() { // generate one tag... context.begin('input') .id("foo") .styles({ foo: "bar" }) .classNames("foo bar".w()) .push("line") .end(); // generate second tag...will reuse internal temporary attrs object. context.begin('input').id("bar").end(); var str = context.get(context.length-1); equals(str, "<input id=\"bar\" />"); }); test("it should work when nested more than one level deep", function() { context.begin().id("foo") .begin().id("bar").end() .end(); var str = context.join(''); ok(str.match(/id="foo"/), 'has foo'); ok(str.match(/id="bar"/), 'has bar'); });