codemodels-js 0.1.0-java

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.
@@ -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