als-document 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/document.js +25 -11
- package/document.mjs +804 -0
- package/package.json +3 -6
- package/readme.md +12 -4
- package/test/{html1.js → data/html1.js} +1 -2
- package/test/{html2.js → data/html2.js} +1 -1
- package/test/front-test/html.html +5650 -0
- package/test/front-test/html.js +3218 -0
- package/test/front-test/test.html +18 -0
- package/test/front-test/test.js +129 -0
- package/test/test.html +17 -0
- package/test/test.js +15 -19
- package/test/tests/document-test.js +402 -0
- package/test/tests/parser-test.js +99 -0
- package/test/tests/query-test.js +71 -0
- package/test/tests/selector-test.js +169 -0
- package/test/utils/__dirname.js +6 -0
- package/test/utils/als-simple-test/test.mjs +153 -0
- package/test/utils/iframe.js +4 -0
- package/document/document.js +0 -192
- package/document/test.js +0 -678
- package/document.min.js +0 -1
- package/index.js +0 -6
- package/parser/parser.js +0 -336
- package/parser/test.js +0 -233
- package/query/query.js +0 -147
- package/query/readme.md +0 -134
- package/query/test.js +0 -143
- package/selector/selector.js +0 -126
- package/selector/test.js +0 -410
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { HtmlParser } from '../../document.mjs'
|
|
2
|
+
import SimpleTest from '../utils/als-simple-test/test.mjs'
|
|
3
|
+
let {describe,it,beforeEach,runTests,expect,delay} = SimpleTest
|
|
4
|
+
import html1 from '../data/html1.js'
|
|
5
|
+
import html2 from '../data/html2.js'
|
|
6
|
+
|
|
7
|
+
let root1 = HtmlParser.parse(html1)
|
|
8
|
+
let root2 = HtmlParser.parse(html2)
|
|
9
|
+
let body1 = root1.children[1].children[1]
|
|
10
|
+
let head1 = root1.children[1].children[0]
|
|
11
|
+
let body2 = root2.children[0].children[1]
|
|
12
|
+
let head2 = root2.children[0].children[0]
|
|
13
|
+
|
|
14
|
+
export default function() {
|
|
15
|
+
describe('HtmlParser tests', () => {
|
|
16
|
+
it('Parse html for html1',() => {
|
|
17
|
+
expect(root1.type).equalTo('root')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('Parse html for html2',() => {
|
|
21
|
+
expect(root2.type).equalTo('root')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('root1 element has 2 children',() => {
|
|
25
|
+
expect(root1.children.length).equalTo(2)
|
|
26
|
+
})
|
|
27
|
+
it('Check if element is right',() => {
|
|
28
|
+
expect(body1.tag).equalTo('body')
|
|
29
|
+
})
|
|
30
|
+
it('Check if element is right',() => {
|
|
31
|
+
expect(head1.tag).equalTo('head')
|
|
32
|
+
})
|
|
33
|
+
it('body element has 4 children',() => {
|
|
34
|
+
expect(body1.children.length).equalTo(4)
|
|
35
|
+
})
|
|
36
|
+
it('Read title text',() => {
|
|
37
|
+
expect(head1.children[3].children[0].text).equalTo('Document')
|
|
38
|
+
})
|
|
39
|
+
it('innerHTML',() => {
|
|
40
|
+
expect(body1.children[3].children[6].innerHTML).equalTo('tab3 content')
|
|
41
|
+
})
|
|
42
|
+
it('outerHTML',() => {
|
|
43
|
+
expect(body1.children[3].children[6].outerHTML)
|
|
44
|
+
.equalTo('<div class="tab-content p2 transition1">tab3 content</div>')
|
|
45
|
+
})
|
|
46
|
+
it('ancestors',() => {
|
|
47
|
+
expect(body1.children[3].children[6].ancestors.length).equalTo(3)
|
|
48
|
+
})
|
|
49
|
+
it('elements',() => {
|
|
50
|
+
expect(body1.children[3].elements.length).equalTo(25)
|
|
51
|
+
})
|
|
52
|
+
it('children length',() => {
|
|
53
|
+
expect(body2.children.length).equalTo(15)
|
|
54
|
+
})
|
|
55
|
+
it('id',() => {
|
|
56
|
+
expect(body1.children[3].children[1].id).equalTo('tab2')
|
|
57
|
+
})
|
|
58
|
+
it('classList',() => {
|
|
59
|
+
expect(body2.children[2].children[0].children[4].classList.length).equalTo(5)
|
|
60
|
+
})
|
|
61
|
+
it('style',() => {
|
|
62
|
+
let style = body2.children[2].children[0].children[4].style
|
|
63
|
+
expect(Object.keys(style)[0]).equalTo('marginTop')
|
|
64
|
+
})
|
|
65
|
+
it('style length',() => {
|
|
66
|
+
let style = body2.children[4].style
|
|
67
|
+
expect(Object.keys(style).length).equalTo(5)
|
|
68
|
+
})
|
|
69
|
+
it('style with multiple styles',() => {
|
|
70
|
+
let style = body2.children[4].style
|
|
71
|
+
expect(style.left).equalTo('605px')
|
|
72
|
+
})
|
|
73
|
+
it('attributs length',() => {
|
|
74
|
+
let attribs = body2.children[2].children[0].children[0].attribs
|
|
75
|
+
expect(Object.keys(attribs).length).equalTo(6)
|
|
76
|
+
})
|
|
77
|
+
it('attribute content',() => {
|
|
78
|
+
expect(body2.children[2].children[0].children[0].attribs.target).equalTo('_blank')
|
|
79
|
+
})
|
|
80
|
+
it('next',() => {
|
|
81
|
+
let {tag,id} = body2.children[2].children[0].children[0].next
|
|
82
|
+
expect(`${tag}#${id}`).equalTo('a#menuButton')
|
|
83
|
+
})
|
|
84
|
+
it('prev',() => {
|
|
85
|
+
let {tag,id} = body2.children[2].children[0].children[1].prev
|
|
86
|
+
expect(`${tag}#${id}`).equalTo('a#tryhome')
|
|
87
|
+
})
|
|
88
|
+
it('parent',() => {
|
|
89
|
+
let {tag,classList} = body2.children[2].children[0].children[1].parent
|
|
90
|
+
expect(`${tag}.${classList[0]}`).equalTo('div.w3-bar')
|
|
91
|
+
})
|
|
92
|
+
it('Single tags doesnt have children',() => {
|
|
93
|
+
expect(head2.children[1].children).isNot().defined()
|
|
94
|
+
})
|
|
95
|
+
it('Text tag doesnt have children',() => {
|
|
96
|
+
expect(head2.children[0].children[0].children).isNot().defined()
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Query } from '../../document.mjs'
|
|
2
|
+
import SimpleTest from '../utils/als-simple-test/test.mjs'
|
|
3
|
+
let {describe,it,beforeEach,runTests,expect,delay} = SimpleTest
|
|
4
|
+
// import html1 from './html1.js'
|
|
5
|
+
// import html2 from './html2.js'
|
|
6
|
+
const q1 = 'html>body>div.tabs~.some[type $= "some"][test]>p+div>.some-id .tab-content~input[disabled] div.some'
|
|
7
|
+
const s1 = Query.get(q1)[0]
|
|
8
|
+
|
|
9
|
+
export default function () {
|
|
10
|
+
it('Check target',() => {
|
|
11
|
+
const expected = 'div.some'
|
|
12
|
+
let {tag,classList} = s1
|
|
13
|
+
expect(`${tag}.${classList[0]}`).equalTo(expected)
|
|
14
|
+
})
|
|
15
|
+
it('Check ancestors length',() => {
|
|
16
|
+
expect(s1.ancestors.length).equalTo(2)
|
|
17
|
+
})
|
|
18
|
+
it('Check prev group',() => {
|
|
19
|
+
const expected = s1.ancestors[0].group.split('+')[0]
|
|
20
|
+
expect(s1.ancestors[0].prev.group).equalTo(expected)
|
|
21
|
+
})
|
|
22
|
+
it('Check parents length',() => {
|
|
23
|
+
expect(s1.ancestors[0].parents.length).equalTo(1)
|
|
24
|
+
})
|
|
25
|
+
it('Check prev any, prev and classList',() => {
|
|
26
|
+
expect(s1.ancestors[0].prev.prevAny.classList[0]).equalTo('tabs')
|
|
27
|
+
})
|
|
28
|
+
it('Check attributes length',() => {
|
|
29
|
+
expect(s1.ancestors[0].prev.parents[0].attribs.length).equalTo(2)
|
|
30
|
+
})
|
|
31
|
+
it('Check attributes fn $',() => {
|
|
32
|
+
expect(s1.ancestors[0].prev.parents[0].attribs[0].check('test and some')).equalTo(true)
|
|
33
|
+
})
|
|
34
|
+
it('Check attributes fn *=',() => {
|
|
35
|
+
expect(s1.ancestors[0].prev.parents[0].attribs[0].check('some'))
|
|
36
|
+
.equalTo(true)
|
|
37
|
+
})
|
|
38
|
+
it('Check attributes fn *=',() => {
|
|
39
|
+
let s = Query.get('[test*="some value"]')[0]
|
|
40
|
+
expect(s.attribs[0].check('some value test')).equalTo(true)
|
|
41
|
+
})
|
|
42
|
+
it('Check attributes fn ~= prase instead single word',() => {
|
|
43
|
+
let s = Query.get('[test~="some value"]')[0]
|
|
44
|
+
expect(s.attribs[0].check('some value test')).equalTo(false)
|
|
45
|
+
})
|
|
46
|
+
it('Check attributes fn ~=',() => {
|
|
47
|
+
let s = Query.get('[test~="value"]')[0]
|
|
48
|
+
expect(s.attribs[0].check('some value test'))
|
|
49
|
+
.equalTo(true)
|
|
50
|
+
})
|
|
51
|
+
it('Check attributes fn ^=',() => {
|
|
52
|
+
let s = Query.get('[test^="some"]')[0]
|
|
53
|
+
expect(s.attribs[0].check('some value test'))
|
|
54
|
+
.equalTo(true)
|
|
55
|
+
})
|
|
56
|
+
it('Check attributes fn |= with few words',() => {
|
|
57
|
+
let s = Query.get('[test|="some value test"]')[0]
|
|
58
|
+
expect(s.attribs[0].check('some'))
|
|
59
|
+
.equalTo(false)
|
|
60
|
+
})
|
|
61
|
+
it('Check attributes fn |=word',() => {
|
|
62
|
+
let s = Query.get('[test|="some"]')[0]
|
|
63
|
+
expect(s.attribs[0].check('some'))
|
|
64
|
+
.equalTo(true)
|
|
65
|
+
})
|
|
66
|
+
it('Check attributes fn |=word-word',() => {
|
|
67
|
+
let s = Query.get('[test|="some"]')[0]
|
|
68
|
+
expect(s.attribs[0].check('some-value'))
|
|
69
|
+
.equalTo(true)
|
|
70
|
+
})
|
|
71
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { HtmlSelector } from '../../document.mjs'
|
|
2
|
+
import SimpleTest from '../utils/als-simple-test/test.mjs'
|
|
3
|
+
let {describe,it,beforeEach,runTests,expect,delay} = SimpleTest
|
|
4
|
+
import html1 from '../data/html1.js'
|
|
5
|
+
import html2 from '../data/html2.js'
|
|
6
|
+
let $1 = new HtmlSelector(html1)
|
|
7
|
+
let $2 = new HtmlSelector(html2)
|
|
8
|
+
|
|
9
|
+
export default function () {
|
|
10
|
+
describe('Selector tests', () => {
|
|
11
|
+
describe('Tests for selecting single element',() => {
|
|
12
|
+
it('Get body tag from $1', () => {
|
|
13
|
+
expect( $1.$('body').tag).equalTo('body');
|
|
14
|
+
})
|
|
15
|
+
it('Get body tag from $2', () => {
|
|
16
|
+
expect( $2.$('body').tag).equalTo('body');
|
|
17
|
+
})
|
|
18
|
+
it('Get element by className from $1', () => {
|
|
19
|
+
expect( $1.$('.tabs').classList.includes('tabs')).equalTo(true);
|
|
20
|
+
})
|
|
21
|
+
it('Get element by className from $2', () => {
|
|
22
|
+
expect( $2.$('.w3-button').attribs.href)
|
|
23
|
+
.equalTo('https://www.w3schools.com');
|
|
24
|
+
})
|
|
25
|
+
it('Get element by id from $1', () => {
|
|
26
|
+
expect( $1.$('#tab3').id).equalTo('tab3');
|
|
27
|
+
})
|
|
28
|
+
it('Get element by id from $2', () => {
|
|
29
|
+
expect( $2.$('#runbtn').id).equalTo('runbtn');
|
|
30
|
+
})
|
|
31
|
+
it('Get element by attribute from $1', () => {
|
|
32
|
+
expect( $1.$('[name="css-tabs"][type="radio"][checked]').id).equalTo('tab1');
|
|
33
|
+
})
|
|
34
|
+
it('Get element by attribute from $2', () => {
|
|
35
|
+
expect( $2.$('[title="Save"]').attribs.title)
|
|
36
|
+
.equalTo('Save');
|
|
37
|
+
})
|
|
38
|
+
it('Get element by attribute name $1', () => {
|
|
39
|
+
expect( $1.$('[style]').style.display).equalTo('none');
|
|
40
|
+
})
|
|
41
|
+
it('Get element by attribute name $2', () => {
|
|
42
|
+
expect( $2.$('[class]').attribs.class).equalTo('trytopnav');
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
describe('Check attributes for single',() => {
|
|
46
|
+
it('Test includes - "*=" fro $1',() => {
|
|
47
|
+
expect( $1.$('[class*="transition1"]').innerHTML).equalTo('Tab 1')
|
|
48
|
+
})
|
|
49
|
+
it('Test starts with - "^=" fro $1',() => {
|
|
50
|
+
expect( $1.$('[class*="tab-content"]').innerHTML).equalTo('tab1 content')
|
|
51
|
+
})
|
|
52
|
+
it('Test ends with - "$=" fro $1',() => {
|
|
53
|
+
expect( $1.$('[class*="p2 transition1"]').innerHTML).equalTo('tab1 content')
|
|
54
|
+
})
|
|
55
|
+
it('Test starts with word- "|=" fro $1',() => {
|
|
56
|
+
expect( $1.$('[name|="css"]').attribs.name).equalTo('css-tabs')
|
|
57
|
+
})
|
|
58
|
+
it('Test includes word "~=" fro $1',() => {
|
|
59
|
+
expect($1.$('[class~="bgc-smoke"]').classList.includes('bgc-smoke')).equalTo(true)
|
|
60
|
+
})
|
|
61
|
+
it('Test includes - "*=" fro $2',() => {
|
|
62
|
+
expect( $2.$('[title*=".com"]').attribs.title).equalTo('w3schools.com Home')
|
|
63
|
+
})
|
|
64
|
+
it('Test starts with - "^=" fro $2',() => {
|
|
65
|
+
expect( $2.$('[class^="w3-right"]').attribs.class).equalTo('w3-right w3-hide-small')
|
|
66
|
+
})
|
|
67
|
+
it('Test ends with - "$=" fro $2',() => {
|
|
68
|
+
expect( $2.$('[title$="Home"]').attribs.title).equalTo('w3schools.com Home')
|
|
69
|
+
})
|
|
70
|
+
it('Test starts with word- "|=" fro $2',() => {
|
|
71
|
+
expect( $2.$('[lang|="en"]').attribs.lang).equalTo('en-US')
|
|
72
|
+
})
|
|
73
|
+
it('Test includes word "~=" fro $2',() => {
|
|
74
|
+
expect( $2.$('[property~="width"]').attribs.property).equalTo('og:image:width')
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
describe('Few selectors test for single',() => {
|
|
78
|
+
it('tag and attribute $1',() => {
|
|
79
|
+
expect( $1.$('input[checked]').id).equalTo('tab1')
|
|
80
|
+
})
|
|
81
|
+
it('parent tag and attribute $1',() => {
|
|
82
|
+
expect( $1.$('div.tabs>input[checked]').id).equalTo('tab1')
|
|
83
|
+
})
|
|
84
|
+
it('parent and next $1',() => {
|
|
85
|
+
expect( $1.$('div.tabs>input[checked]+input').id).equalTo('tab2')
|
|
86
|
+
})
|
|
87
|
+
it('ancestor $1',() => {
|
|
88
|
+
expect( $1.$('body [onclick*="Hello world"]').attribs.onclick.includes('this.innerHTML')).equalTo(true)
|
|
89
|
+
})
|
|
90
|
+
it('ancestor, parent and (~) $1',() => {
|
|
91
|
+
expect( $1.$('[checked]~#tab3').id).equalTo('tab3')
|
|
92
|
+
})
|
|
93
|
+
it('inner',() => {
|
|
94
|
+
expect( $1.$('[inner*="content"]').innerHTML).equalTo('tab1 content')
|
|
95
|
+
})
|
|
96
|
+
it('tag and attribute $2',() => {
|
|
97
|
+
expect( $2.$('button[onclick]').id).equalTo('runbtn')
|
|
98
|
+
})
|
|
99
|
+
it('parent tag and attribute $2',() => {
|
|
100
|
+
expect( $2.$('#container>div>span[title="Close Menu"]').innerHTML).equalTo('×')
|
|
101
|
+
})
|
|
102
|
+
it('parent and next $2',() => {
|
|
103
|
+
expect( $2.$('#container>div>span[title="Close Menu"]+div').attribs.class).equalTo('w3-bar-block')
|
|
104
|
+
})
|
|
105
|
+
it('ancestor $2',() => {
|
|
106
|
+
expect( $2.$('#container a span').innerHTML).equalTo('Change Orientation')
|
|
107
|
+
})
|
|
108
|
+
it('ancestor, parent and (~) $2',() => {
|
|
109
|
+
expect( $2.$('#container a>i~span').innerHTML).equalTo('Change Orientation')
|
|
110
|
+
})
|
|
111
|
+
it('inner',() => {
|
|
112
|
+
expect( $2.$('[inner*="Privacy"]').innerHTML).equalTo('Privacy policy')
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
describe('Select collection',() => {
|
|
116
|
+
it('Select few elements (input) $1',() => {
|
|
117
|
+
expect( $1.$$('input').length).equalTo(3)
|
|
118
|
+
})
|
|
119
|
+
it('Select few elements ([inner*=test]) $1',() => {
|
|
120
|
+
expect( $1.$$('[inner*=test]').length).equalTo(3)
|
|
121
|
+
})
|
|
122
|
+
it('Select few elements (.transition1) $1',() => {
|
|
123
|
+
expect( $1.$$('.transition1').length).equalTo(6)
|
|
124
|
+
})
|
|
125
|
+
it('Select few elements (div>.transition1) $1',() => {
|
|
126
|
+
expect( $1.$$('div>.transition1').length).equalTo(3)
|
|
127
|
+
})
|
|
128
|
+
it('Select few elements (.col5>input[checked][name^=css][type]) $1',() => {
|
|
129
|
+
expect( $1.$$('.col5>input[checked][name^=css][type]').length).equalTo(1)
|
|
130
|
+
})
|
|
131
|
+
it('Select few elements (.col5 label[for^="tab"]) $1',() => {
|
|
132
|
+
expect( $1.$$('.col5 label[for^="tab"]').length).equalTo(3)
|
|
133
|
+
})
|
|
134
|
+
it('Select few elements (.w3-button) $2',() => {
|
|
135
|
+
expect( $2.$$('.w3-button').length).equalTo(12)
|
|
136
|
+
})
|
|
137
|
+
it('Select few elements (.w3-button) $2',() => {
|
|
138
|
+
expect( $2.$$('.w3-button>img').length).equalTo(1)
|
|
139
|
+
})
|
|
140
|
+
it('Select few elements (.w3-button>img+span) $2',() => {
|
|
141
|
+
expect( $2.$$('.w3-button>img+span')[0].innerHTML).equalTo('Go to Spaces')
|
|
142
|
+
})
|
|
143
|
+
it('Select few elements (#container div) $2',() => {
|
|
144
|
+
expect( $2.$$('#container div').length).equalTo(30)
|
|
145
|
+
})
|
|
146
|
+
it('Select few elements (#container div) $2',() => {
|
|
147
|
+
expect( $2.$$('#container>div').length).equalTo(4)
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
describe('Few selectors',() => {
|
|
151
|
+
it('Select few elements (.col5 label[for^="tab"],input[checked]) $1',() => {
|
|
152
|
+
expect( $1.$$('.col5 label[for^="tab"],input[checked]').length).equalTo(4)
|
|
153
|
+
})
|
|
154
|
+
it('Select few elements ([style],[onclick]) $1',() => {
|
|
155
|
+
expect( $1.$$('[style],[onclick],[name]').length).equalTo(7)
|
|
156
|
+
})
|
|
157
|
+
it('Select few elements (#container a[title]) $2',() => {
|
|
158
|
+
expect( $2.$$('#container a[title]').length).equalTo(4)
|
|
159
|
+
})
|
|
160
|
+
it('Select few elements (div,span) $2',() => {
|
|
161
|
+
expect( $2.$$('div,span').length).equalTo(165)
|
|
162
|
+
})
|
|
163
|
+
it('Select few elements (meta[property^="og"],meta[content^="width"]) $2',() => {
|
|
164
|
+
expect( $2.$$('meta[property^="og"],meta[content^="width"]').length).equalTo(8)
|
|
165
|
+
})
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
})
|
|
169
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
class SimpleTest {
|
|
2
|
+
static tests = [];
|
|
3
|
+
static beforeEachCallback;
|
|
4
|
+
static afterEachCallback;
|
|
5
|
+
static nestingLevel = 0;
|
|
6
|
+
static currentParent = [];
|
|
7
|
+
static space = ''
|
|
8
|
+
static results = {}
|
|
9
|
+
static errors = []
|
|
10
|
+
static failed = []
|
|
11
|
+
static testTitle = ''
|
|
12
|
+
static showFullError = false
|
|
13
|
+
static colors = {
|
|
14
|
+
bold:'\x1b[1m',
|
|
15
|
+
cblue:'\x1b[34m',
|
|
16
|
+
cred:'\x1b[31m',
|
|
17
|
+
cgreen:'\x1b[32m',
|
|
18
|
+
cgray:'\x1b[37m',
|
|
19
|
+
reset:'\x1b[0m'
|
|
20
|
+
}
|
|
21
|
+
static delay = (ms,toResolve) => new Promise((resolve) => {
|
|
22
|
+
setTimeout(() => {resolve(toResolve)}, ms);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
static describe(title, callback) {
|
|
26
|
+
let { nestingLevel, currentParent } = SimpleTest
|
|
27
|
+
nestingLevel++;
|
|
28
|
+
currentParent.push(title);
|
|
29
|
+
callback();
|
|
30
|
+
|
|
31
|
+
currentParent.pop();
|
|
32
|
+
nestingLevel--;
|
|
33
|
+
if (nestingLevel === 0) {
|
|
34
|
+
SimpleTest.beforeEachCallback = null; // Clear beforeEachCallback after finishing the outermost describe block
|
|
35
|
+
SimpleTest.afterEachCallback = null; // Clear beforeEachCallback after finishing the outermost describe block
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static beforeEach(callback) {SimpleTest.beforeEachCallback = callback;}
|
|
40
|
+
|
|
41
|
+
static afterEach(callback) {SimpleTest.afterEachCallback = callback;}
|
|
42
|
+
|
|
43
|
+
static it(title, callback) {
|
|
44
|
+
SimpleTest.tests.push({
|
|
45
|
+
titles: [...SimpleTest.currentParent, title],
|
|
46
|
+
before: SimpleTest.beforeEachCallback,
|
|
47
|
+
after:SimpleTest.afterEachCallback,
|
|
48
|
+
test: callback,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static async runTests(consoleLog=true) {
|
|
53
|
+
const {bold,cblue,cred,reset} = SimpleTest.colors
|
|
54
|
+
SimpleTest.consoleLog = consoleLog
|
|
55
|
+
let { tests,results,showFullError } = SimpleTest;
|
|
56
|
+
let previousTitles = [];
|
|
57
|
+
for(const test of tests) {
|
|
58
|
+
let curentResult = results
|
|
59
|
+
SimpleTest.space = test.titles.map(t => ' ').join('');
|
|
60
|
+
test.titles.forEach((title, index) => {
|
|
61
|
+
if(curentResult[title] == undefined) {
|
|
62
|
+
if(index == test.titles.length-1) curentResult[title] = []
|
|
63
|
+
else curentResult[title] = {}
|
|
64
|
+
}
|
|
65
|
+
curentResult = curentResult[title]
|
|
66
|
+
if(previousTitles[index] !== title) {
|
|
67
|
+
const indentation = ' '.repeat(index);
|
|
68
|
+
console.log(bold+cblue+'%s'+reset,`${indentation} ${title}`);
|
|
69
|
+
previousTitles[index] = title;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
SimpleTest.curentResult = curentResult
|
|
73
|
+
try {
|
|
74
|
+
if (test.before) await test.before();
|
|
75
|
+
await test.test();
|
|
76
|
+
if (test.after) await test.after();
|
|
77
|
+
} catch (error) {
|
|
78
|
+
let msg = `${SimpleTest.space}${cred}Error:${reset} ${error.message}`
|
|
79
|
+
SimpleTest.errors.push(msg)
|
|
80
|
+
if(showFullError) console.log(error)
|
|
81
|
+
else console.log(msg);
|
|
82
|
+
curentResult.push({error})
|
|
83
|
+
}
|
|
84
|
+
console.log('\n');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static expect(value1) {
|
|
89
|
+
let { logResult, isEqual } = SimpleTest
|
|
90
|
+
const methods = {
|
|
91
|
+
is: (text='') => {
|
|
92
|
+
SimpleTest.testTitle = text;
|
|
93
|
+
SimpleTest.not = false
|
|
94
|
+
return methods;
|
|
95
|
+
},
|
|
96
|
+
isNot: (text='') => {
|
|
97
|
+
SimpleTest.testTitle = text;
|
|
98
|
+
SimpleTest.not = true
|
|
99
|
+
return methods;
|
|
100
|
+
},
|
|
101
|
+
equalTo: (value2) => {logResult(value1 === value2);},
|
|
102
|
+
between(value2,value3) {logResult(value1 >= value2 && value1 <= value3);},
|
|
103
|
+
below(value2) {logResult(value1 < value2);},
|
|
104
|
+
above(value2) {logResult(value1 > value2);},
|
|
105
|
+
atLeast(value2) {logResult(value1 >= value2);},
|
|
106
|
+
sameAs: (value2) => {logResult(isEqual(value1, value2));},
|
|
107
|
+
defined: () => {logResult(value1 !== undefined);},
|
|
108
|
+
matchTo(pattern) {logResult(pattern.test(new RegExp(value1)));},
|
|
109
|
+
includes(value2) {logResult(value1.includes(value2));},
|
|
110
|
+
error: () => {
|
|
111
|
+
try {value1(); return false;
|
|
112
|
+
} catch (error) {return true}
|
|
113
|
+
},
|
|
114
|
+
hasProperty: (property) => {logResult(Object.prototype.hasOwnProperty.call(value1, property));},
|
|
115
|
+
};
|
|
116
|
+
return methods;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static logResult(result) {
|
|
120
|
+
let {curentResult,testTitle,not,space,colors} = SimpleTest
|
|
121
|
+
let {cgreen,cred,cgray,reset} = colors
|
|
122
|
+
if(not) result = !result
|
|
123
|
+
curentResult.push({result:result ? true : false,testTitle,error:null})
|
|
124
|
+
SimpleTest.failed.push(testTitle)
|
|
125
|
+
const status = result ? 'Success' : 'Failed';
|
|
126
|
+
const color = result ? cgreen : cred;
|
|
127
|
+
if (testTitle == '') console.log(`${color}${space}${status}${reset}`);
|
|
128
|
+
else console.log(`${space}${color}${status}: ${testTitle ? `${cgray}${testTitle}` : ''}`+reset,);
|
|
129
|
+
SimpleTest.not = false
|
|
130
|
+
SimpleTest.testTitle = ''
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static isEqual(obj1, obj2, visited = new WeakMap()) {
|
|
134
|
+
if (obj1 === obj2) return true;
|
|
135
|
+
|
|
136
|
+
if (visited.has(obj1) && visited.get(obj1) === obj2) return true;
|
|
137
|
+
|
|
138
|
+
const type1 = typeof obj1;
|
|
139
|
+
const type2 = typeof obj2;
|
|
140
|
+
if (type1 !== type2 || type1 !== 'object' || obj1 === null || obj2 === null) return false;
|
|
141
|
+
visited.set(obj1, obj2);
|
|
142
|
+
|
|
143
|
+
const keys1 = Object.keys(obj1);
|
|
144
|
+
const keys2 = Object.keys(obj2);
|
|
145
|
+
if (keys1.length !== keys2.length) return false;
|
|
146
|
+
|
|
147
|
+
for (let key of keys1) {
|
|
148
|
+
if (!keys2.includes(key) || !SimpleTest.isEqual(obj1[key], obj2[key], visited)) return false;
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export default SimpleTest
|