├── .gitignore
├── .jshintrc
├── .travis.yml
├── Gruntfile.js
├── LICENSE-MIT
├── README.md
├── package-lock.json
├── package.json
├── tasks
└── htmlangular.js
└── test
├── html
├── invalid
│ ├── improperly_closed_tag.tmpl.html
│ ├── improperly_nested_tags.tmpl.html
│ ├── missing_closing_tag.tmpl.html
│ └── template_missing_extension.html
└── valid
│ ├── full
│ ├── valid_angular.html
│ ├── valid_angular_directives.html
│ └── valid_regular.html
│ └── template
│ ├── valid_angular.tmpl.html
│ ├── valid_angular_table_row.tmpl.html
│ └── valid_regular.tmpl.html
└── htmlangular_test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | tmp
4 | html-angular-validate-report.json
5 | html-angular-validate-report-checkstyle.xml
6 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "curly": true,
3 | "eqeqeq": true,
4 | "immed": true,
5 | "indent": 4,
6 | "latedef": true,
7 | "newcap": true,
8 | "noarg": true,
9 | "plusplus": true,
10 | "sub": true,
11 | "undef": true,
12 | "boss": true,
13 | "eqnull": true,
14 | "node": true
15 | }
16 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | node_js:
4 | - "9"
5 | - "8"
6 | - "7"
7 | - "6"
8 | - "5"
9 |
10 | branches:
11 | only:
12 | - master
13 |
14 | before_script:
15 | - npm install -g grunt-cli
16 | - grunt jshint
17 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /*
2 | * grunt-html-angular-validate
3 | * https://github.com/nikestep/grunt-html-angular-validate
4 | *
5 | * Copyright (c) 2014 Nik Estep
6 | * Licensed under the MIT license.
7 | */
8 |
9 | 'use strict';
10 |
11 | module.exports = function(grunt) {
12 |
13 | // Project configuration.
14 | grunt.initConfig({
15 | jshint: {
16 | all: [
17 | 'Gruntfile.js',
18 | 'tasks/*.js',
19 | '<%= nodeunit.all %>',
20 | ],
21 | options: {
22 | jshintrc: '.jshintrc',
23 | },
24 | },
25 |
26 | // Before generating any new files, remove any previously-created files.
27 | clean: {
28 | tests: ['tmp'],
29 | },
30 |
31 | // Configurations to be run (and then tested).
32 | htmlangular: {
33 | default_options: {
34 | options: {
35 | customtags: ['custom-tag', 'custom-*'],
36 | customattrs: ['fixed-div-label', 'custom-*'],
37 | wrapping: {
38 | 'tr': '
2 |
3 | Some content.
4 |
--------------------------------------------------------------------------------
/test/html/invalid/template_missing_extension.html:
--------------------------------------------------------------------------------
1 |
2 |
Nothing Special Div Fragment
3 |
4 |
5 | - Item One
6 | - Item Two
7 | - Item Three
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/html/valid/full/valid_angular.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Test HTML - Valid
5 |
6 |
7 |
{{paraBody}}
8 |
9 | Some sort of directive content would go here, I presume.
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/html/valid/full/valid_angular_directives.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Test HTML - Valid
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/test/html/valid/full/valid_regular.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Test HTML - Valid
5 |
6 |
7 |
Hi Nik!
8 |
9 |
--------------------------------------------------------------------------------
/test/html/valid/template/valid_angular.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 |
{{fragLabel}}
3 |
8 |
--------------------------------------------------------------------------------
/test/html/valid/template/valid_angular_table_row.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 | {name} |
3 | {birthdate} |
4 | {address} |
5 |
--------------------------------------------------------------------------------
/test/html/valid/template/valid_regular.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 |
Nothing Special Div Fragment
3 |
4 |
5 | - Item One
6 | - Item Two
7 | - Item Three
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/htmlangular_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | ======== A Handy Little Nodeunit Reference ========
5 | https://github.com/caolan/nodeunit
6 |
7 | Test methods:
8 | test.expect(numAssertions)
9 | test.done()
10 | Test assertions:
11 | test.ok(value, [message])
12 | test.equal(actual, expected, [message])
13 | test.notEqual(actual, expected, [message])
14 | test.deepEqual(actual, expected, [message])
15 | test.notDeepEqual(actual, expected, [message])
16 | test.strictEqual(actual, expected, [message])
17 | test.notStrictEqual(actual, expected, [message])
18 | test.throws(block, [error], [message])
19 | test.doesNotThrow(block, [error], [message])
20 | test.ifError(value)
21 | */
22 |
23 | var
24 | path = require('path'),
25 | exec = require('child_process').exec,
26 | execOptions = {
27 | cwd: path.join(__dirname, '..')
28 | }
29 | ;
30 |
31 | exports.tests = {
32 | default_options: function(test) {
33 | test.expect(1);
34 | exec('grunt htmlangular:default_options', execOptions, function(error, stdout) {
35 | test.equal(
36 | stdout.indexOf('6 files passed validation') > -1,
37 | true,
38 | 'valid files pass'
39 | );
40 | test.done();
41 | });
42 | },
43 | default_options_concurrent: function(test) {
44 | test.expect(1);
45 | exec('grunt htmlangular:default_options_concurrent', execOptions, function(error, stdout) {
46 | test.equal(
47 | stdout.indexOf('6 files passed validation') > -1,
48 | true,
49 | 'valid files pass'
50 | );
51 | test.done();
52 | });
53 | },
54 | missing_wrapping: function(test) {
55 | test.expect(4);
56 | exec('grunt htmlangular:missing_wrapping', execOptions, function(error, stdout) {
57 | test.equal(
58 | stdout.indexOf('Stray start tag “tr”') > -1,
59 | true,
60 | 'found unwrapped starting
'
61 | );
62 | test.equal(
63 | stdout.indexOf('Stray start tag “td”') > -1,
64 | true,
65 | 'found unwrapped starting '
66 | );
67 | test.equal(
68 | stdout.indexOf('Stray end tag “td”') > -1,
69 | true,
70 | 'found unwrapped starting | '
71 | );
72 | test.equal(
73 | stdout.indexOf('Stray end tag “tr”') > -1,
74 | true,
75 | 'found unwrapped starting |
'
76 | );
77 | test.done();
78 | });
79 | },
80 | /*missing_custom_tags: function(test) {
81 | test.expect(1);
82 | exec('grunt htmlangular:missing_custom_tags', execOptions, function(error, stdout) {
83 | test.equal(
84 | stdout.indexOf('Element “custom-tag” not allowed as child') > -1,
85 | true,
86 | 'found custom tag'
87 | );
88 | test.done();
89 | });
90 | },*/
91 | missing_custom_attrs: function(test) {
92 | test.expect(1);
93 | exec('grunt htmlangular:missing_custom_attrs', execOptions, function(error, stdout) {
94 | test.equal(
95 | stdout.indexOf('Attribute “fixed-div-label” not allowed on element') > -1,
96 | true,
97 | 'found custom attribute'
98 | );
99 | test.done();
100 | });
101 | },
102 | template_missing_extension: function(test) {
103 | test.expect(1);
104 | exec('grunt htmlangular:template_missing_extension', execOptions, function(error, stdout) {
105 | test.equal(
106 | stdout.indexOf('Element “head” is missing a required instance of child element “title”') > -1,
107 | true,
108 | 'figured out it is just template'
109 | );
110 | test.done();
111 | });
112 | },
113 | missing_closing_tag: function(test) {
114 | test.expect(1);
115 | exec('grunt htmlangular:missing_closing_tag', execOptions, function(error, stdout) {
116 | test.equal(
117 | stdout.indexOf('Unclosed element “div”') > -1,
118 | true,
119 | 'found unclosed div'
120 | );
121 | test.done();
122 | });
123 | },
124 | improperly_closed_tag: function(test) {
125 | test.expect(2);
126 | exec('grunt htmlangular:improperly_closed_tag', execOptions, function(error, stdout) {
127 | test.equal(
128 | stdout.indexOf('Self-closing syntax (“/>”) used on a non-void HTML element') > -1,
129 | true,
130 | 'found self-closed span'
131 | );
132 | test.equal(
133 | stdout.indexOf('Unclosed element “span”') > -1,
134 | true,
135 | 'found unclosed span'
136 | );
137 | test.done();
138 | });
139 | },
140 | improperly_nested_tags: function(test) {
141 | test.expect(2);
142 | exec('grunt htmlangular:improperly_nested_tags', execOptions, function(error, stdout) {
143 | test.equal(
144 | stdout.indexOf('End tag “b” violates nesting rules') > -1,
145 | true,
146 | 'found closed too early'
147 | );
148 | test.equal(
149 | stdout.indexOf('No “i” element in scope but a “i” end tag seen') > -1,
150 | true,
151 | 'found closed too late'
152 | );
153 | test.done();
154 | });
155 | },
156 | improper_angular_operator_relaxed: function(test) {
157 | test.expect(1);
158 | exec('grunt htmlangular:improper_angular_operator_relaxed', execOptions, function(error, stdout) {
159 | test.equal(
160 | stdout.indexOf('“&” did not start a character reference. (“&” probably should have been escaped as “&”.)') === -1,
161 | true,
162 | 'relaxed ignored error'
163 | );
164 | test.done();
165 | });
166 | }
167 | };
168 |
--------------------------------------------------------------------------------