aboutsummaryrefslogtreecommitdiffstats
path: root/test/CompilerSpec.js
blob: 9922070f0d46817710d8b2b1f806a97614d3982d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
describe('compiler', function(){
  var compiler, textMarkup, directives, widgets, compile, log;

  beforeEach(function(){
    log = "";
    directives = {
      hello: function(expression, element){
        log += "hello ";
        return function() {
          log += expression;
        };
      },

      watch: function(expression, element){
        return function() {
          this.$watch(expression, function(val){
            log += ":" + val;
          });
        };
      }

    };
    textMarkup = [];
    attrMarkup = [];
    widgets = {};
    compiler = new Compiler(textMarkup, attrMarkup, directives, widgets);
    compile = function(html){
      var e = jqLite("<div>" + html + "</div>");
      var scope = compiler.compile(e)(e);
      scope.$init();
      return scope;
    };
  });

  it('should recognize a directive', function(){
    var e = jqLite('<div directive="expr" ignore="me"></div>');
    directives.directive = function(expression, element){
      log += "found";
      expect(expression).toEqual("expr");
      expect(element).toEqual(e);
      return function initFn() {
        log += ":init";
      };
    };
    var template = compiler.compile(e);
    var init = template(e).$init;
    expect(log).toEqual("found");
    init();
    expect(log).toEqual("found:init");
  });

  it('should recurse to children', function(){
    var scope = compile('<div><span hello="misko"/></div>');
    expect(log).toEqual("hello misko");
  });

  it('should watch scope', function(){
    var scope = compile('<span watch="name"/>');
    expect(log).toEqual("");
    scope.$eval();
    scope.$set('name', 'misko');
    scope.$eval();
    scope.$eval();
    scope.$set('name', 'adam');
    scope.$eval();
    scope.$eval();
    expect(log).toEqual(":misko:adam");
  });

  it('should prevent descend', function(){
    directives.stop = function(){ this.descend(false); };
    var scope = compile('<span hello="misko" stop="true"><span hello="adam"/></span>');
    expect(log).toEqual("hello misko");
  });

  it('should allow creation of templates', function(){
    directives.duplicate = function(expr, element){
      element.replaceWith(document.createComment("marker"));
      element.removeAttr("duplicate");
      var template = this.compile(element);
      return function(marker) {
        this.$onEval(function() {
          marker.after(template(element.clone()).element);
        });
      };
    };
    var scope = compile('before<span duplicate="expr">x</span>after');
    expect(sortedHtml(scope.$element)).toEqual('<div>before<#comment></#comment>after</div>');
    scope.$eval();
    expect(sortedHtml(scope.$element)).toEqual('<div>before<#comment></#comment>after</div>');
    scope.$eval();
    expect(sortedHtml(scope.$element)).toEqual('<div>before<#comment></#comment>after</div>');
  });

  it('should process markup before directives', function(){
    textMarkup.push(function(text, textNode, parentNode) {
      if (text == 'middle') {
        expect(textNode.text()).toEqual(text);
        parentNode.attr('hello', text);
        textNode.text('replaced');
      }
    });
    var scope = compile('before<span>middle</span>after');
    expect(scope.$element[0].innerHTML).toEqual('before<span hello="middle">replaced</span>after');
    expect(log).toEqual("hello middle");
  });

  it('should replace widgets', function(){
    widgets['NG:BUTTON'] = function(element) {
      element.replaceWith('<div>button</div>', element);
      return function(element) {
        log += 'init';
      };
    };
    var scope = compile('<ng:button>push me</ng:button>');
    expect(scope.$element[0].innerHTML).toEqual('<div>button</div>');
    expect(log).toEqual('init');
  });

});