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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/Gemfile +5 -0
- data/LICENSE +191 -0
- data/README.md +4 -0
- data/Rakefile +10 -0
- data/codemodels-js.gemspec +28 -0
- data/lib/codemodels/js/language.rb +19 -0
- data/lib/codemodels/js/metamodel.rb +586 -0
- data/lib/codemodels/js/model_building.rb +33 -0
- data/lib/codemodels/js/parser.rb +227 -0
- data/lib/codemodels/js/version.rb +6 -0
- data/lib/codemodels/js.rb +6 -0
- data/lib/jars/js.jar +0 -0
- data/test/data/app.js +66 -0
- data/test/data/app_clean.js +66 -0
- data/test/test_basic_node_properties.rb +52 -0
- data/test/test_basic_parsing.rb +150 -0
- data/test/test_example_app.rb +23 -0
- data/test/test_expression_parser.rb +28 -0
- data/test/test_helper.rb +65 -0
- data/test/test_info_extraction.rb +169 -0
- data/test/test_metamodel.rb +210 -0
- metadata +145 -0
@@ -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
|
data/test/test_helper.rb
ADDED
@@ -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
|