codemodels-js 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,150 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ class TestBasicParsing < Test::Unit::TestCase
5
+
6
+ include TestHelper
7
+ include CodeModels
8
+ include CodeModels::Js
9
+
10
+ def test_block
11
+ code = "{ var x = 5 + 5; }"
12
+ model = parse_code(code)
13
+ assert model.is_a?(AstRoot)
14
+ assert_equal 1,model.statements.count
15
+ assert model.statements[0].is_a?(Scope)
16
+ end
17
+
18
+ def test_while_statements_empty
19
+ code = "while (true) { }"
20
+ model = parse_code(code).statements[0]
21
+ assert_class WhileLoop, model
22
+ assert_equal 0,model.body.statements.count
23
+ end
24
+
25
+ def test_while_statements_one_element
26
+ code = "while (true) { i++; }"
27
+ model = parse_code(code).statements[0]
28
+ assert_class WhileLoop, model
29
+ assert_equal 1,model.body.statements.count
30
+ end
31
+
32
+ def test_bitwise_not_operator
33
+ code = "~1"
34
+ model = parse_code(code).statements[0]
35
+ assert_class ExpressionStatement, model
36
+ assert_class BitwiseNotOperator, model.expression
37
+ end
38
+
39
+ def test_not_operator
40
+ code = "!true"
41
+ model = parse_code(code).statements[0]
42
+ assert_class ExpressionStatement, model
43
+ assert_class NotOperator, model.expression
44
+ end
45
+
46
+ def test_equals_infix_expr
47
+ code = "1==1"
48
+ model = parse_code(code).statements[0]
49
+ assert_class ExpressionStatement, model
50
+ assert_class EqualsInfixExpression, model.expression
51
+ end
52
+
53
+ def test_identity_infix_expr
54
+ code = "1===1"
55
+ model = parse_code(code).statements[0]
56
+ assert_class ExpressionStatement, model
57
+ assert_class IdentityInfixExpression, model.expression
58
+ end
59
+
60
+ def test_not_identity_infix_expr
61
+ code = "1!==1"
62
+ model = parse_code(code).statements[0]
63
+ assert_class ExpressionStatement, model
64
+ assert_class NotIdentityInfixExpression, model.expression
65
+ end
66
+
67
+ def test_not_equals_infix_expr
68
+ code = "1!=1"
69
+ model = parse_code(code).statements[0]
70
+ assert_class ExpressionStatement, model
71
+ assert_class NotEqualsInfixExpression, model.expression
72
+ end
73
+
74
+ def test_sub_expression_position
75
+ code = "1!=1"
76
+ model = parse_code(code).statements[0]
77
+ assert_class ExpressionStatement, model
78
+ assert_class NotEqualsInfixExpression, model.expression
79
+ assert_class Js::NumberLiteral, model.expression.left
80
+ assert_class Js::NumberLiteral, model.expression.right
81
+ assert_equal SourcePoint.new(1,1),model.expression.left.source.position.begin_point
82
+ assert_equal SourcePoint.new(1,1),model.expression.left.source.position.end_point
83
+ assert_equal SourcePoint.new(1,4),model.expression.right.source.position.begin_point
84
+ assert_equal SourcePoint.new(1,4),model.expression.right.source.position.end_point
85
+ end
86
+
87
+ def test_logic_and_infix_expr
88
+ code = "1&&1"
89
+ model = parse_code(code).statements[0]
90
+ assert_class ExpressionStatement, model
91
+ assert_class LogicAndInfixExpression, model.expression
92
+ end
93
+
94
+ def test_logic_or_infix_expr
95
+ code = "1||1"
96
+ model = parse_code(code).statements[0]
97
+ assert_class ExpressionStatement, model
98
+ assert_class LogicOrInfixExpression, model.expression
99
+ end
100
+
101
+ def test_unary_plus
102
+ code = "+1"
103
+ model = parse_code(code).statements[0]
104
+ assert_class ExpressionStatement, model
105
+ assert_class UnaryPlusOperator, model.expression
106
+ end
107
+
108
+ def test_unary_minus
109
+ code = "-1"
110
+ model = parse_code(code).statements[0]
111
+ assert_class ExpressionStatement, model
112
+ assert_class UnaryMinusOperator, model.expression
113
+ end
114
+
115
+ def test_comma_infix_expr
116
+ code = "1,2"
117
+ model = parse_code(code).statements[0]
118
+ assert_class ExpressionStatement, model
119
+ assert_class CommaInfixExpression, model.expression
120
+ end
121
+
122
+ def test_empty_stmt
123
+ code = ";"
124
+ model = parse_code(code).statements[0]
125
+ assert_class EmptyStatement, model
126
+ end
127
+
128
+ def test_switch_stmt
129
+ code = %q{
130
+ switch (1) {
131
+ case 2:
132
+ 3;
133
+ break;
134
+ case 4:
135
+ 5;
136
+ break;
137
+ default:
138
+ 6;
139
+ }
140
+ }
141
+ model = parse_code(code).statements[0]
142
+ assert_class SwitchStatement, model
143
+ assert_class NumberLiteral, model.expression
144
+ assert_equal 3, model.cases.count
145
+ assert_class ExpressionSwitchCase, model.cases[0]
146
+ assert_class ExpressionSwitchCase, model.cases[1]
147
+ assert_class DefaultSwitchCase, model.cases[2]
148
+ end
149
+
150
+ end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ class TestExampleApp < Test::Unit::TestCase
4
+
5
+ include TestHelper
6
+ include CodeModels
7
+ include CodeModels::Js
8
+
9
+ def setup
10
+ @root = Js.parse_file(relative_path('data/app.js'))
11
+ end
12
+
13
+ def test_root_is_ast_root
14
+ assert_class AstRoot, @root
15
+ end
16
+
17
+ def test_root_contains_function_call
18
+ assert_equal 1, @root.statements.count
19
+ assert_class ExpressionStatement, @root.statements[0]
20
+ assert_class FunctionCall, @root.statements[0].expression
21
+ end
22
+
23
+ end
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ class TestExpressionParser < Test::Unit::TestCase
4
+
5
+ include TestHelper
6
+ include CodeModels
7
+ include CodeModels::Js
8
+
9
+ def test_basic_expression_parsing
10
+ r = Js::ExpressionParser.parse_code("i < 10")
11
+ assert_equal CodeModels::Js::LANGUAGE,r.language
12
+ assert_class Js::LessInfixExpression,r
13
+ end
14
+
15
+ def test_name_expression_parsing
16
+ r = Js::ExpressionParser.parse_code("pippo")
17
+ assert_equal CodeModels::Js::LANGUAGE,r.language
18
+ assert_class Js::Name,r
19
+ end
20
+
21
+ def test_basic_expression_position
22
+ r = Js::ExpressionParser.parse_code("i < 10")
23
+ assert_equal CodeModels::Js::LANGUAGE,r.language
24
+ assert_equal SourcePoint.new(1,1),r.source.position.begin_point
25
+ assert_equal SourcePoint.new(1,6),r.source.position.end_point
26
+ end
27
+
28
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: UTF-8
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "/test/"
5
+ end
6
+
7
+ require 'test/unit'
8
+ require 'codemodels'
9
+ require 'codemodels/js'
10
+
11
+ module TestHelper
12
+
13
+ include CodeModels
14
+
15
+ def parse_code(code)
16
+ Js.parse_code(code.encode(Parser::DEFAULT_INTERNAL_ENCODING))
17
+ end
18
+
19
+ def assert_metamodel(name,attrs,refs)
20
+ assert Js.const_defined?(name), "Metaclass '#{name}' not found"
21
+ c = Js.const_get name
22
+
23
+ assert_all_attrs attrs, c
24
+ assert_all_refs refs, c
25
+ c
26
+ end
27
+
28
+ def assert_class(expected_class,node)
29
+ assert node.class==expected_class, "Node expected to have class #{expected_class} instead it has class #{node.class}"
30
+ end
31
+
32
+ def relative_path(path)
33
+ File.join(File.dirname(__FILE__),path)
34
+ end
35
+
36
+ def assert_all_attrs(expected,c)
37
+ actual = c.ecore.eAllAttributes
38
+ assert_equal expected.count,actual.count,"Expected #{expected.count} attrs, found #{actual.count}. They are #{actual.name}"
39
+ expected.each do |e|
40
+ assert actual.find {|a| a.name==e}, "Attribute #{e} not found"
41
+ end
42
+ end
43
+
44
+ def assert_all_refs(expected,c)
45
+ actual = c.ecore.eAllReferences
46
+ assert_equal expected.count,actual.count,"Expected #{expected.count} refs, found #{actual.count}. They are #{actual.name}"
47
+ expected.each do |e|
48
+ assert actual.find {|a| a.name==e}, "Reference #{e} not found"
49
+ end
50
+ end
51
+
52
+ def assert_ref(c,name,type,many=false)
53
+ ref = c.ecore.eAllReferences.find {|r| r.name==name}
54
+ assert ref, "Reference '#{name}' not found"
55
+ assert_equal type.ecore.name,ref.eType.name
56
+ assert_equal many, ref.many
57
+ end
58
+
59
+ def assert_attr(c,name,type,many=false)
60
+ att = c.ecore.eAllAttributes.find {|a| a.name==name}
61
+ assert_equal type.name,att.eType.name
62
+ assert_equal many, att.many
63
+ end
64
+
65
+ end
@@ -0,0 +1,169 @@
1
+ # encoding: UTF-8
2
+ #Encoding.default_internal = Encoding::UTF_8
3
+ require 'test_helper'
4
+
5
+ class TestInfoExtraction < Test::Unit::TestCase
6
+
7
+ include TestHelper
8
+ include CodeModels
9
+
10
+ def assert_map(exp,map)
11
+ assert_equal exp.count,map.count, "Expected to have keys: #{exp.keys}, it has #{map}"
12
+ exp.each do |k,v|
13
+ assert_equal exp[k],map[k], "Expected #{k} to have #{exp[k]} instances, it has #{map[k.to_s]}. Map: #{map}"
14
+ end
15
+ end
16
+
17
+ def assert_code_map_to(code,exp)
18
+ r = parse_code(code)
19
+ map = r.values_map
20
+ assert_map(exp,map)
21
+ end
22
+
23
+ def test_info_the_root_is_parsed
24
+ code = "for(var i = 0; i < 10; i++) { var x = 5 + 5; }"
25
+ assert_code_map_to(code, {'i'=> 3, 0.0 => 1, 5.0 => 2, 10.0=> 1, 'x' => 1})
26
+ end
27
+
28
+ def test_info_var_statement
29
+ code = "var i = 0;"
30
+ assert_code_map_to(code, {'i'=> 1, 0.0 => 1})
31
+ end
32
+
33
+ def test_info_less
34
+ code = "i < 10;"
35
+ assert_code_map_to(code, {'i'=> 1, 10.0 => 1})
36
+ end
37
+
38
+ def test_info_postfix
39
+ code = "i++;"
40
+ assert_code_map_to(code, {'i'=> 1})
41
+ end
42
+
43
+ def test_info_block
44
+ code = "{ var x = 5 + 5; }"
45
+ assert_code_map_to(code, {'x'=> 1, 5.0 => 2})
46
+ end
47
+
48
+ def test_snippet_1
49
+ code = "var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};"
50
+ assert_code_map_to(code, {'lowercase'=> 1, 'string' => 4, 'isString' => 1, 'toLowerCase' => 1})
51
+ end
52
+
53
+ def test_snippet_2
54
+ code = %q{
55
+ var manualLowercase = function(s) {
56
+ return isString(s)
57
+ ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
58
+ : s;
59
+ };
60
+ var manualUppercase = function(s) {
61
+ return isString(s)
62
+ ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
63
+ : s;
64
+ };
65
+ }
66
+ assert_code_map_to(code, {
67
+ 'manualLowercase'=> 1, 'manualUppercase'=>1,
68
+ 's' => 8, 'isString' => 2, 'replace' => 2,
69
+ '[A-Z]'=>1, '[a-z]'=>1,
70
+ 'g'=>2, # this is the flag, it should be removed from the AST in the future
71
+ 'ch'=>4, 'String'=>2,
72
+ 'fromCharCode'=>2, 'charCodeAt'=>2,
73
+ 0.0=>2, 32.0=>2})
74
+ end
75
+
76
+ def test_snippet_3
77
+ code = %q{
78
+ 'use strict';
79
+
80
+ // Declare app level module which depends on filters, and services
81
+ angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives']).
82
+ config(['$routeProvider', function($routeProvider) {
83
+ $routeProvider.when('/aes', {template: 'partials/aes.html', controller: aesCtrl});
84
+ $routeProvider.when('/about', {template: 'partials/about.html', controller: homeCtrl});
85
+ //$routeProvider.when('/memorize', {template: 'partials/memorize.html', controller: memorizeCtrl});
86
+ $routeProvider.when('/phrases', {template: 'partials/phrases.html', controller: phrasesCtrl});
87
+ //$routeProvider.when('/about', {template: 'partials/about.html', controller: aboutCtrl});
88
+ $routeProvider.otherwise({redirectTo: '/aes'});
89
+ }]);
90
+ }
91
+ assert_code_map_to(code, {
92
+ 'use strict' => 1,
93
+ 'angular'=>1,
94
+ 'module'=>1,
95
+ 'myApp'=>1,
96
+ 'myApp.filters'=>1,
97
+ 'myApp.services'=>1,
98
+ 'myApp.directives'=>1,
99
+ 'config'=>1,
100
+ '$routeProvider' => 6,
101
+ 'when' => 3,
102
+ 'otherwise'=>1,
103
+ '/aes' =>2, 'partials/aes.html'=>1,
104
+ '/about' =>1, 'partials/about.html'=>1,
105
+ '/phrases' =>1, 'partials/phrases.html'=>1,
106
+ 'template' => 3,
107
+ 'controller' => 3,
108
+ 'aesCtrl' => 1,
109
+ 'homeCtrl' => 1,
110
+ 'phrasesCtrl' => 1,
111
+ 'redirectTo' => 1
112
+ })
113
+ end
114
+
115
+ # def test_encoding_is_supported
116
+ # r = Js.parse_file('test/data/app.js','UTF-8')
117
+ #
118
+ # r.traverse(:also_foreign) do |node|
119
+ # end
120
+ # end
121
+
122
+ def test_no_extraneous_values_simple_encoding
123
+ #code = IO.read('test/data/app.js',{ :encoding => 'UTF-8', :mode => 'rb'})
124
+ r = Js.parse_file('test/data/app_clean.js','UTF-8')
125
+ r.traverse(:also_foreign) do |node|
126
+ node.collect_values_with_count.each do |value,count|
127
+ value_s = value.to_s.encode(Parser::DEFAULT_INTERNAL_ENCODING)
128
+ value_s = value_s[0..-3] if value_s.end_with?('.0')
129
+ node_code = node.source.code.encode(Parser::DEFAULT_INTERNAL_ENCODING)
130
+ unless node_code.include?(value_s)
131
+ node.class.ecore.eAllAttributes.each do |a|
132
+ if a.many
133
+ puts "Attribute #{a.name}" if node.send(:"#{a.name}").include?(value)
134
+ else
135
+ puts "Attribute #{a.name}" if node.send(:"#{a.name}")==value
136
+ end
137
+ end
138
+
139
+ fail("Value '#{value}' expected in #{node}. Artifact: #{node.source.artifact}, abspos: #{node.source.position(:absolute)}, code: '#{node_code}'")
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ def test_no_extraneous_values
146
+ #code = IO.read('test/data/app.js',{ :encoding => 'UTF-8', :mode => 'rb'})
147
+ r = Js.parse_file('test/data/app.js','UTF-8')
148
+ r.traverse(:also_foreign) do |node|
149
+ node.collect_values_with_count.each do |value,count|
150
+ value_s = value.to_s.encode(Parser::DEFAULT_INTERNAL_ENCODING)
151
+ value_s = value_s[0..-3] if value_s.end_with?('.0')
152
+ node_code = node.source.code.encode(Parser::DEFAULT_INTERNAL_ENCODING)
153
+ unless node_code.include?(value_s)
154
+ node.class.ecore.eAllAttributes.each do |a|
155
+ if a.many
156
+ puts "Attribute #{a.name}" if node.send(:"#{a.name}").include?(value)
157
+ else
158
+ puts "Attribute #{a.name}" if node.send(:"#{a.name}")==value
159
+ end
160
+ end
161
+
162
+ fail("Value '#{value}' expected in #{node}. Artifact: #{node.source.artifact}, abspos: #{node.source.position(:absolute)}, code: '#{node_code}'")
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+
169
+ end
@@ -0,0 +1,210 @@
1
+ require 'test_helper'
2
+
3
+ class TestInfoExtraction < Test::Unit::TestCase
4
+
5
+ include TestHelper
6
+ include CodeModels
7
+ include CodeModels::Js
8
+ include RGen::ECore
9
+
10
+ # TODO ArrayComprehension
11
+ # TODO ArrayComprehensionLoop
12
+
13
+ def test_ast_root
14
+ c = assert_metamodel :AstRoot, [], ['statements']
15
+
16
+ assert_ref c, 'statements', JsNode, true
17
+ end
18
+
19
+ def test_array_literal
20
+ assert Js.const_defined? :ArrayLiteral
21
+ c = Js.const_get :ArrayLiteral
22
+
23
+ assert_all_attrs [], c
24
+ assert_all_refs ['elements'], c
25
+
26
+ assert_ref c,'elements',JsNode,true
27
+ end
28
+
29
+ def test_block
30
+ assert Js.const_defined? :Block
31
+ c = Js.const_get :Block
32
+
33
+ assert_all_attrs [], c
34
+ assert_all_refs ['contents'], c
35
+
36
+ assert_ref c,'contents',JsNode,true
37
+ end
38
+
39
+ def test_break
40
+ assert Js.const_defined? :BreakStatement
41
+ c = Js.const_get :BreakStatement
42
+
43
+ # TODO break label and break target maybe should be there
44
+ assert_all_attrs [], c
45
+ assert_all_refs ['breakLabel'], c
46
+
47
+ assert_ref c,'breakLabel',Name
48
+ end
49
+
50
+ def test_catch_clause
51
+ c = assert_metamodel :CatchClause, [], ['varName', 'catchCondition','body']
52
+
53
+ assert_ref c,'varName',Name
54
+ assert_ref c,'catchCondition',JsNode
55
+ assert_ref c,'body',Block
56
+ end
57
+
58
+ def test_conditional_expression
59
+ c = assert_metamodel :ConditionalExpression, [], ['testExpression','trueExpression','falseExpression']
60
+
61
+ assert_ref c,'testExpression',JsNode
62
+ assert_ref c,'trueExpression',JsNode
63
+ assert_ref c,'falseExpression',JsNode
64
+ end
65
+
66
+ def test_continue_statement
67
+ c = assert_metamodel :ContinueStatement, [], ['label']
68
+
69
+ assert_ref c,'label',Name
70
+ end
71
+
72
+ def test_do_loop
73
+ c = assert_metamodel :DoLoop, [], ['body','condition']
74
+
75
+ assert_ref c,'body',JsNode
76
+ assert_ref c,'condition',JsNode
77
+ end
78
+
79
+ def test_function_call
80
+ c = assert_metamodel :FunctionCall, [], ['target','arguments']
81
+
82
+ assert_ref c,'target',JsNode
83
+ assert_ref c,'arguments',JsNode, true
84
+ end
85
+
86
+ def test_get_object_property
87
+ c = assert_metamodel :GetObjectProperty, [], ['name','value']
88
+
89
+ assert_ref c,'name',JsNode
90
+ assert_ref c,'value',JsNode
91
+ end
92
+
93
+ def test_infix_expression
94
+ assert Js.const_defined? :InfixExpression
95
+ c = Js.const_get :InfixExpression
96
+
97
+ assert_all_attrs [], c
98
+ assert_all_refs ['left','right'], c
99
+
100
+ assert_ref c,'left',JsNode
101
+ assert_ref c,'right',JsNode
102
+ end
103
+
104
+ def test_js_node
105
+ assert Js.const_defined? :JsNode
106
+ c = Js.const_get :JsNode
107
+
108
+ assert_all_attrs [], c
109
+ assert_all_refs [], c
110
+ end
111
+
112
+ def test_loop
113
+ c = assert_metamodel :Loop, [], ['body']
114
+
115
+ assert_ref c,'body',JsNode
116
+ end
117
+
118
+ def test_new_expression
119
+ c = assert_metamodel :NewExpression, [], ['initializer','target','arguments']
120
+
121
+ assert_ref c,'initializer',ObjectLiteral
122
+ assert_ref c,'target',JsNode
123
+ assert_ref c,'arguments',JsNode, true
124
+ end
125
+
126
+ def test_number_literal
127
+ c = assert_metamodel :NumberLiteral, ['number'], []
128
+
129
+ assert_attr c,'number',EFloat
130
+ end
131
+
132
+ def test_object_literal
133
+ c = assert_metamodel :ObjectLiteral, [], ['elements']
134
+
135
+ assert_ref c,'elements',ObjectProperty,true
136
+ end
137
+
138
+ def test_object_property
139
+ c = assert_metamodel :ObjectProperty, [], ['name','value']
140
+
141
+ assert_ref c,'name',JsNode
142
+ assert_ref c,'value',JsNode
143
+ end
144
+
145
+ def test_property_get
146
+ assert Js.const_defined? :PropertyGet
147
+ c = Js.const_get :PropertyGet
148
+
149
+ assert_all_attrs [], c
150
+ assert_all_refs ['left','right'], c
151
+
152
+ assert_equal 0,c.ecore.eAttributes.count
153
+ assert_equal 0,c.ecore.eReferences.count
154
+ end
155
+
156
+ def test_set_object_property
157
+ c = assert_metamodel :SetObjectProperty, [], ['name','value']
158
+
159
+ assert_ref c,'name',JsNode
160
+ assert_ref c,'value',JsNode
161
+ end
162
+
163
+ def test_simple_object_property
164
+ c = assert_metamodel :SimpleObjectProperty, [], ['name','value']
165
+
166
+ assert_ref c,'name',JsNode
167
+ assert_ref c,'value',JsNode
168
+ end
169
+
170
+ def test_scope
171
+ c = assert_metamodel :Scope, [], ['statements']
172
+
173
+ assert_ref c,'statements',JsNode, true
174
+ end
175
+
176
+ def test_symbol
177
+ assert Js.const_defined? :Symbol
178
+ c = Js.const_get :Symbol
179
+
180
+ assert_attr c,'declType',EString
181
+ end
182
+
183
+ def test_while_loop
184
+ c = assert_metamodel :WhileLoop, [], ['body','condition']
185
+
186
+ assert_ref c,'body',JsNode
187
+ assert_ref c,'condition',JsNode
188
+ end
189
+
190
+ def test_switch_statement
191
+ c = assert_metamodel :SwitchStatement, [], ['expression','cases']
192
+
193
+ assert_ref c,'expression',JsNode
194
+ assert_ref c,'cases',SwitchCase,true
195
+ end
196
+
197
+ def test_expression_switch_case
198
+ c = assert_metamodel :ExpressionSwitchCase, [], ['expression','statements']
199
+
200
+ assert_ref c,'expression',JsNode
201
+ assert_ref c,'statements',JsNode, true
202
+ end
203
+
204
+ def test_default_switch_case
205
+ c = assert_metamodel :DefaultSwitchCase, [], ['statements']
206
+
207
+ assert_ref c,'statements',JsNode, true
208
+ end
209
+
210
+ end