puppet 4.4.2 → 4.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CONTRIBUTING.md +5 -5
- data/Gemfile +2 -2
- data/LICENSE +2 -2
- data/README.md +5 -0
- data/ext/project_data.yaml +2 -0
- data/lib/hiera_puppet.rb +6 -14
- data/lib/puppet/application/agent.rb +2 -3
- data/lib/puppet/data_providers/hiera_config.rb +2 -4
- data/lib/puppet/data_providers/hiera_interpolate.rb +12 -154
- data/lib/puppet/data_providers/json_data_provider_factory.rb +0 -7
- data/lib/puppet/data_providers/yaml_data_provider_factory.rb +2 -8
- data/lib/puppet/defaults.rb +70 -7
- data/lib/puppet/functions.rb +69 -0
- data/lib/puppet/functions/dig.rb +39 -0
- data/lib/puppet/functions/lest.rb +53 -0
- data/lib/puppet/functions/lookup.rb +40 -27
- data/lib/puppet/functions/new.rb +502 -0
- data/lib/puppet/functions/regsubst.rb +11 -10
- data/lib/puppet/functions/then.rb +74 -0
- data/lib/puppet/functions/type.rb +4 -4
- data/lib/puppet/functions/with.rb +1 -1
- data/lib/puppet/indirector/catalog/compiler.rb +2 -0
- data/lib/puppet/indirector/resource_type/parser.rb +5 -0
- data/lib/puppet/indirector/rest.rb +5 -1
- data/lib/puppet/loaders.rb +2 -0
- data/lib/puppet/metatype/manager.rb +19 -2
- data/lib/puppet/module_tool/applications/application.rb +1 -1
- data/lib/puppet/module_tool/skeleton/templates/generator/Gemfile +6 -2
- data/lib/puppet/module_tool/skeleton/templates/generator/Rakefile +19 -4
- data/lib/puppet/module_tool/skeleton/templates/generator/{tests → examples}/init.pp.erb +1 -1
- data/lib/puppet/module_tool/skeleton/templates/generator/spec/classes/init_spec.rb.erb +0 -1
- data/lib/puppet/network/http/api/master/v3/environment.rb +6 -2
- data/lib/puppet/parser/ast/pops_bridge.rb +20 -3
- data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +24 -2
- data/lib/puppet/parser/e4_parser_adapter.rb +13 -12
- data/lib/puppet/parser/environment_compiler.rb +2 -2
- data/lib/puppet/parser/resource.rb +14 -5
- data/lib/puppet/parser/scope.rb +18 -15
- data/lib/puppet/plugins/data_providers/data_provider.rb +19 -8
- data/lib/puppet/pops.rb +6 -0
- data/lib/puppet/pops/adapters.rb +5 -1
- data/lib/puppet/pops/evaluator/access_operator.rb +52 -14
- data/lib/puppet/pops/evaluator/compare_operator.rb +34 -4
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +75 -22
- data/lib/puppet/pops/evaluator/literal_evaluator.rb +7 -6
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +13 -1
- data/lib/puppet/pops/evaluator/runtime3_support.rb +14 -4
- data/lib/puppet/pops/functions/dispatcher.rb +1 -1
- data/lib/puppet/pops/issues.rb +18 -2
- data/lib/puppet/pops/loader/base_loader.rb +48 -7
- data/lib/puppet/pops/loader/dependency_loader.rb +27 -2
- data/lib/puppet/pops/loader/loader.rb +12 -0
- data/lib/puppet/pops/loader/predefined_loader.rb +29 -0
- data/lib/puppet/pops/loader/runtime3_type_loader.rb +57 -0
- data/lib/puppet/pops/loader/static_loader.rb +92 -5
- data/lib/puppet/pops/loader/type_definition_instantiator.rb +25 -3
- data/lib/puppet/pops/loaders.rb +84 -14
- data/lib/puppet/pops/lookup/explainer.rb +38 -1
- data/lib/puppet/pops/lookup/interpolation.rb +115 -0
- data/lib/puppet/pops/lookup/sub_lookup.rb +86 -0
- data/lib/puppet/pops/model/ast_transformer.rb +8 -1
- data/lib/puppet/pops/model/factory.rb +31 -8
- data/lib/puppet/pops/model/model.rb +8 -0
- data/lib/puppet/pops/model/model_label_provider.rb +1 -0
- data/lib/puppet/pops/model/model_meta.rb +7 -1
- data/lib/puppet/pops/model/model_tree_dumper.rb +4 -0
- data/lib/puppet/pops/parser/egrammar.ra +24 -7
- data/lib/puppet/pops/parser/eparser.rb +863 -798
- data/lib/puppet/pops/parser/evaluating_parser.rb +4 -0
- data/lib/puppet/pops/parser/locator.rb +8 -4
- data/lib/puppet/pops/pcore.rb +30 -0
- data/lib/puppet/pops/types/class_loader.rb +2 -4
- data/lib/puppet/pops/types/implementation_registry.rb +146 -0
- data/lib/puppet/pops/types/iterable.rb +4 -4
- data/lib/puppet/pops/types/p_object_type.rb +846 -0
- data/lib/puppet/pops/types/p_runtime_type.rb +102 -0
- data/lib/puppet/pops/types/p_sem_ver_range_type.rb +164 -0
- data/lib/puppet/pops/types/p_sem_ver_type.rb +113 -0
- data/lib/puppet/pops/types/puppet_object.rb +21 -0
- data/lib/puppet/pops/types/ruby_generator.rb +258 -0
- data/lib/puppet/pops/types/string_converter.rb +922 -0
- data/lib/puppet/pops/types/type_calculator.rb +29 -5
- data/lib/puppet/pops/types/type_conversion_error.rb +15 -0
- data/lib/puppet/pops/types/type_factory.rb +49 -16
- data/lib/puppet/pops/types/type_formatter.rb +335 -112
- data/lib/puppet/pops/types/type_mismatch_describer.rb +110 -29
- data/lib/puppet/pops/types/type_parser.rb +205 -197
- data/lib/puppet/pops/types/types.rb +481 -103
- data/lib/puppet/pops/validation.rb +1 -1
- data/lib/puppet/pops/validation/checker4_0.rb +66 -4
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
- data/lib/puppet/pops/visitor.rb +3 -1
- data/lib/puppet/property.rb +1 -1
- data/lib/puppet/provider/augeas/augeas.rb +1 -1
- data/lib/puppet/provider/package/pip.rb +64 -20
- data/lib/puppet/provider/package/rpm.rb +112 -0
- data/lib/puppet/provider/package/yum.rb +7 -68
- data/lib/puppet/provider/service/daemontools.rb +3 -3
- data/lib/puppet/provider/service/init.rb +4 -2
- data/lib/puppet/provider/service/runit.rb +3 -3
- data/lib/puppet/provider/service/smf.rb +6 -3
- data/lib/puppet/provider/service/systemd.rb +59 -73
- data/lib/puppet/reference/providers.rb +1 -2
- data/lib/puppet/resource.rb +54 -37
- data/lib/puppet/resource/catalog.rb +31 -29
- data/lib/puppet/resource/type_collection.rb +23 -8
- data/lib/puppet/settings.rb +4 -2
- data/lib/puppet/settings/base_setting.rb +9 -3
- data/lib/puppet/settings/symbolic_enum_setting.rb +17 -0
- data/lib/puppet/test/test_helper.rb +0 -1
- data/lib/puppet/type.rb +9 -3
- data/lib/puppet/type/exec.rb +17 -17
- data/lib/puppet/type/file.rb +12 -0
- data/lib/puppet/type/file/content.rb +6 -6
- data/lib/puppet/type/file/ensure.rb +4 -4
- data/lib/puppet/type/file/source.rb +4 -4
- data/lib/puppet/type/file/target.rb +2 -2
- data/lib/puppet/type/mount.rb +18 -1
- data/lib/puppet/type/package.rb +3 -3
- data/lib/puppet/type/schedule.rb +4 -4
- data/lib/puppet/type/service.rb +15 -0
- data/lib/puppet/type/sshkey.rb +5 -3
- data/lib/puppet/type/tidy.rb +3 -3
- data/lib/puppet/type/zone.rb +5 -5
- data/lib/puppet/util/feature.rb +1 -1
- data/lib/puppet/util/monkey_patches.rb +8 -0
- data/lib/puppet/util/network_device/cisco/device.rb +16 -6
- data/lib/puppet/util/network_device/cisco/interface.rb +5 -6
- data/lib/puppet/util/plist.rb +3 -3
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/unit/application/environments/production/data/common.yaml +13 -0
- data/spec/fixtures/unit/data_providers/environments/production/modules/abc/lib/puppet/functions/abc/data.rb +2 -1
- data/spec/fixtures/unit/data_providers/environments/production/modules/abc/manifests/init.pp +2 -1
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_json/data/empty_key.json +1 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_json/hiera.yaml +5 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_json/manifests/init.pp +2 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_json/metadata.json +9 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_yaml/data/empty_key.yaml +1 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_yaml/hiera.yaml +5 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_yaml/manifests/init.pp +2 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_key_yaml/metadata.json +9 -0
- data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_yaml/data/empty.yaml +1 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/usee/lib/puppet/type/usee_type.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/manifests/init.pp +6 -0
- data/spec/fixtures/unit/provider/service/smf/svcs.out +4 -3
- data/spec/integration/module_tool/tar/mini_spec.rb +27 -27
- data/spec/integration/parser/catalog_spec.rb +14 -2
- data/spec/integration/parser/compiler_spec.rb +94 -3
- data/spec/integration/parser/resource_expressions_spec.rb +1 -1
- data/spec/integration/resource/type_collection_spec.rb +8 -0
- data/spec/lib/puppet_spec/compiler.rb +11 -4
- data/spec/shared_contexts/types_setup.rb +4 -0
- data/spec/unit/application/lookup_spec.rb +91 -9
- data/spec/unit/appmgmt_spec.rb +44 -35
- data/spec/unit/capability_spec.rb +33 -53
- data/spec/unit/data_providers/function_data_provider_spec.rb +19 -1
- data/spec/unit/data_providers/hiera_data_provider_spec.rb +1 -1
- data/spec/unit/defaults_spec.rb +18 -0
- data/spec/unit/functions/assert_type_spec.rb +1 -1
- data/spec/unit/functions/dig_spec.rb +58 -0
- data/spec/unit/functions/lest_spec.rb +34 -0
- data/spec/unit/functions/lookup_spec.rb +108 -2
- data/spec/unit/functions/new_spec.rb +543 -0
- data/spec/unit/functions/regsubst_spec.rb +8 -0
- data/spec/unit/functions/then_spec.rb +40 -0
- data/spec/unit/functions4_spec.rb +78 -10
- data/spec/unit/hiera_puppet_spec.rb +49 -8
- data/spec/unit/indirector/resource_type/parser_spec.rb +5 -0
- data/spec/unit/indirector/rest_spec.rb +12 -0
- data/spec/unit/network/http/api/master/v3/environment_spec.rb +60 -0
- data/spec/unit/node/environment_spec.rb +10 -0
- data/spec/unit/parser/compiler_spec.rb +20 -1
- data/spec/unit/parser/functions/create_resources_spec.rb +2 -2
- data/spec/unit/parser/functions/shared.rb +1 -1
- data/spec/unit/parser/resource_spec.rb +8 -1
- data/spec/unit/parser/scope_spec.rb +45 -0
- data/spec/unit/pops/evaluator/access_ops_spec.rb +14 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +13 -5
- data/spec/unit/pops/loaders/static_loader_spec.rb +92 -1
- data/spec/unit/{data_providers/hiera_interpolation_spec.rb → pops/lookup/interpolation_spec.rb} +7 -5
- data/spec/unit/pops/parser/lexer2_spec.rb +2 -9
- data/spec/unit/pops/parser/parse_application_spec.rb +3 -8
- data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +19 -0
- data/spec/unit/pops/parser/parse_capabilities_spec.rb +3 -10
- data/spec/unit/pops/parser/parse_site_spec.rb +19 -10
- data/spec/unit/pops/parser/parser_rspec_helper.rb +0 -4
- data/spec/unit/pops/types/enumeration_spec.rb +13 -12
- data/spec/unit/pops/types/iterable_spec.rb +2 -2
- data/spec/unit/pops/types/p_object_type_spec.rb +1060 -0
- data/spec/unit/pops/types/p_sem_ver_type_spec.rb +285 -0
- data/spec/unit/pops/types/recursion_guard_spec.rb +19 -17
- data/spec/unit/pops/types/ruby_generator_spec.rb +261 -0
- data/spec/unit/pops/types/string_converter_spec.rb +904 -0
- data/spec/unit/pops/types/type_calculator_spec.rb +430 -406
- data/spec/unit/pops/types/type_factory_spec.rb +119 -104
- data/spec/unit/pops/types/type_formatter_spec.rb +73 -6
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +2 -2
- data/spec/unit/pops/types/type_parser_spec.rb +54 -15
- data/spec/unit/pops/types/types_spec.rb +113 -8
- data/spec/unit/pops/validator/validator_spec.rb +84 -10
- data/spec/unit/provider/package/pip3_spec.rb +9 -270
- data/spec/unit/provider/package/pip_spec.rb +85 -30
- data/spec/unit/provider/package/rpm_spec.rb +160 -3
- data/spec/unit/provider/package/yum_spec.rb +23 -134
- data/spec/unit/provider/service/smf_spec.rb +14 -2
- data/spec/unit/provider/service/systemd_spec.rb +33 -41
- data/spec/unit/resource/capability_finder_spec.rb +10 -2
- data/spec/unit/settings/file_setting_spec.rb +6 -0
- data/spec/unit/transaction/additional_resource_generator_spec.rb +80 -65
- data/spec/unit/type/mount_spec.rb +51 -10
- data/spec/unit/type/service_spec.rb +16 -0
- data/spec/unit/type_spec.rb +14 -0
- data/spec/unit/util/feature_spec.rb +1 -1
- data/spec/unit/util/monkey_patches_spec.rb +60 -0
- data/spec/unit/util/network_device/cisco/device_spec.rb +1 -1
- metadata +63 -11
- data/lib/puppet/pops/types/types_meta.rb +0 -0
- data/spec/integration/provider/package_spec.rb +0 -35
@@ -1,60 +1,62 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'puppet/pops'
|
3
3
|
|
4
|
+
module Puppet::Pops
|
5
|
+
module Types
|
4
6
|
describe 'The type calculator' do
|
5
|
-
let(:calculator) {
|
7
|
+
let(:calculator) { TypeCalculator.new }
|
6
8
|
|
7
9
|
def range_t(from, to)
|
8
|
-
|
10
|
+
PIntegerType.new(from, to)
|
9
11
|
end
|
10
12
|
|
11
13
|
def pattern_t(*patterns)
|
12
|
-
|
14
|
+
TypeFactory.pattern(*patterns)
|
13
15
|
end
|
14
16
|
|
15
17
|
def regexp_t(pattern)
|
16
|
-
|
18
|
+
TypeFactory.regexp(pattern)
|
17
19
|
end
|
18
20
|
|
19
21
|
def string_t(*strings)
|
20
|
-
|
22
|
+
TypeFactory.string(nil, *strings)
|
21
23
|
end
|
22
24
|
|
23
25
|
def constrained_string_t(size_type, *strings)
|
24
|
-
|
26
|
+
TypeFactory.string(size_type, *strings)
|
25
27
|
end
|
26
28
|
|
27
29
|
def callable_t(*params)
|
28
|
-
|
30
|
+
TypeFactory.callable(*params)
|
29
31
|
end
|
30
32
|
|
31
33
|
def all_callables_t
|
32
|
-
|
34
|
+
TypeFactory.all_callables
|
33
35
|
end
|
34
36
|
|
35
37
|
def enum_t(*strings)
|
36
|
-
|
38
|
+
TypeFactory.enum(*strings)
|
37
39
|
end
|
38
40
|
|
39
41
|
def variant_t(*types)
|
40
|
-
|
42
|
+
TypeFactory.variant(*types)
|
41
43
|
end
|
42
44
|
|
43
45
|
def type_alias_t(name, type_string)
|
44
|
-
type_expr =
|
45
|
-
|
46
|
+
type_expr = Parser::EvaluatingParser.new.parse_string(type_string).current
|
47
|
+
TypeFactory.type_alias(name, type_expr)
|
46
48
|
end
|
47
49
|
|
48
|
-
def type_reference_t(
|
49
|
-
|
50
|
+
def type_reference_t(type_string)
|
51
|
+
TypeFactory.type_reference(type_string)
|
50
52
|
end
|
51
53
|
|
52
54
|
def integer_t
|
53
|
-
|
55
|
+
TypeFactory.integer
|
54
56
|
end
|
55
57
|
|
56
58
|
def array_t(t, s = nil)
|
57
|
-
|
59
|
+
TypeFactory.array_of(t, s)
|
58
60
|
end
|
59
61
|
|
60
62
|
def empty_array_t
|
@@ -62,257 +64,282 @@ describe 'The type calculator' do
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def hash_t(k,v,s = nil)
|
65
|
-
|
67
|
+
TypeFactory.hash_of(v, k, s)
|
66
68
|
end
|
67
69
|
|
68
70
|
def data_t
|
69
|
-
|
71
|
+
TypeFactory.data
|
70
72
|
end
|
71
73
|
|
72
74
|
def factory
|
73
|
-
|
75
|
+
TypeFactory
|
74
76
|
end
|
75
77
|
|
76
78
|
def collection_t(size_type = nil)
|
77
|
-
|
79
|
+
TypeFactory.collection(size_type)
|
78
80
|
end
|
79
81
|
|
80
82
|
def tuple_t(*types)
|
81
|
-
|
83
|
+
TypeFactory.tuple(types)
|
82
84
|
end
|
83
85
|
|
84
86
|
def constrained_tuple_t(size_type, *types)
|
85
|
-
|
87
|
+
TypeFactory.tuple(types, size_type)
|
86
88
|
end
|
87
89
|
|
88
90
|
def struct_t(type_hash)
|
89
|
-
|
91
|
+
TypeFactory.struct(type_hash)
|
90
92
|
end
|
91
93
|
|
92
94
|
def object_t
|
93
|
-
|
95
|
+
TypeFactory.any
|
94
96
|
end
|
95
97
|
|
96
98
|
def optional_t(t)
|
97
|
-
|
99
|
+
TypeFactory.optional(t)
|
98
100
|
end
|
99
101
|
|
100
102
|
def type_t(t)
|
101
|
-
|
103
|
+
TypeFactory.type_type(t)
|
102
104
|
end
|
103
105
|
|
104
106
|
def not_undef_t(t = nil)
|
105
|
-
|
107
|
+
TypeFactory.not_undef(t)
|
106
108
|
end
|
107
109
|
|
108
110
|
def undef_t
|
109
|
-
|
111
|
+
TypeFactory.undef
|
110
112
|
end
|
111
113
|
|
112
114
|
def unit_t
|
113
115
|
# Cannot be created via factory, the type is private to the type system
|
114
|
-
|
116
|
+
PUnitType::DEFAULT
|
115
117
|
end
|
116
118
|
|
117
119
|
def types
|
118
|
-
|
120
|
+
Types
|
119
121
|
end
|
120
122
|
|
121
123
|
context 'when inferring ruby' do
|
122
124
|
|
123
125
|
it 'fixnum translates to PIntegerType' do
|
124
|
-
expect(calculator.infer(1).class).to eq(
|
126
|
+
expect(calculator.infer(1).class).to eq(PIntegerType)
|
125
127
|
end
|
126
128
|
|
127
129
|
it 'large fixnum (or bignum depending on architecture) translates to PIntegerType' do
|
128
|
-
expect(calculator.infer(2**33).class).to eq(
|
130
|
+
expect(calculator.infer(2**33).class).to eq(PIntegerType)
|
129
131
|
end
|
130
132
|
|
131
133
|
it 'float translates to PFloatType' do
|
132
|
-
expect(calculator.infer(1.3).class).to eq(
|
134
|
+
expect(calculator.infer(1.3).class).to eq(PFloatType)
|
133
135
|
end
|
134
136
|
|
135
137
|
it 'string translates to PStringType' do
|
136
|
-
expect(calculator.infer('foo').class).to eq(
|
138
|
+
expect(calculator.infer('foo').class).to eq(PStringType)
|
137
139
|
end
|
138
140
|
|
139
141
|
it 'inferred string type knows the string value' do
|
140
142
|
t = calculator.infer('foo')
|
141
|
-
expect(t.class).to eq(
|
143
|
+
expect(t.class).to eq(PStringType)
|
142
144
|
expect(t.values).to eq(['foo'])
|
143
145
|
end
|
144
146
|
|
145
147
|
it 'boolean true translates to PBooleanType' do
|
146
|
-
expect(calculator.infer(true).class).to eq(
|
148
|
+
expect(calculator.infer(true).class).to eq(PBooleanType)
|
147
149
|
end
|
148
150
|
|
149
151
|
it 'boolean false translates to PBooleanType' do
|
150
|
-
expect(calculator.infer(false).class).to eq(
|
152
|
+
expect(calculator.infer(false).class).to eq(PBooleanType)
|
151
153
|
end
|
152
154
|
|
153
155
|
it 'regexp translates to PRegexpType' do
|
154
|
-
expect(calculator.infer(/^a regular expression$/).class).to eq(
|
156
|
+
expect(calculator.infer(/^a regular expression$/).class).to eq(PRegexpType)
|
155
157
|
end
|
156
158
|
|
157
159
|
it 'iterable translates to PIteratorType' do
|
158
|
-
expect(calculator.infer(
|
160
|
+
expect(calculator.infer(Iterable.on(1))).to be_a(PIteratorType)
|
159
161
|
end
|
160
162
|
|
161
163
|
it 'nil translates to PUndefType' do
|
162
|
-
expect(calculator.infer(nil).class).to eq(
|
164
|
+
expect(calculator.infer(nil).class).to eq(PUndefType)
|
163
165
|
end
|
164
166
|
|
165
167
|
it ':undef translates to PUndefType' do
|
166
|
-
expect(calculator.infer(:undef).class).to eq(
|
168
|
+
expect(calculator.infer(:undef).class).to eq(PUndefType)
|
167
169
|
end
|
168
170
|
|
169
171
|
it 'an instance of class Foo translates to PRuntimeType[ruby, Foo]' do
|
170
|
-
|
172
|
+
::Foo = Class.new
|
173
|
+
begin
|
174
|
+
t = calculator.infer(::Foo.new)
|
175
|
+
expect(t.class).to eq(PRuntimeType)
|
176
|
+
expect(t.runtime).to eq(:ruby)
|
177
|
+
expect(t.runtime_type_name).to eq('Foo')
|
178
|
+
ensure
|
179
|
+
Object.send(:remove_const, :Foo)
|
171
180
|
end
|
172
|
-
|
173
|
-
t = calculator.infer(Foo.new)
|
174
|
-
expect(t.class).to eq(Puppet::Pops::Types::PRuntimeType)
|
175
|
-
expect(t.runtime).to eq(:ruby)
|
176
|
-
expect(t.runtime_type_name).to eq('Foo')
|
177
181
|
end
|
178
182
|
|
179
183
|
it 'Class Foo translates to PType[PRuntimeType[ruby, Foo]]' do
|
180
|
-
|
184
|
+
::Foo = Class.new
|
185
|
+
begin
|
186
|
+
t = calculator.infer(::Foo)
|
187
|
+
expect(t.class).to eq(PType)
|
188
|
+
tt = t.type
|
189
|
+
expect(tt.class).to eq(PRuntimeType)
|
190
|
+
expect(tt.runtime).to eq(:ruby)
|
191
|
+
expect(tt.runtime_type_name).to eq('Foo')
|
192
|
+
ensure
|
193
|
+
Object.send(:remove_const, :Foo)
|
181
194
|
end
|
182
|
-
|
183
|
-
t = calculator.infer(Foo)
|
184
|
-
expect(t.class).to eq(Puppet::Pops::Types::PType)
|
185
|
-
tt = t.type
|
186
|
-
expect(tt.class).to eq(Puppet::Pops::Types::PRuntimeType)
|
187
|
-
expect(tt.runtime).to eq(:ruby)
|
188
|
-
expect(tt.runtime_type_name).to eq('Foo')
|
189
195
|
end
|
190
196
|
|
191
197
|
it 'Module FooModule translates to PType[PRuntimeType[ruby, FooModule]]' do
|
192
|
-
|
198
|
+
::FooModule = Module.new
|
199
|
+
begin
|
200
|
+
t = calculator.infer(::FooModule)
|
201
|
+
expect(t.class).to eq(PType)
|
202
|
+
tt = t.type
|
203
|
+
expect(tt.class).to eq(PRuntimeType)
|
204
|
+
expect(tt.runtime).to eq(:ruby)
|
205
|
+
expect(tt.runtime_type_name).to eq('FooModule')
|
206
|
+
ensure
|
207
|
+
Object.send(:remove_const, :FooModule)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context 'version' do
|
212
|
+
it 'translates to PVersionType' do
|
213
|
+
expect(calculator.infer(Semantic::Version.new(1,0,0)).class).to eq(PSemVerType)
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'range translates to PVersionRangeType' do
|
217
|
+
expect(calculator.infer(Semantic::VersionRange.parse('1.x')).class).to eq(PSemVerRangeType)
|
193
218
|
end
|
194
219
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
220
|
+
it 'translates to a limited PVersionType by infer_set' do
|
221
|
+
v = Semantic::Version.new(1,0,0)
|
222
|
+
t = calculator.infer_set(v)
|
223
|
+
expect(t.class).to eq(PSemVerType)
|
224
|
+
expect(t.ranges.size).to eq(1)
|
225
|
+
expect(t.ranges[0].min).to eq(v)
|
226
|
+
expect(t.ranges[0].max).to eq(v)
|
227
|
+
end
|
201
228
|
end
|
202
229
|
|
203
230
|
context 'array' do
|
204
231
|
it 'translates to PArrayType' do
|
205
|
-
expect(calculator.infer([1,2]).class).to eq(
|
232
|
+
expect(calculator.infer([1,2]).class).to eq(PArrayType)
|
206
233
|
end
|
207
234
|
|
208
235
|
it 'with fixnum values translates to PArrayType[PIntegerType]' do
|
209
|
-
expect(calculator.infer([1,2]).element_type.class).to eq(
|
236
|
+
expect(calculator.infer([1,2]).element_type.class).to eq(PIntegerType)
|
210
237
|
end
|
211
238
|
|
212
239
|
it 'with 32 and 64 bit integer values translates to PArrayType[PIntegerType]' do
|
213
|
-
expect(calculator.infer([1,2**33]).element_type.class).to eq(
|
240
|
+
expect(calculator.infer([1,2**33]).element_type.class).to eq(PIntegerType)
|
214
241
|
end
|
215
242
|
|
216
243
|
it 'Range of integer values are computed' do
|
217
244
|
t = calculator.infer([-3,0,42]).element_type
|
218
|
-
expect(t.class).to eq(
|
245
|
+
expect(t.class).to eq(PIntegerType)
|
219
246
|
expect(t.from).to eq(-3)
|
220
247
|
expect(t.to).to eq(42)
|
221
248
|
end
|
222
249
|
|
223
250
|
it 'Compound string values are computed' do
|
224
251
|
t = calculator.infer(['a','b', 'c']).element_type
|
225
|
-
expect(t.class).to eq(
|
252
|
+
expect(t.class).to eq(PStringType)
|
226
253
|
expect(t.values).to eq(['a', 'b', 'c'])
|
227
254
|
end
|
228
255
|
|
229
256
|
it 'with fixnum and float values translates to PArrayType[PNumericType]' do
|
230
|
-
expect(calculator.infer([1,2.0]).element_type.class).to eq(
|
257
|
+
expect(calculator.infer([1,2.0]).element_type.class).to eq(PNumericType)
|
231
258
|
end
|
232
259
|
|
233
260
|
it 'with fixnum and string values translates to PArrayType[PScalarType]' do
|
234
|
-
expect(calculator.infer([1,'two']).element_type.class).to eq(
|
261
|
+
expect(calculator.infer([1,'two']).element_type.class).to eq(PScalarType)
|
235
262
|
end
|
236
263
|
|
237
264
|
it 'with float and string values translates to PArrayType[PScalarType]' do
|
238
|
-
expect(calculator.infer([1.0,'two']).element_type.class).to eq(
|
265
|
+
expect(calculator.infer([1.0,'two']).element_type.class).to eq(PScalarType)
|
239
266
|
end
|
240
267
|
|
241
268
|
it 'with fixnum, float, and string values translates to PArrayType[PScalarType]' do
|
242
|
-
expect(calculator.infer([1, 2.0,'two']).element_type.class).to eq(
|
269
|
+
expect(calculator.infer([1, 2.0,'two']).element_type.class).to eq(PScalarType)
|
243
270
|
end
|
244
271
|
|
245
272
|
it 'with fixnum and regexp values translates to PArrayType[PScalarType]' do
|
246
|
-
expect(calculator.infer([1, /two/]).element_type.class).to eq(
|
273
|
+
expect(calculator.infer([1, /two/]).element_type.class).to eq(PScalarType)
|
247
274
|
end
|
248
275
|
|
249
276
|
it 'with string and regexp values translates to PArrayType[PScalarType]' do
|
250
|
-
expect(calculator.infer(['one', /two/]).element_type.class).to eq(
|
277
|
+
expect(calculator.infer(['one', /two/]).element_type.class).to eq(PScalarType)
|
251
278
|
end
|
252
279
|
|
253
280
|
it 'with string and symbol values translates to PArrayType[PAnyType]' do
|
254
|
-
expect(calculator.infer(['one', :two]).element_type.class).to eq(
|
281
|
+
expect(calculator.infer(['one', :two]).element_type.class).to eq(PAnyType)
|
255
282
|
end
|
256
283
|
|
257
284
|
it 'with fixnum and nil values translates to PArrayType[PIntegerType]' do
|
258
|
-
expect(calculator.infer([1, nil]).element_type.class).to eq(
|
285
|
+
expect(calculator.infer([1, nil]).element_type.class).to eq(PIntegerType)
|
259
286
|
end
|
260
287
|
|
261
288
|
it 'with arrays of string values translates to PArrayType[PArrayType[PStringType]]' do
|
262
289
|
et = calculator.infer([['first' 'array'], ['second','array']])
|
263
|
-
expect(et.class).to eq(
|
290
|
+
expect(et.class).to eq(PArrayType)
|
264
291
|
et = et.element_type
|
265
|
-
expect(et.class).to eq(
|
292
|
+
expect(et.class).to eq(PArrayType)
|
266
293
|
et = et.element_type
|
267
|
-
expect(et.class).to eq(
|
294
|
+
expect(et.class).to eq(PStringType)
|
268
295
|
end
|
269
296
|
|
270
297
|
it 'with array of string values and array of fixnums translates to PArrayType[PArrayType[PScalarType]]' do
|
271
298
|
et = calculator.infer([['first' 'array'], [1,2]])
|
272
|
-
expect(et.class).to eq(
|
299
|
+
expect(et.class).to eq(PArrayType)
|
273
300
|
et = et.element_type
|
274
|
-
expect(et.class).to eq(
|
301
|
+
expect(et.class).to eq(PArrayType)
|
275
302
|
et = et.element_type
|
276
|
-
expect(et.class).to eq(
|
303
|
+
expect(et.class).to eq(PScalarType)
|
277
304
|
end
|
278
305
|
|
279
306
|
it 'with hashes of string values translates to PArrayType[PHashType[PStringType]]' do
|
280
307
|
et = calculator.infer([{:first => 'first', :second => 'second' }, {:first => 'first', :second => 'second' }])
|
281
|
-
expect(et.class).to eq(
|
308
|
+
expect(et.class).to eq(PArrayType)
|
282
309
|
et = et.element_type
|
283
|
-
expect(et.class).to eq(
|
310
|
+
expect(et.class).to eq(PHashType)
|
284
311
|
et = et.element_type
|
285
|
-
expect(et.class).to eq(
|
312
|
+
expect(et.class).to eq(PStringType)
|
286
313
|
end
|
287
314
|
|
288
315
|
it 'with hash of string values and hash of fixnums translates to PArrayType[PHashType[PScalarType]]' do
|
289
316
|
et = calculator.infer([{:first => 'first', :second => 'second' }, {:first => 1, :second => 2 }])
|
290
|
-
expect(et.class).to eq(
|
317
|
+
expect(et.class).to eq(PArrayType)
|
291
318
|
et = et.element_type
|
292
|
-
expect(et.class).to eq(
|
319
|
+
expect(et.class).to eq(PHashType)
|
293
320
|
et = et.element_type
|
294
|
-
expect(et.class).to eq(
|
321
|
+
expect(et.class).to eq(PScalarType)
|
295
322
|
end
|
296
323
|
end
|
297
324
|
|
298
325
|
context 'hash' do
|
299
326
|
it 'translates to PHashType' do
|
300
|
-
expect(calculator.infer({:first => 1, :second => 2}).class).to eq(
|
327
|
+
expect(calculator.infer({:first => 1, :second => 2}).class).to eq(PHashType)
|
301
328
|
end
|
302
329
|
|
303
330
|
it 'with symbolic keys translates to PHashType[PRuntimeType[ruby, Symbol], value]' do
|
304
331
|
k = calculator.infer({:first => 1, :second => 2}).key_type
|
305
|
-
expect(k.class).to eq(
|
332
|
+
expect(k.class).to eq(PRuntimeType)
|
306
333
|
expect(k.runtime).to eq(:ruby)
|
307
334
|
expect(k.runtime_type_name).to eq('Symbol')
|
308
335
|
end
|
309
336
|
|
310
337
|
it 'with string keys translates to PHashType[PStringType, value]' do
|
311
|
-
expect(calculator.infer({'first' => 1, 'second' => 2}).key_type.class).to eq(
|
338
|
+
expect(calculator.infer({'first' => 1, 'second' => 2}).key_type.class).to eq(PStringType)
|
312
339
|
end
|
313
340
|
|
314
341
|
it 'with fixnum values translates to PHashType[key, PIntegerType]' do
|
315
|
-
expect(calculator.infer({:first => 1, :second => 2}).element_type.class).to eq(
|
342
|
+
expect(calculator.infer({:first => 1, :second => 2}).element_type.class).to eq(PIntegerType)
|
316
343
|
end
|
317
344
|
|
318
345
|
it 'when empty infers a type that answers true to is_the_empty_hash?' do
|
@@ -331,28 +358,28 @@ describe 'The type calculator' do
|
|
331
358
|
context 'using infer_set' do
|
332
359
|
it "with 'first' and 'second' keys translates to PStructType[{first=>value,second=>value}]" do
|
333
360
|
t = calculator.infer_set({'first' => 1, 'second' => 2})
|
334
|
-
expect(t.class).to eq(
|
361
|
+
expect(t.class).to eq(PStructType)
|
335
362
|
expect(t.elements.size).to eq(2)
|
336
363
|
expect(t.elements.map { |e| e.name }.sort).to eq(['first', 'second'])
|
337
364
|
end
|
338
365
|
|
339
366
|
it 'with string keys and string and array values translates to PStructType[{key1=>PStringType,key2=>PTupleType}]' do
|
340
367
|
t = calculator.infer_set({ 'mode' => 'read', 'path' => ['foo', 'fee' ] })
|
341
|
-
expect(t.class).to eq(
|
368
|
+
expect(t.class).to eq(PStructType)
|
342
369
|
expect(t.elements.size).to eq(2)
|
343
370
|
els = t.elements.map { |e| e.value_type }.sort {|a,b| a.to_s <=> b.to_s }
|
344
|
-
expect(els[0].class).to eq(
|
345
|
-
expect(els[1].class).to eq(
|
371
|
+
expect(els[0].class).to eq(PStringType)
|
372
|
+
expect(els[1].class).to eq(PTupleType)
|
346
373
|
end
|
347
374
|
|
348
375
|
it 'with mixed string and non-string keys translates to PHashType' do
|
349
376
|
t = calculator.infer_set({ 1 => 'first', 'second' => 'second' })
|
350
|
-
expect(t.class).to eq(
|
377
|
+
expect(t.class).to eq(PHashType)
|
351
378
|
end
|
352
379
|
|
353
380
|
it 'with empty string keys translates to PHashType' do
|
354
381
|
t = calculator.infer_set({ '' => 'first', 'second' => 'second' })
|
355
|
-
expect(t.class).to eq(
|
382
|
+
expect(t.class).to eq(PHashType)
|
356
383
|
end
|
357
384
|
end
|
358
385
|
end
|
@@ -361,9 +388,9 @@ describe 'The type calculator' do
|
|
361
388
|
context 'patterns' do
|
362
389
|
it 'constructs a PPatternType' do
|
363
390
|
t = pattern_t('a(b)c')
|
364
|
-
expect(t.class).to eq(
|
391
|
+
expect(t.class).to eq(PPatternType)
|
365
392
|
expect(t.patterns.size).to eq(1)
|
366
|
-
expect(t.patterns[0].class).to eq(
|
393
|
+
expect(t.patterns[0].class).to eq(PRegexpType)
|
367
394
|
expect(t.patterns[0].pattern).to eq('a(b)c')
|
368
395
|
expect(t.patterns[0].regexp.match('abc')[1]).to eq('b')
|
369
396
|
end
|
@@ -377,36 +404,36 @@ describe 'The type calculator' do
|
|
377
404
|
# Deal with cases not covered by computing common type
|
378
405
|
context 'when computing common type' do
|
379
406
|
it 'computes given resource type commonality' do
|
380
|
-
r1 =
|
381
|
-
r2 =
|
407
|
+
r1 = PResourceType.new('File', nil)
|
408
|
+
r2 = PResourceType.new('File', nil)
|
382
409
|
expect(calculator.common_type(r1, r2).to_s).to eq('File')
|
383
410
|
|
384
411
|
|
385
|
-
r2 =
|
412
|
+
r2 = PResourceType.new('File', '/tmp/foo')
|
386
413
|
expect(calculator.common_type(r1, r2).to_s).to eq('File')
|
387
414
|
|
388
|
-
r1 =
|
415
|
+
r1 = PResourceType.new('File', '/tmp/foo')
|
389
416
|
expect(calculator.common_type(r1, r2).to_s).to eq("File['/tmp/foo']")
|
390
417
|
|
391
|
-
r1 =
|
418
|
+
r1 = PResourceType.new('File', '/tmp/bar')
|
392
419
|
expect(calculator.common_type(r1, r2).to_s).to eq('File')
|
393
420
|
|
394
|
-
r2 =
|
421
|
+
r2 = PResourceType.new('Package', 'apache')
|
395
422
|
expect(calculator.common_type(r1, r2).to_s).to eq('Resource')
|
396
423
|
end
|
397
424
|
|
398
425
|
it 'computes given hostclass type commonality' do
|
399
|
-
r1 =
|
400
|
-
r2 =
|
426
|
+
r1 = PHostClassType.new('foo')
|
427
|
+
r2 = PHostClassType.new('foo')
|
401
428
|
expect(calculator.common_type(r1, r2).to_s).to eq('Class[foo]')
|
402
429
|
|
403
|
-
r2 =
|
430
|
+
r2 = PHostClassType.new('bar')
|
404
431
|
expect(calculator.common_type(r1, r2).to_s).to eq('Class')
|
405
432
|
|
406
|
-
r2 =
|
433
|
+
r2 = PHostClassType.new(nil)
|
407
434
|
expect(calculator.common_type(r1, r2).to_s).to eq('Class')
|
408
435
|
|
409
|
-
r1 =
|
436
|
+
r1 = PHostClassType.new(nil)
|
410
437
|
expect(calculator.common_type(r1, r2).to_s).to eq('Class')
|
411
438
|
end
|
412
439
|
|
@@ -415,7 +442,7 @@ describe 'The type calculator' do
|
|
415
442
|
t1 = string_t('abc')
|
416
443
|
t2 = string_t('xyz')
|
417
444
|
common_t = calculator.common_type(t1,t2)
|
418
|
-
expect(common_t.class).to eq(
|
445
|
+
expect(common_t.class).to eq(PStringType)
|
419
446
|
expect(common_t.values).to eq(['abc', 'xyz'])
|
420
447
|
end
|
421
448
|
|
@@ -423,7 +450,7 @@ describe 'The type calculator' do
|
|
423
450
|
t1 = constrained_string_t(range_t(3,6))
|
424
451
|
t2 = constrained_string_t(range_t(2,4))
|
425
452
|
common_t = calculator.common_type(t1,t2)
|
426
|
-
expect(common_t.class).to eq(
|
453
|
+
expect(common_t.class).to eq(PStringType)
|
427
454
|
expect(common_t.size_type).to eq(range_t(2,6))
|
428
455
|
end
|
429
456
|
|
@@ -431,7 +458,7 @@ describe 'The type calculator' do
|
|
431
458
|
t1 = string_t
|
432
459
|
t2 = constrained_string_t(range_t(2,4))
|
433
460
|
common_t = calculator.common_type(t1,t2)
|
434
|
-
expect(common_t.class).to eq(
|
461
|
+
expect(common_t.class).to eq(PStringType)
|
435
462
|
expect(common_t.size_type).to be_nil
|
436
463
|
end
|
437
464
|
|
@@ -439,7 +466,7 @@ describe 'The type calculator' do
|
|
439
466
|
t1 = constrained_string_t(range_t(3,6), 'apa')
|
440
467
|
t2 = constrained_string_t(range_t(2,4))
|
441
468
|
common_t = calculator.common_type(t1,t2)
|
442
|
-
expect(common_t.class).to eq(
|
469
|
+
expect(common_t.class).to eq(PStringType)
|
443
470
|
expect(common_t.values).to be_empty
|
444
471
|
end
|
445
472
|
end
|
@@ -448,7 +475,7 @@ describe 'The type calculator' do
|
|
448
475
|
t1 = pattern_t('abc')
|
449
476
|
t2 = pattern_t('xyz')
|
450
477
|
common_t = calculator.common_type(t1,t2)
|
451
|
-
expect(common_t.class).to eq(
|
478
|
+
expect(common_t.class).to eq(PPatternType)
|
452
479
|
expect(common_t.patterns.map { |pr| pr.pattern }).to eq(['abc', 'xyz'])
|
453
480
|
expect(common_t.to_s).to eq('Pattern[/abc/, /xyz/]')
|
454
481
|
end
|
@@ -464,21 +491,23 @@ describe 'The type calculator' do
|
|
464
491
|
a_t1 = integer_t
|
465
492
|
a_t2 = enum_t('b')
|
466
493
|
v_a = variant_t(a_t1, a_t2)
|
467
|
-
b_t1 =
|
468
|
-
|
494
|
+
b_t1 = integer_t
|
495
|
+
b_t2 = enum_t('a')
|
496
|
+
v_b = variant_t(b_t1, b_t2)
|
469
497
|
common_t = calculator.common_type(v_a, v_b)
|
470
|
-
expect(common_t.class).to eq(
|
471
|
-
expect(Set.new(common_t.types)).to eq(Set.new([a_t1, a_t2, b_t1]))
|
498
|
+
expect(common_t.class).to eq(PVariantType)
|
499
|
+
expect(Set.new(common_t.types)).to eq(Set.new([a_t1, a_t2, b_t1, b_t2]))
|
472
500
|
end
|
473
501
|
|
474
502
|
it 'computed variant commonality to type union where added types are sub-types' do
|
475
503
|
a_t1 = integer_t
|
476
504
|
a_t2 = string_t
|
477
505
|
v_a = variant_t(a_t1, a_t2)
|
478
|
-
b_t1 =
|
479
|
-
|
506
|
+
b_t1 = integer_t
|
507
|
+
b_t2 = enum_t('a')
|
508
|
+
v_b = variant_t(b_t1, b_t2)
|
480
509
|
common_t = calculator.common_type(v_a, v_b)
|
481
|
-
expect(common_t.class).to eq(
|
510
|
+
expect(common_t.class).to eq(PVariantType)
|
482
511
|
expect(Set.new(common_t.types)).to eq(Set.new([a_t1, a_t2]))
|
483
512
|
end
|
484
513
|
|
@@ -487,18 +516,18 @@ describe 'The type calculator' do
|
|
487
516
|
t1 = callable_t(String)
|
488
517
|
t2 = callable_t(Integer)
|
489
518
|
common_t = calculator.common_type(t1, t2)
|
490
|
-
expect(common_t.class).to be(
|
519
|
+
expect(common_t.class).to be(PCallableType)
|
491
520
|
expect(common_t.param_types).to be_nil
|
492
521
|
expect(common_t.block_type).to be_nil
|
493
522
|
end
|
494
523
|
|
495
524
|
it 'compatible instances => the most specific' do
|
496
525
|
t1 = callable_t(String)
|
497
|
-
scalar_t =
|
526
|
+
scalar_t = PScalarType.new
|
498
527
|
t2 = callable_t(scalar_t)
|
499
528
|
common_t = calculator.common_type(t1, t2)
|
500
|
-
expect(common_t.class).to be(
|
501
|
-
expect(common_t.param_types.class).to be(
|
529
|
+
expect(common_t.class).to be(PCallableType)
|
530
|
+
expect(common_t.param_types.class).to be(PTupleType)
|
502
531
|
expect(common_t.param_types.types).to eql([string_t])
|
503
532
|
expect(common_t.block_type).to be_nil
|
504
533
|
end
|
@@ -509,7 +538,7 @@ describe 'The type calculator' do
|
|
509
538
|
t1 = callable_t(String, b1)
|
510
539
|
t2 = callable_t(String, b2)
|
511
540
|
common_t = calculator.common_type(t1, t2)
|
512
|
-
expect(common_t.class).to be(
|
541
|
+
expect(common_t.class).to be(PCallableType)
|
513
542
|
expect(common_t.param_types).to be_nil
|
514
543
|
expect(common_t.block_type).to be_nil
|
515
544
|
end
|
@@ -517,11 +546,11 @@ describe 'The type calculator' do
|
|
517
546
|
it 'block_type is included in the check (compatible block)' do
|
518
547
|
b1 = callable_t(String)
|
519
548
|
t1 = callable_t(String, b1)
|
520
|
-
scalar_t =
|
549
|
+
scalar_t = PScalarType::DEFAULT
|
521
550
|
b2 = callable_t(scalar_t)
|
522
551
|
t2 = callable_t(String, b2)
|
523
552
|
common_t = calculator.common_type(t1, t2)
|
524
|
-
expect(common_t.param_types.class).to be(
|
553
|
+
expect(common_t.param_types.class).to be(PTupleType)
|
525
554
|
expect(common_t.block_type).to eql(callable_t(scalar_t))
|
526
555
|
end
|
527
556
|
end
|
@@ -539,31 +568,31 @@ describe 'The type calculator' do
|
|
539
568
|
|
540
569
|
context 'for Unit, such that' do
|
541
570
|
it 'all types are assignable to Unit' do
|
542
|
-
t =
|
571
|
+
t = PUnitType::DEFAULT
|
543
572
|
all_types.each { |t2| expect(t2::DEFAULT).to be_assignable_to(t) }
|
544
573
|
end
|
545
574
|
|
546
575
|
it 'Unit is assignable to all other types' do
|
547
|
-
t =
|
576
|
+
t = PUnitType::DEFAULT
|
548
577
|
all_types.each { |t2| expect(t).to be_assignable_to(t2::DEFAULT) }
|
549
578
|
end
|
550
579
|
|
551
580
|
it 'Unit is assignable to Unit' do
|
552
|
-
t =
|
553
|
-
t2 =
|
581
|
+
t = PUnitType::DEFAULT
|
582
|
+
t2 = PUnitType::DEFAULT
|
554
583
|
expect(t).to be_assignable_to(t2)
|
555
584
|
end
|
556
585
|
end
|
557
586
|
|
558
587
|
context 'for Any, such that' do
|
559
588
|
it 'all types are assignable to Any' do
|
560
|
-
t =
|
589
|
+
t = PAnyType::DEFAULT
|
561
590
|
all_types.each { |t2| expect(t2::DEFAULT).to be_assignable_to(t) }
|
562
591
|
end
|
563
592
|
|
564
593
|
it 'Any is not assignable to anything but Any and Optional (implied Optional[Any])' do
|
565
|
-
tested_types = all_types() - [
|
566
|
-
t =
|
594
|
+
tested_types = all_types() - [PAnyType, POptionalType]
|
595
|
+
t = PAnyType::DEFAULT
|
567
596
|
tested_types.each { |t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
568
597
|
end
|
569
598
|
end
|
@@ -571,8 +600,8 @@ describe 'The type calculator' do
|
|
571
600
|
context "for NotUndef, such that" do
|
572
601
|
it 'all types except types assignable from Undef are assignable to NotUndef' do
|
573
602
|
t = not_undef_t
|
574
|
-
tc =
|
575
|
-
undef_t =
|
603
|
+
tc = TypeCalculator.singleton
|
604
|
+
undef_t = PUndefType::DEFAULT
|
576
605
|
all_types.each do |c|
|
577
606
|
t2 = c::DEFAULT
|
578
607
|
if tc.assignable?(t2, undef_t)
|
@@ -584,8 +613,8 @@ describe 'The type calculator' do
|
|
584
613
|
end
|
585
614
|
|
586
615
|
it 'type NotUndef[T] is assignable from T unless T is assignable from Undef ' do
|
587
|
-
tc =
|
588
|
-
undef_t =
|
616
|
+
tc = TypeCalculator.singleton
|
617
|
+
undef_t = PUndefType::DEFAULT
|
589
618
|
all_types().select do |c|
|
590
619
|
t2 = c::DEFAULT
|
591
620
|
not_undef_t = not_undef_t(t2)
|
@@ -598,8 +627,8 @@ describe 'The type calculator' do
|
|
598
627
|
end
|
599
628
|
|
600
629
|
it 'type T is assignable from NotUndef[T] unless T is assignable from Undef' do
|
601
|
-
tc =
|
602
|
-
undef_t =
|
630
|
+
tc = TypeCalculator.singleton
|
631
|
+
undef_t = PUndefType::DEFAULT
|
603
632
|
all_types().select do |c|
|
604
633
|
t2 = c::DEFAULT
|
605
634
|
not_undef_t = not_undef_t(t2)
|
@@ -612,17 +641,17 @@ describe 'The type calculator' do
|
|
612
641
|
|
613
642
|
context "for TypeReference, such that" do
|
614
643
|
it 'no other type is assignable' do
|
615
|
-
t =
|
644
|
+
t = PTypeReferenceType::DEFAULT
|
616
645
|
all_instances = (all_types - [
|
617
|
-
|
618
|
-
|
619
|
-
|
646
|
+
PTypeReferenceType, # Avoid comparison with t
|
647
|
+
PVariantType, # DEFAULT contains no variants, so assignability is never tested and always true
|
648
|
+
PTypeAliasType # DEFAULT resolves to PTypeReferenceType::DEFAULT, i.e. t
|
620
649
|
]).map {|c| c::DEFAULT }
|
621
650
|
|
622
651
|
# Add a non-empty variant
|
623
|
-
all_instances << variant_t(
|
652
|
+
all_instances << variant_t(PAnyType::DEFAULT, PUnitType::DEFAULT)
|
624
653
|
# Add a type alias that doesn't resolve to 't'
|
625
|
-
all_instances << type_alias_t('MyInt', 'Integer').resolve(
|
654
|
+
all_instances << type_alias_t('MyInt', 'Integer').resolve(TypeParser.new, nil)
|
626
655
|
|
627
656
|
all_instances.each { |i| expect(i).not_to be_assignable_to(t) }
|
628
657
|
end
|
@@ -642,32 +671,26 @@ describe 'The type calculator' do
|
|
642
671
|
|
643
672
|
context 'for Data, such that' do
|
644
673
|
it 'all scalars + array and hash are assignable to Data' do
|
645
|
-
t =
|
674
|
+
t = PDataType::DEFAULT
|
646
675
|
data_compatible_types.each { |t2|
|
647
676
|
expect(type_from_class(t2)).to be_assignable_to(t)
|
648
677
|
}
|
649
678
|
end
|
650
679
|
|
651
|
-
it 'a
|
652
|
-
t =
|
653
|
-
data_compatible_types.each { |t2| expect(
|
680
|
+
it 'a scalar, hash, or array is assignable to Data' do
|
681
|
+
t = PDataType::DEFAULT
|
682
|
+
data_compatible_types.each { |t2| expect(type_from_class(t2)).to be_assignable_to(t) }
|
654
683
|
end
|
655
684
|
|
656
685
|
it 'Data is not assignable to any of its subtypes' do
|
657
|
-
t =
|
658
|
-
types_to_test = data_compatible_types- [
|
686
|
+
t = PDataType::DEFAULT
|
687
|
+
types_to_test = data_compatible_types- [PDataType]
|
659
688
|
types_to_test.each {|t2| expect(t).not_to be_assignable_to(type_from_class(t2)) }
|
660
689
|
end
|
661
690
|
|
662
|
-
it 'Data is not assignable to a Variant of Data subtype' do
|
663
|
-
t = Puppet::Pops::Types::PDataType::DEFAULT
|
664
|
-
types_to_test = data_compatible_types- [Puppet::Pops::Types::PDataType]
|
665
|
-
types_to_test.each { |t2| expect(t).not_to be_assignable_to(variant_t(type_from_class(t2))) }
|
666
|
-
end
|
667
|
-
|
668
691
|
it 'Data is not assignable to any disjunct type' do
|
669
|
-
tested_types = all_types - [
|
670
|
-
t =
|
692
|
+
tested_types = all_types - [PAnyType, POptionalType, PDataType] - scalar_types
|
693
|
+
t = PDataType::DEFAULT
|
671
694
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
672
695
|
end
|
673
696
|
end
|
@@ -692,90 +715,90 @@ describe 'The type calculator' do
|
|
692
715
|
|
693
716
|
context 'for Scalar, such that' do
|
694
717
|
it 'all scalars are assignable to Scalar' do
|
695
|
-
t =
|
718
|
+
t = PScalarType::DEFAULT
|
696
719
|
scalar_types.each {|t2| expect(t2::DEFAULT).to be_assignable_to(t) }
|
697
720
|
end
|
698
721
|
|
699
722
|
it 'Scalar is not assignable to any of its subtypes' do
|
700
|
-
t =
|
701
|
-
types_to_test = scalar_types - [
|
723
|
+
t = PScalarType::DEFAULT
|
724
|
+
types_to_test = scalar_types - [PScalarType]
|
702
725
|
types_to_test.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
703
726
|
end
|
704
727
|
|
705
728
|
it 'Scalar is not assignable to any disjunct type' do
|
706
|
-
tested_types = all_types - [
|
707
|
-
t =
|
729
|
+
tested_types = all_types - [PAnyType, POptionalType, PNotUndefType, PDataType] - scalar_types
|
730
|
+
t = PScalarType::DEFAULT
|
708
731
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
709
732
|
end
|
710
733
|
end
|
711
734
|
|
712
735
|
context 'for Numeric, such that' do
|
713
736
|
it 'all numerics are assignable to Numeric' do
|
714
|
-
t =
|
737
|
+
t = PNumericType::DEFAULT
|
715
738
|
numeric_types.each {|t2| expect(t2::DEFAULT).to be_assignable_to(t) }
|
716
739
|
end
|
717
740
|
|
718
741
|
it 'Numeric is not assignable to any of its subtypes' do
|
719
|
-
t =
|
720
|
-
types_to_test = numeric_types - [
|
742
|
+
t = PNumericType::DEFAULT
|
743
|
+
types_to_test = numeric_types - [PNumericType]
|
721
744
|
types_to_test.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
722
745
|
end
|
723
746
|
|
724
747
|
it 'Numeric is not assignable to any disjunct type' do
|
725
748
|
tested_types = all_types - [
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
749
|
+
PAnyType,
|
750
|
+
POptionalType,
|
751
|
+
PNotUndefType,
|
752
|
+
PDataType,
|
753
|
+
PScalarType,
|
731
754
|
] - numeric_types
|
732
|
-
t =
|
755
|
+
t = PNumericType::DEFAULT
|
733
756
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
734
757
|
end
|
735
758
|
end
|
736
759
|
|
737
760
|
context 'for Collection, such that' do
|
738
761
|
it 'all collections are assignable to Collection' do
|
739
|
-
t =
|
762
|
+
t = PCollectionType::DEFAULT
|
740
763
|
collection_types.each {|t2| expect(t2::DEFAULT).to be_assignable_to(t) }
|
741
764
|
end
|
742
765
|
|
743
766
|
it 'Collection is not assignable to any of its subtypes' do
|
744
|
-
t =
|
745
|
-
types_to_test = collection_types - [
|
767
|
+
t = PCollectionType::DEFAULT
|
768
|
+
types_to_test = collection_types - [PCollectionType]
|
746
769
|
types_to_test.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
747
770
|
end
|
748
771
|
|
749
772
|
it 'Collection is not assignable to any disjunct type' do
|
750
773
|
tested_types = all_types - [
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
t =
|
774
|
+
PAnyType,
|
775
|
+
POptionalType,
|
776
|
+
PNotUndefType,
|
777
|
+
PIterableType] - collection_types
|
778
|
+
t = PCollectionType::DEFAULT
|
756
779
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
757
780
|
end
|
758
781
|
end
|
759
782
|
|
760
783
|
context 'for Array, such that' do
|
761
784
|
it 'Array is not assignable to non Array based Collection type' do
|
762
|
-
t =
|
785
|
+
t = PArrayType::DEFAULT
|
763
786
|
tested_types = collection_types - [
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
787
|
+
PCollectionType,
|
788
|
+
PNotUndefType,
|
789
|
+
PArrayType,
|
790
|
+
PTupleType]
|
768
791
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
769
792
|
end
|
770
793
|
|
771
794
|
it 'Array is not assignable to any disjunct type' do
|
772
795
|
tested_types = all_types - [
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
t =
|
796
|
+
PAnyType,
|
797
|
+
POptionalType,
|
798
|
+
PNotUndefType,
|
799
|
+
PIterableType,
|
800
|
+
PDataType] - collection_types
|
801
|
+
t = PArrayType::DEFAULT
|
779
802
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
780
803
|
end
|
781
804
|
|
@@ -787,22 +810,22 @@ describe 'The type calculator' do
|
|
787
810
|
|
788
811
|
context 'for Hash, such that' do
|
789
812
|
it 'Hash is not assignable to any other Collection type' do
|
790
|
-
t =
|
813
|
+
t = PHashType::DEFAULT
|
791
814
|
tested_types = collection_types - [
|
792
|
-
|
793
|
-
|
794
|
-
|
815
|
+
PCollectionType,
|
816
|
+
PStructType,
|
817
|
+
PHashType]
|
795
818
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
796
819
|
end
|
797
820
|
|
798
821
|
it 'Hash is not assignable to any disjunct type' do
|
799
822
|
tested_types = all_types - [
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
t =
|
823
|
+
PAnyType,
|
824
|
+
POptionalType,
|
825
|
+
PNotUndefType,
|
826
|
+
PIterableType,
|
827
|
+
PDataType] - collection_types
|
828
|
+
t = PHashType::DEFAULT
|
806
829
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
807
830
|
end
|
808
831
|
|
@@ -825,11 +848,11 @@ describe 'The type calculator' do
|
|
825
848
|
|
826
849
|
context 'for Tuple, such that' do
|
827
850
|
it 'Tuple is not assignable to any other non Array based Collection type' do
|
828
|
-
t =
|
851
|
+
t = PTupleType::DEFAULT
|
829
852
|
tested_types = collection_types - [
|
830
|
-
|
831
|
-
|
832
|
-
|
853
|
+
PCollectionType,
|
854
|
+
PTupleType,
|
855
|
+
PArrayType]
|
833
856
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
834
857
|
end
|
835
858
|
|
@@ -841,34 +864,34 @@ describe 'The type calculator' do
|
|
841
864
|
|
842
865
|
it 'Tuple is not assignable to any disjunct type' do
|
843
866
|
tested_types = all_types - [
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
t =
|
867
|
+
PAnyType,
|
868
|
+
POptionalType,
|
869
|
+
PNotUndefType,
|
870
|
+
PIterableType,
|
871
|
+
PDataType] - collection_types
|
872
|
+
t = PTupleType::DEFAULT
|
850
873
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
851
874
|
end
|
852
875
|
end
|
853
876
|
|
854
877
|
context 'for Struct, such that' do
|
855
878
|
it 'Struct is not assignable to any other non Hashed based Collection type' do
|
856
|
-
t =
|
879
|
+
t = PStructType::DEFAULT
|
857
880
|
tested_types = collection_types - [
|
858
|
-
|
859
|
-
|
860
|
-
|
881
|
+
PCollectionType,
|
882
|
+
PStructType,
|
883
|
+
PHashType]
|
861
884
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
862
885
|
end
|
863
886
|
|
864
887
|
it 'Struct is not assignable to any disjunct type' do
|
865
888
|
tested_types = all_types - [
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
t =
|
889
|
+
PAnyType,
|
890
|
+
POptionalType,
|
891
|
+
PNotUndefType,
|
892
|
+
PIterableType,
|
893
|
+
PDataType] - collection_types
|
894
|
+
t = PStructType::DEFAULT
|
872
895
|
tested_types.each {|t2| expect(t).not_to be_assignable_to(t2::DEFAULT) }
|
873
896
|
end
|
874
897
|
|
@@ -916,12 +939,12 @@ describe 'The type calculator' do
|
|
916
939
|
|
917
940
|
context 'for Callable, such that' do
|
918
941
|
it 'Callable is not assignable to any disjunct type' do
|
919
|
-
t =
|
942
|
+
t = PCallableType::DEFAULT
|
920
943
|
tested_types = all_types - [
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
944
|
+
PCallableType,
|
945
|
+
PAnyType,
|
946
|
+
POptionalType,
|
947
|
+
PNotUndefType]
|
925
948
|
tested_types.each {|t2| expect(t).to_not be_assignable_to(t2::DEFAULT) }
|
926
949
|
end
|
927
950
|
|
@@ -935,19 +958,19 @@ describe 'The type calculator' do
|
|
935
958
|
end
|
936
959
|
|
937
960
|
it 'should recognize mapped ruby types' do
|
938
|
-
{ Integer =>
|
939
|
-
Fixnum =>
|
940
|
-
Bignum =>
|
941
|
-
Float =>
|
942
|
-
Numeric =>
|
943
|
-
NilClass =>
|
944
|
-
TrueClass =>
|
945
|
-
FalseClass =>
|
946
|
-
String =>
|
947
|
-
Regexp =>
|
948
|
-
Regexp =>
|
949
|
-
Array =>
|
950
|
-
Hash =>
|
961
|
+
{ Integer => PIntegerType::DEFAULT,
|
962
|
+
Fixnum => PIntegerType::DEFAULT,
|
963
|
+
Bignum => PIntegerType::DEFAULT,
|
964
|
+
Float => PFloatType::DEFAULT,
|
965
|
+
Numeric => PNumericType::DEFAULT,
|
966
|
+
NilClass => PUndefType::DEFAULT,
|
967
|
+
TrueClass => PBooleanType::DEFAULT,
|
968
|
+
FalseClass => PBooleanType::DEFAULT,
|
969
|
+
String => PStringType::DEFAULT,
|
970
|
+
Regexp => PRegexpType::DEFAULT,
|
971
|
+
Regexp => PRegexpType::DEFAULT,
|
972
|
+
Array => TypeFactory.array_of_data,
|
973
|
+
Hash => TypeFactory.hash_of_data
|
951
974
|
}.each do |ruby_type, puppet_type |
|
952
975
|
expect(ruby_type).to be_assignable_to(puppet_type)
|
953
976
|
end
|
@@ -1264,55 +1287,55 @@ describe 'The type calculator' do
|
|
1264
1287
|
end
|
1265
1288
|
|
1266
1289
|
it 'should allow host class with same name' do
|
1267
|
-
hc1 =
|
1268
|
-
hc2 =
|
1290
|
+
hc1 = TypeFactory.host_class('the_name')
|
1291
|
+
hc2 = TypeFactory.host_class('the_name')
|
1269
1292
|
expect(calculator.assignable?(hc1, hc2)).to eq(true)
|
1270
1293
|
end
|
1271
1294
|
|
1272
1295
|
it 'should allow host class with name assigned to hostclass without name' do
|
1273
|
-
hc1 =
|
1274
|
-
hc2 =
|
1296
|
+
hc1 = TypeFactory.host_class
|
1297
|
+
hc2 = TypeFactory.host_class('the_name')
|
1275
1298
|
expect(calculator.assignable?(hc1, hc2)).to eq(true)
|
1276
1299
|
end
|
1277
1300
|
|
1278
1301
|
it 'should reject host classes with different names' do
|
1279
|
-
hc1 =
|
1280
|
-
hc2 =
|
1302
|
+
hc1 = TypeFactory.host_class('the_name')
|
1303
|
+
hc2 = TypeFactory.host_class('another_name')
|
1281
1304
|
expect(calculator.assignable?(hc1, hc2)).to eq(false)
|
1282
1305
|
end
|
1283
1306
|
|
1284
1307
|
it 'should reject host classes without name assigned to host class with name' do
|
1285
|
-
hc1 =
|
1286
|
-
hc2 =
|
1308
|
+
hc1 = TypeFactory.host_class('the_name')
|
1309
|
+
hc2 = TypeFactory.host_class
|
1287
1310
|
expect(calculator.assignable?(hc1, hc2)).to eq(false)
|
1288
1311
|
end
|
1289
1312
|
|
1290
1313
|
it 'should allow resource with same type_name and title' do
|
1291
|
-
r1 =
|
1292
|
-
r2 =
|
1314
|
+
r1 = TypeFactory.resource('file', 'foo')
|
1315
|
+
r2 = TypeFactory.resource('file', 'foo')
|
1293
1316
|
expect(calculator.assignable?(r1, r2)).to eq(true)
|
1294
1317
|
end
|
1295
1318
|
|
1296
1319
|
it 'should allow more specific resource assignment' do
|
1297
|
-
r1 =
|
1298
|
-
r2 =
|
1320
|
+
r1 = TypeFactory.resource
|
1321
|
+
r2 = TypeFactory.resource('file')
|
1299
1322
|
expect(calculator.assignable?(r1, r2)).to eq(true)
|
1300
|
-
r2 =
|
1323
|
+
r2 = TypeFactory.resource('file', '/tmp/foo')
|
1301
1324
|
expect(calculator.assignable?(r1, r2)).to eq(true)
|
1302
|
-
r1 =
|
1325
|
+
r1 = TypeFactory.resource('file')
|
1303
1326
|
expect(calculator.assignable?(r1, r2)).to eq(true)
|
1304
1327
|
end
|
1305
1328
|
|
1306
1329
|
it 'should reject less specific resource assignment' do
|
1307
|
-
r1 =
|
1308
|
-
r2 =
|
1330
|
+
r1 = TypeFactory.resource('file', '/tmp/foo')
|
1331
|
+
r2 = TypeFactory.resource('file')
|
1309
1332
|
expect(calculator.assignable?(r1, r2)).to eq(false)
|
1310
|
-
r2 =
|
1333
|
+
r2 = TypeFactory.resource
|
1311
1334
|
expect(calculator.assignable?(r1, r2)).to eq(false)
|
1312
1335
|
end
|
1313
1336
|
|
1314
1337
|
context 'for TypeAlias, such that' do
|
1315
|
-
let!(:parser) {
|
1338
|
+
let!(:parser) { TypeParser.new }
|
1316
1339
|
|
1317
1340
|
it 'it is assignable to the type that it is an alias for' do
|
1318
1341
|
t = type_alias_t('Alias', 'Integer').resolve(parser, nil)
|
@@ -1325,13 +1348,13 @@ describe 'The type calculator' do
|
|
1325
1348
|
end
|
1326
1349
|
|
1327
1350
|
it 'a recursive alias can be assignable from a conformant type with any depth' do
|
1328
|
-
scope =
|
1351
|
+
scope = Object.new
|
1329
1352
|
|
1330
1353
|
t = type_alias_t('Tree', 'Hash[String,Variant[String,Tree]]')
|
1331
|
-
loader =
|
1354
|
+
loader = Object.new
|
1332
1355
|
loader.expects(:load).with(:type, 'tree').returns t
|
1333
1356
|
|
1334
|
-
|
1357
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object).with(instance_of(Model::QualifiedReference), scope).at_most_once.returns loader
|
1335
1358
|
|
1336
1359
|
t.resolve(parser, scope)
|
1337
1360
|
expect(calculator.assignable?(t, parser.parse('Hash[String,Variant[String,Hash[String,Variant[String,String]]]]'))).to be_truthy
|
@@ -1339,15 +1362,15 @@ describe 'The type calculator' do
|
|
1339
1362
|
|
1340
1363
|
|
1341
1364
|
it 'similar recursive aliases are assignable' do
|
1342
|
-
scope =
|
1365
|
+
scope = Object.new
|
1343
1366
|
|
1344
1367
|
t1 = type_alias_t('Tree1', 'Hash[String,Variant[String,Tree1]]')
|
1345
1368
|
t2 = type_alias_t('Tree2', 'Hash[String,Variant[String,Tree2]]')
|
1346
|
-
loader =
|
1369
|
+
loader = Object.new
|
1347
1370
|
loader.expects(:load).with(:type, 'tree1').returns t1
|
1348
1371
|
loader.expects(:load).with(:type, 'tree2').returns t2
|
1349
1372
|
|
1350
|
-
|
1373
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object).with(instance_of(Model::QualifiedReference), scope).at_least_once.returns loader
|
1351
1374
|
|
1352
1375
|
t1.resolve(parser, scope)
|
1353
1376
|
t2.resolve(parser, scope)
|
@@ -1355,16 +1378,16 @@ describe 'The type calculator' do
|
|
1355
1378
|
end
|
1356
1379
|
|
1357
1380
|
it 'crossing recursive aliases are assignable' do
|
1358
|
-
scope =
|
1381
|
+
scope = Object.new
|
1359
1382
|
|
1360
1383
|
t1 = type_alias_t('Tree1', 'Hash[String,Variant[String,Tree2]]')
|
1361
1384
|
t2 = type_alias_t('Tree2', 'Hash[String,Variant[String,Tree1]]')
|
1362
|
-
loader =
|
1385
|
+
loader = Object.new
|
1363
1386
|
loader.expects(:load).with(:type, 'tree1').returns t1
|
1364
1387
|
loader.expects(:load).with(:type, 'tree2').returns t2
|
1365
|
-
loader.expects(:is_a?).with(
|
1388
|
+
loader.expects(:is_a?).with(Loader::Loader).returns true
|
1366
1389
|
|
1367
|
-
|
1390
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object).with(instance_of(Model::QualifiedReference), scope).at_least_once.returns loader
|
1368
1391
|
|
1369
1392
|
t1.resolve(parser, scope)
|
1370
1393
|
t2.resolve(parser, scope)
|
@@ -1372,13 +1395,13 @@ describe 'The type calculator' do
|
|
1372
1395
|
end
|
1373
1396
|
|
1374
1397
|
it 'Type[T] is assignable to Type[AT] when AT is an alias for T' do
|
1375
|
-
scope =
|
1398
|
+
scope = Object.new
|
1376
1399
|
|
1377
1400
|
ta = type_alias_t('PositiveInteger', 'Integer[0,default]')
|
1378
|
-
loader =
|
1401
|
+
loader = Object.new
|
1379
1402
|
loader.expects(:load).with(:type, 'positiveinteger').returns ta
|
1380
|
-
|
1381
|
-
.with(instance_of(
|
1403
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object)
|
1404
|
+
.with(instance_of(Model::QualifiedReference), scope).returns loader
|
1382
1405
|
|
1383
1406
|
t1 = type_t(range_t(0, :default))
|
1384
1407
|
t2 = parser.parse('Type[PositiveInteger]', scope)
|
@@ -1386,13 +1409,13 @@ describe 'The type calculator' do
|
|
1386
1409
|
end
|
1387
1410
|
|
1388
1411
|
it 'Type[T] is assignable to AT when AT is an alias for Type[T]' do
|
1389
|
-
scope =
|
1412
|
+
scope = Object.new
|
1390
1413
|
|
1391
1414
|
ta = type_alias_t('PositiveIntegerType', 'Type[Integer[0,default]]')
|
1392
|
-
loader =
|
1415
|
+
loader = Object.new
|
1393
1416
|
loader.expects(:load).with(:type, 'positiveintegertype').returns ta
|
1394
|
-
|
1395
|
-
.with(instance_of(
|
1417
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object)
|
1418
|
+
.with(instance_of(Model::QualifiedReference), scope).returns loader
|
1396
1419
|
|
1397
1420
|
t1 = type_t(range_t(0, :default))
|
1398
1421
|
t2 = parser.parse('PositiveIntegerType', scope)
|
@@ -1400,13 +1423,13 @@ describe 'The type calculator' do
|
|
1400
1423
|
end
|
1401
1424
|
|
1402
1425
|
it 'Type[Type[T]] is assignable to Type[Type[AT]] when AT is an alias for T' do
|
1403
|
-
scope =
|
1426
|
+
scope = Object.new
|
1404
1427
|
|
1405
1428
|
ta = type_alias_t('PositiveInteger', 'Integer[0,default]')
|
1406
|
-
loader =
|
1429
|
+
loader = Object.new
|
1407
1430
|
loader.expects(:load).with(:type, 'positiveinteger').returns ta
|
1408
|
-
|
1409
|
-
.with(instance_of(
|
1431
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object)
|
1432
|
+
.with(instance_of(Model::QualifiedReference), scope).returns loader
|
1410
1433
|
|
1411
1434
|
t1 = type_t(type_t(range_t(0, :default)))
|
1412
1435
|
t2 = parser.parse('Type[Type[PositiveInteger]]', scope)
|
@@ -1414,13 +1437,13 @@ describe 'The type calculator' do
|
|
1414
1437
|
end
|
1415
1438
|
|
1416
1439
|
it 'Type[Type[T]] is assignable to Type[AT] when AT is an alias for Type[T]' do
|
1417
|
-
scope =
|
1440
|
+
scope = Object.new
|
1418
1441
|
|
1419
1442
|
ta = type_alias_t('PositiveIntegerType', 'Type[Integer[0,default]]')
|
1420
|
-
loader =
|
1443
|
+
loader = Object.new
|
1421
1444
|
loader.expects(:load).with(:type, 'positiveintegertype').returns ta
|
1422
|
-
|
1423
|
-
.with(instance_of(
|
1445
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object)
|
1446
|
+
.with(instance_of(Model::QualifiedReference), scope).returns loader
|
1424
1447
|
|
1425
1448
|
t1 = type_t(type_t(range_t(0, :default)))
|
1426
1449
|
t2 = parser.parse('Type[PositiveIntegerType]', scope)
|
@@ -1433,14 +1456,14 @@ describe 'The type calculator' do
|
|
1433
1456
|
include_context 'types_setup'
|
1434
1457
|
|
1435
1458
|
it 'should consider undef to be instance of Any, NilType, and optional' do
|
1436
|
-
expect(calculator.instance?(
|
1437
|
-
expect(calculator.instance?(
|
1438
|
-
expect(calculator.instance?(
|
1459
|
+
expect(calculator.instance?(PUndefType::DEFAULT, nil)).to eq(true)
|
1460
|
+
expect(calculator.instance?(PAnyType::DEFAULT, nil)).to eq(true)
|
1461
|
+
expect(calculator.instance?(POptionalType::DEFAULT, nil)).to eq(true)
|
1439
1462
|
end
|
1440
1463
|
|
1441
1464
|
it 'all types should be (ruby) instance of PAnyType' do
|
1442
1465
|
all_types.each do |t|
|
1443
|
-
expect(t::DEFAULT.is_a?(
|
1466
|
+
expect(t::DEFAULT.is_a?(PAnyType)).to eq(true)
|
1444
1467
|
end
|
1445
1468
|
end
|
1446
1469
|
|
@@ -1449,23 +1472,23 @@ describe 'The type calculator' do
|
|
1449
1472
|
end
|
1450
1473
|
|
1451
1474
|
it "should not consider :default to be instance of Runtime['ruby', 'Symbol]" do
|
1452
|
-
expect(calculator.instance?(
|
1475
|
+
expect(calculator.instance?(PRuntimeType.new(:ruby, 'Symbol'), :default)).to eq(false)
|
1453
1476
|
end
|
1454
1477
|
|
1455
1478
|
it "should not consider :undef to be instance of Runtime['ruby', 'Symbol]" do
|
1456
|
-
expect(calculator.instance?(
|
1479
|
+
expect(calculator.instance?(PRuntimeType.new(:ruby, 'Symbol'), :undef)).to eq(false)
|
1457
1480
|
end
|
1458
1481
|
|
1459
1482
|
it 'should consider :undef to be instance of an Optional type' do
|
1460
|
-
expect(calculator.instance?(
|
1483
|
+
expect(calculator.instance?(POptionalType::DEFAULT, :undef)).to eq(true)
|
1461
1484
|
end
|
1462
1485
|
|
1463
1486
|
it 'should not consider undef to be an instance of any other type than Any, UndefType and Data' do
|
1464
1487
|
types_to_test = all_types - [
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1488
|
+
PAnyType,
|
1489
|
+
PUndefType,
|
1490
|
+
PDataType,
|
1491
|
+
POptionalType,
|
1469
1492
|
]
|
1470
1493
|
|
1471
1494
|
types_to_test.each {|t| expect(calculator.instance?(t::DEFAULT, nil)).to eq(false) }
|
@@ -1473,22 +1496,22 @@ describe 'The type calculator' do
|
|
1473
1496
|
end
|
1474
1497
|
|
1475
1498
|
it 'should consider default to be instance of Default and Any' do
|
1476
|
-
expect(calculator.instance?(
|
1477
|
-
expect(calculator.instance?(
|
1499
|
+
expect(calculator.instance?(PDefaultType::DEFAULT, :default)).to eq(true)
|
1500
|
+
expect(calculator.instance?(PAnyType::DEFAULT, :default)).to eq(true)
|
1478
1501
|
end
|
1479
1502
|
|
1480
1503
|
it 'should not consider "default" to be an instance of anything but Default, NotUndef, and Any' do
|
1481
1504
|
types_to_test = all_types - [
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1505
|
+
PAnyType,
|
1506
|
+
PNotUndefType,
|
1507
|
+
PDefaultType,
|
1485
1508
|
]
|
1486
1509
|
|
1487
1510
|
types_to_test.each {|t| expect(calculator.instance?(t::DEFAULT, :default)).to eq(false) }
|
1488
1511
|
end
|
1489
1512
|
|
1490
1513
|
it 'should consider fixnum instanceof PIntegerType' do
|
1491
|
-
expect(calculator.instance?(
|
1514
|
+
expect(calculator.instance?(PIntegerType::DEFAULT, 1)).to eq(true)
|
1492
1515
|
end
|
1493
1516
|
|
1494
1517
|
it 'should consider fixnum instanceof Fixnum' do
|
@@ -1677,10 +1700,10 @@ describe 'The type calculator' do
|
|
1677
1700
|
context 'and t is something Callable' do
|
1678
1701
|
|
1679
1702
|
it 'a Closure should be considered a Callable' do
|
1680
|
-
factory =
|
1703
|
+
factory = Model::Factory
|
1681
1704
|
params = [factory.PARAM('a')]
|
1682
1705
|
the_block = factory.LAMBDA(params,factory.literal(42))
|
1683
|
-
the_closure =
|
1706
|
+
the_closure = Evaluator::Closure.new(:fake_evaluator, the_block, :fake_scope)
|
1684
1707
|
expect(calculator.instance?(all_callables_t, the_closure)).to be_truthy
|
1685
1708
|
expect(calculator.instance?(callable_t(object_t), the_closure)).to be_truthy
|
1686
1709
|
expect(calculator.instance?(callable_t(object_t, object_t), the_closure)).to be_falsey
|
@@ -1705,7 +1728,7 @@ describe 'The type calculator' do
|
|
1705
1728
|
end
|
1706
1729
|
|
1707
1730
|
context 'and t is a TypeAlias' do
|
1708
|
-
let!(:parser) {
|
1731
|
+
let!(:parser) { TypeParser.new }
|
1709
1732
|
|
1710
1733
|
it 'should consider x an instance of the aliased simple type' do
|
1711
1734
|
t = type_alias_t('Alias', 'Integer').resolve(parser, nil)
|
@@ -1718,29 +1741,29 @@ describe 'The type calculator' do
|
|
1718
1741
|
end
|
1719
1742
|
|
1720
1743
|
it 'should consider x an instance of the aliased type that uses self recursion' do
|
1721
|
-
scope =
|
1744
|
+
scope = Object.new
|
1722
1745
|
|
1723
1746
|
t = type_alias_t('Tree', 'Hash[String,Variant[String,Tree]]')
|
1724
|
-
loader =
|
1747
|
+
loader = Object.new
|
1725
1748
|
loader.expects(:load).with(:type, 'tree').returns t
|
1726
1749
|
|
1727
|
-
|
1750
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object).with(instance_of(Model::QualifiedReference), scope).at_most_once.returns loader
|
1728
1751
|
|
1729
1752
|
t.resolve(parser, scope)
|
1730
1753
|
expect(calculator.instance?(t, {'a'=>{'aa'=>{'aaa'=>'aaaa'}}, 'b'=>'bb'})).to be_truthy
|
1731
1754
|
end
|
1732
1755
|
|
1733
1756
|
it 'should consider x an instance of the aliased type that uses contains an alias that causes self recursion' do
|
1734
|
-
scope =
|
1757
|
+
scope = Object.new
|
1735
1758
|
|
1736
1759
|
t1 = type_alias_t('Tree', 'Hash[String,Variant[String,OtherTree]]')
|
1737
1760
|
t2 = type_alias_t('OtherTree', 'Hash[String,Tree]')
|
1738
|
-
loader =
|
1761
|
+
loader = Object.new
|
1739
1762
|
loader.expects(:load).with(:type, 'tree').returns t1
|
1740
1763
|
loader.expects(:load).with(:type, 'othertree').returns t2
|
1741
|
-
loader.expects(:is_a?).with(
|
1764
|
+
loader.expects(:is_a?).with(Loader::Loader).returns true
|
1742
1765
|
|
1743
|
-
|
1766
|
+
Adapters::LoaderAdapter.expects(:loader_for_model_object).with(instance_of(Model::QualifiedReference), scope).at_least_once.returns loader
|
1744
1767
|
|
1745
1768
|
t1.resolve(parser, scope)
|
1746
1769
|
expect(calculator.instance?(t1, {'a'=>{'aa'=>{'aaa'=>'aaaa'}}, 'b'=>'bb'})).to be_truthy
|
@@ -1751,105 +1774,105 @@ describe 'The type calculator' do
|
|
1751
1774
|
context 'when converting a ruby class' do
|
1752
1775
|
it 'should yield \'PIntegerType\' for Integer, Fixnum, and Bignum' do
|
1753
1776
|
[Integer,Fixnum,Bignum].each do |c|
|
1754
|
-
expect(calculator.type(c).class).to eq(
|
1777
|
+
expect(calculator.type(c).class).to eq(PIntegerType)
|
1755
1778
|
end
|
1756
1779
|
end
|
1757
1780
|
|
1758
1781
|
it 'should yield \'PFloatType\' for Float' do
|
1759
|
-
expect(calculator.type(Float).class).to eq(
|
1782
|
+
expect(calculator.type(Float).class).to eq(PFloatType)
|
1760
1783
|
end
|
1761
1784
|
|
1762
1785
|
it 'should yield \'PBooleanType\' for FalseClass and TrueClass' do
|
1763
1786
|
[FalseClass,TrueClass].each do |c|
|
1764
|
-
expect(calculator.type(c).class).to eq(
|
1787
|
+
expect(calculator.type(c).class).to eq(PBooleanType)
|
1765
1788
|
end
|
1766
1789
|
end
|
1767
1790
|
|
1768
1791
|
it 'should yield \'PUndefType\' for NilClass' do
|
1769
|
-
expect(calculator.type(NilClass).class).to eq(
|
1792
|
+
expect(calculator.type(NilClass).class).to eq(PUndefType)
|
1770
1793
|
end
|
1771
1794
|
|
1772
1795
|
it 'should yield \'PStringType\' for String' do
|
1773
|
-
expect(calculator.type(String).class).to eq(
|
1796
|
+
expect(calculator.type(String).class).to eq(PStringType)
|
1774
1797
|
end
|
1775
1798
|
|
1776
1799
|
it 'should yield \'PRegexpType\' for Regexp' do
|
1777
|
-
expect(calculator.type(Regexp).class).to eq(
|
1800
|
+
expect(calculator.type(Regexp).class).to eq(PRegexpType)
|
1778
1801
|
end
|
1779
1802
|
|
1780
1803
|
it 'should yield \'PArrayType[PDataType]\' for Array' do
|
1781
1804
|
t = calculator.type(Array)
|
1782
|
-
expect(t.class).to eq(
|
1783
|
-
expect(t.element_type.class).to eq(
|
1805
|
+
expect(t.class).to eq(PArrayType)
|
1806
|
+
expect(t.element_type.class).to eq(PDataType)
|
1784
1807
|
end
|
1785
1808
|
|
1786
1809
|
it 'should yield \'PHashType[PScalarType,PDataType]\' for Hash' do
|
1787
1810
|
t = calculator.type(Hash)
|
1788
|
-
expect(t.class).to eq(
|
1789
|
-
expect(t.key_type.class).to eq(
|
1790
|
-
expect(t.element_type.class).to eq(
|
1811
|
+
expect(t.class).to eq(PHashType)
|
1812
|
+
expect(t.key_type.class).to eq(PScalarType)
|
1813
|
+
expect(t.element_type.class).to eq(PDataType)
|
1791
1814
|
end
|
1792
1815
|
end
|
1793
1816
|
|
1794
1817
|
context 'when processing meta type' do
|
1795
1818
|
it 'should infer PType as the type of all other types' do
|
1796
|
-
ptype =
|
1797
|
-
expect(calculator.infer(
|
1798
|
-
expect(calculator.infer(
|
1799
|
-
expect(calculator.infer(
|
1800
|
-
expect(calculator.infer(
|
1801
|
-
expect(calculator.infer(
|
1802
|
-
expect(calculator.infer(
|
1803
|
-
expect(calculator.infer(
|
1804
|
-
expect(calculator.infer(
|
1805
|
-
expect(calculator.infer(
|
1806
|
-
expect(calculator.infer(
|
1807
|
-
expect(calculator.infer(
|
1808
|
-
expect(calculator.infer(
|
1809
|
-
expect(calculator.infer(
|
1810
|
-
expect(calculator.infer(
|
1811
|
-
expect(calculator.infer(
|
1812
|
-
expect(calculator.infer(
|
1813
|
-
expect(calculator.infer(
|
1814
|
-
expect(calculator.infer(
|
1815
|
-
expect(calculator.infer(
|
1816
|
-
expect(calculator.infer(
|
1817
|
-
expect(calculator.infer(
|
1818
|
-
expect(calculator.infer(
|
1819
|
+
ptype = PType
|
1820
|
+
expect(calculator.infer(PUndefType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1821
|
+
expect(calculator.infer(PDataType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1822
|
+
expect(calculator.infer(PScalarType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1823
|
+
expect(calculator.infer(PStringType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1824
|
+
expect(calculator.infer(PNumericType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1825
|
+
expect(calculator.infer(PIntegerType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1826
|
+
expect(calculator.infer(PFloatType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1827
|
+
expect(calculator.infer(PRegexpType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1828
|
+
expect(calculator.infer(PBooleanType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1829
|
+
expect(calculator.infer(PCollectionType::DEFAULT).is_a?(ptype)).to eq(true)
|
1830
|
+
expect(calculator.infer(PArrayType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1831
|
+
expect(calculator.infer(PHashType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1832
|
+
expect(calculator.infer(PIterableType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1833
|
+
expect(calculator.infer(PRuntimeType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1834
|
+
expect(calculator.infer(PHostClassType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1835
|
+
expect(calculator.infer(PResourceType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1836
|
+
expect(calculator.infer(PEnumType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1837
|
+
expect(calculator.infer(PPatternType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1838
|
+
expect(calculator.infer(PVariantType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1839
|
+
expect(calculator.infer(PTupleType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1840
|
+
expect(calculator.infer(POptionalType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1841
|
+
expect(calculator.infer(PCallableType::DEFAULT ).is_a?(ptype)).to eq(true)
|
1819
1842
|
end
|
1820
1843
|
|
1821
1844
|
it 'should infer PType as the type of all other types' do
|
1822
|
-
expect(calculator.infer(
|
1823
|
-
expect(calculator.infer(
|
1824
|
-
expect(calculator.infer(
|
1825
|
-
expect(calculator.infer(
|
1826
|
-
expect(calculator.infer(
|
1827
|
-
expect(calculator.infer(
|
1828
|
-
expect(calculator.infer(
|
1829
|
-
expect(calculator.infer(
|
1830
|
-
expect(calculator.infer(
|
1831
|
-
expect(calculator.infer(
|
1832
|
-
expect(calculator.infer(
|
1833
|
-
expect(calculator.infer(
|
1834
|
-
expect(calculator.infer(
|
1835
|
-
expect(calculator.infer(
|
1836
|
-
expect(calculator.infer(
|
1837
|
-
expect(calculator.infer(
|
1838
|
-
expect(calculator.infer(
|
1839
|
-
expect(calculator.infer(
|
1840
|
-
expect(calculator.infer(
|
1841
|
-
expect(calculator.infer(
|
1842
|
-
expect(calculator.infer(
|
1843
|
-
expect(calculator.infer(
|
1844
|
-
|
1845
|
-
expect(calculator.infer(
|
1846
|
-
expect(calculator.infer(
|
1847
|
-
expect(calculator.infer(
|
1845
|
+
expect(calculator.infer(PUndefType::DEFAULT ).to_s).to eq('Type[Undef]')
|
1846
|
+
expect(calculator.infer(PDataType::DEFAULT ).to_s).to eq('Type[Data]')
|
1847
|
+
expect(calculator.infer(PScalarType::DEFAULT ).to_s).to eq('Type[Scalar]')
|
1848
|
+
expect(calculator.infer(PStringType::DEFAULT ).to_s).to eq('Type[String]')
|
1849
|
+
expect(calculator.infer(PNumericType::DEFAULT ).to_s).to eq('Type[Numeric]')
|
1850
|
+
expect(calculator.infer(PIntegerType::DEFAULT ).to_s).to eq('Type[Integer]')
|
1851
|
+
expect(calculator.infer(PFloatType::DEFAULT ).to_s).to eq('Type[Float]')
|
1852
|
+
expect(calculator.infer(PRegexpType::DEFAULT ).to_s).to eq('Type[Regexp]')
|
1853
|
+
expect(calculator.infer(PBooleanType::DEFAULT ).to_s).to eq('Type[Boolean]')
|
1854
|
+
expect(calculator.infer(PCollectionType::DEFAULT).to_s).to eq('Type[Collection]')
|
1855
|
+
expect(calculator.infer(PArrayType::DEFAULT ).to_s).to eq('Type[Array[?]]')
|
1856
|
+
expect(calculator.infer(PHashType::DEFAULT ).to_s).to eq('Type[Hash[?, ?]]')
|
1857
|
+
expect(calculator.infer(PIterableType::DEFAULT ).to_s).to eq('Type[Iterable]')
|
1858
|
+
expect(calculator.infer(PRuntimeType::DEFAULT ).to_s).to eq('Type[Runtime[?, ?]]')
|
1859
|
+
expect(calculator.infer(PHostClassType::DEFAULT ).to_s).to eq('Type[Class]')
|
1860
|
+
expect(calculator.infer(PResourceType::DEFAULT ).to_s).to eq('Type[Resource]')
|
1861
|
+
expect(calculator.infer(PEnumType::DEFAULT ).to_s).to eq('Type[Enum]')
|
1862
|
+
expect(calculator.infer(PVariantType::DEFAULT ).to_s).to eq('Type[Variant]')
|
1863
|
+
expect(calculator.infer(PPatternType::DEFAULT ).to_s).to eq('Type[Pattern]')
|
1864
|
+
expect(calculator.infer(PTupleType::DEFAULT ).to_s).to eq('Type[Tuple]')
|
1865
|
+
expect(calculator.infer(POptionalType::DEFAULT ).to_s).to eq('Type[Optional]')
|
1866
|
+
expect(calculator.infer(PCallableType::DEFAULT ).to_s).to eq('Type[Callable]')
|
1867
|
+
|
1868
|
+
expect(calculator.infer(PResourceType.new('foo::fee::fum')).to_s).to eq('Type[Foo::Fee::Fum]')
|
1869
|
+
expect(calculator.infer(PResourceType.new('foo::fee::fum')).to_s).to eq('Type[Foo::Fee::Fum]')
|
1870
|
+
expect(calculator.infer(PResourceType.new('Foo::Fee::Fum')).to_s).to eq('Type[Foo::Fee::Fum]')
|
1848
1871
|
end
|
1849
1872
|
|
1850
1873
|
it "computes the common type of PType's type parameter" do
|
1851
|
-
int_t =
|
1852
|
-
string_t =
|
1874
|
+
int_t = PIntegerType::DEFAULT
|
1875
|
+
string_t = PStringType::DEFAULT
|
1853
1876
|
expect(calculator.infer([int_t]).to_s).to eq('Array[Type[Integer], 1, 1]')
|
1854
1877
|
expect(calculator.infer([int_t, string_t]).to_s).to eq('Array[Type[Scalar], 2, 2]')
|
1855
1878
|
end
|
@@ -1858,49 +1881,49 @@ describe 'The type calculator' do
|
|
1858
1881
|
class Foo
|
1859
1882
|
end
|
1860
1883
|
[Object, Numeric, Integer, Fixnum, Bignum, Float, String, Regexp, Array, Hash, Foo].each do |c|
|
1861
|
-
expect(calculator.infer(c).is_a?(
|
1884
|
+
expect(calculator.infer(c).is_a?(PType)).to eq(true)
|
1862
1885
|
end
|
1863
1886
|
end
|
1864
1887
|
|
1865
1888
|
it 'should infer PType as the type of PType (meta regression short-circuit)' do
|
1866
|
-
expect(calculator.infer(
|
1889
|
+
expect(calculator.infer(PType::DEFAULT).is_a?(PType)).to eq(true)
|
1867
1890
|
end
|
1868
1891
|
|
1869
1892
|
it 'computes instance? to be true if parameterized and type match' do
|
1870
|
-
int_t =
|
1871
|
-
type_t =
|
1872
|
-
type_type_t =
|
1893
|
+
int_t = PIntegerType::DEFAULT
|
1894
|
+
type_t = TypeFactory.type_type(int_t)
|
1895
|
+
type_type_t = TypeFactory.type_type(type_t)
|
1873
1896
|
expect(calculator.instance?(type_type_t, type_t)).to eq(true)
|
1874
1897
|
end
|
1875
1898
|
|
1876
1899
|
it 'computes instance? to be false if parameterized and type do not match' do
|
1877
|
-
int_t =
|
1878
|
-
string_t =
|
1879
|
-
type_t =
|
1880
|
-
type_t2 =
|
1881
|
-
type_type_t =
|
1900
|
+
int_t = PIntegerType::DEFAULT
|
1901
|
+
string_t = PStringType::DEFAULT
|
1902
|
+
type_t = TypeFactory.type_type(int_t)
|
1903
|
+
type_t2 = TypeFactory.type_type(string_t)
|
1904
|
+
type_type_t = TypeFactory.type_type(type_t)
|
1882
1905
|
# i.e. Type[Integer] =~ Type[Type[Integer]] # false
|
1883
1906
|
expect(calculator.instance?(type_type_t, type_t2)).to eq(false)
|
1884
1907
|
end
|
1885
1908
|
|
1886
1909
|
it 'computes instance? to be true if unparameterized and matched against a type[?]' do
|
1887
|
-
int_t =
|
1888
|
-
type_t =
|
1889
|
-
expect(calculator.instance?(
|
1910
|
+
int_t = PIntegerType::DEFAULT
|
1911
|
+
type_t = TypeFactory.type_type(int_t)
|
1912
|
+
expect(calculator.instance?(PType::DEFAULT, type_t)).to eq(true)
|
1890
1913
|
end
|
1891
1914
|
end
|
1892
1915
|
|
1893
1916
|
context 'when asking for an iterable ' do
|
1894
1917
|
it 'should produce an iterable for an Integer range that is finite' do
|
1895
|
-
t =
|
1918
|
+
t = PIntegerType.new(1, 10)
|
1896
1919
|
expect(calculator.iterable(t).respond_to?(:each)).to eq(true)
|
1897
1920
|
end
|
1898
1921
|
|
1899
1922
|
it 'should not produce an iterable for an Integer range that has an infinite side' do
|
1900
|
-
t =
|
1923
|
+
t = PIntegerType.new(nil, 10)
|
1901
1924
|
expect(calculator.iterable(t)).to eq(nil)
|
1902
1925
|
|
1903
|
-
t =
|
1926
|
+
t = PIntegerType.new(1, nil)
|
1904
1927
|
expect(calculator.iterable(t)).to eq(nil)
|
1905
1928
|
end
|
1906
1929
|
|
@@ -1954,35 +1977,35 @@ describe 'The type calculator' do
|
|
1954
1977
|
|
1955
1978
|
it "does not reduce by combining types when using infer_set" do
|
1956
1979
|
element_type = calculator.infer(['a','b',1,2]).element_type
|
1957
|
-
expect(element_type.class).to eq(
|
1980
|
+
expect(element_type.class).to eq(PScalarType)
|
1958
1981
|
inferred_type = calculator.infer_set(['a','b',1,2])
|
1959
|
-
expect(inferred_type.class).to eq(
|
1982
|
+
expect(inferred_type.class).to eq(PTupleType)
|
1960
1983
|
element_types = inferred_type.types
|
1961
|
-
expect(element_types[0].class).to eq(
|
1962
|
-
expect(element_types[1].class).to eq(
|
1963
|
-
expect(element_types[2].class).to eq(
|
1964
|
-
expect(element_types[3].class).to eq(
|
1984
|
+
expect(element_types[0].class).to eq(PStringType)
|
1985
|
+
expect(element_types[1].class).to eq(PStringType)
|
1986
|
+
expect(element_types[2].class).to eq(PIntegerType)
|
1987
|
+
expect(element_types[3].class).to eq(PIntegerType)
|
1965
1988
|
end
|
1966
1989
|
|
1967
1990
|
it 'does not reduce by combining types when using infer_set and values are undef' do
|
1968
1991
|
element_type = calculator.infer(['a',nil]).element_type
|
1969
|
-
expect(element_type.class).to eq(
|
1992
|
+
expect(element_type.class).to eq(PStringType)
|
1970
1993
|
inferred_type = calculator.infer_set(['a',nil])
|
1971
|
-
expect(inferred_type.class).to eq(
|
1994
|
+
expect(inferred_type.class).to eq(PTupleType)
|
1972
1995
|
element_types = inferred_type.types
|
1973
|
-
expect(element_types[0].class).to eq(
|
1974
|
-
expect(element_types[1].class).to eq(
|
1996
|
+
expect(element_types[0].class).to eq(PStringType)
|
1997
|
+
expect(element_types[1].class).to eq(PUndefType)
|
1975
1998
|
end
|
1976
1999
|
|
1977
2000
|
it 'infers on an empty Array produces Array[Unit,0,0]' do
|
1978
2001
|
inferred_type = calculator.infer([])
|
1979
|
-
expect(inferred_type.element_type.class).to eq(
|
2002
|
+
expect(inferred_type.element_type.class).to eq(PUnitType)
|
1980
2003
|
expect(inferred_type.size_range).to eq([0, 0])
|
1981
2004
|
end
|
1982
2005
|
|
1983
2006
|
it 'infer_set on an empty Array produces Array[Unit,0,0]' do
|
1984
2007
|
inferred_type = calculator.infer_set([])
|
1985
|
-
expect(inferred_type.element_type.class).to eq(
|
2008
|
+
expect(inferred_type.element_type.class).to eq(PUnitType)
|
1986
2009
|
expect(inferred_type.size_range).to eq([0, 0])
|
1987
2010
|
end
|
1988
2011
|
end
|
@@ -2068,7 +2091,7 @@ describe 'The type calculator' do
|
|
2068
2091
|
end
|
2069
2092
|
|
2070
2093
|
matcher :be_assignable_to do |type|
|
2071
|
-
calc =
|
2094
|
+
calc = TypeCalculator.singleton
|
2072
2095
|
|
2073
2096
|
match do |actual|
|
2074
2097
|
calc.assignable?(type, actual)
|
@@ -2082,5 +2105,6 @@ describe 'The type calculator' do
|
|
2082
2105
|
"#{calc.string(actual)} is assignable to #{calc.string(type)} when it should not"
|
2083
2106
|
end
|
2084
2107
|
end
|
2085
|
-
|
2108
|
+
end
|
2109
|
+
end
|
2086
2110
|
end
|