puppet 5.1.0-x64-mingw32 → 5.2.0-x64-mingw32
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/lib/puppet.rb +6 -53
- data/lib/puppet/application.rb +14 -7
- data/lib/puppet/application/agent.rb +6 -2
- data/lib/puppet/application/apply.rb +6 -2
- data/lib/puppet/application/cert.rb +6 -2
- data/lib/puppet/application/describe.rb +6 -2
- data/lib/puppet/application/device.rb +40 -29
- data/lib/puppet/application/doc.rb +6 -2
- data/lib/puppet/application/filebucket.rb +6 -2
- data/lib/puppet/application/lookup.rb +6 -2
- data/lib/puppet/application/master.rb +6 -2
- data/lib/puppet/application/resource.rb +6 -2
- data/lib/puppet/face/catalog.rb +1 -1
- data/lib/puppet/face/certificate_request.rb +1 -1
- data/lib/puppet/face/certificate_revocation_list.rb +1 -1
- data/lib/puppet/face/help.rb +17 -13
- data/lib/puppet/file_serving/configuration.rb +3 -0
- data/lib/puppet/file_serving/configuration/parser.rb +2 -0
- data/lib/puppet/file_serving/mount/tasks.rb +21 -0
- data/lib/puppet/functions/epp.rb +3 -0
- data/lib/puppet/functions/lookup.rb +2 -1
- data/lib/puppet/generate/models/type/property.rb +1 -1
- data/lib/puppet/gettext/config.rb +70 -0
- data/lib/puppet/gettext/stubs.rb +11 -0
- data/lib/puppet/indirector/request.rb +4 -4
- data/lib/puppet/info_service.rb +10 -0
- data/lib/puppet/info_service/task_information_service.rb +32 -0
- data/lib/puppet/module.rb +43 -12
- data/lib/puppet/module/task.rb +90 -0
- data/lib/puppet/parser/ast/leaf.rb +1 -1
- data/lib/puppet/parser/functions/dig.rb +11 -2
- data/lib/puppet/parser/functions/epp.rb +3 -0
- data/lib/puppet/parser/functions/new.rb +8 -8
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
- data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -0
- data/lib/puppet/pops/issues.rb +11 -5
- data/lib/puppet/pops/loader/static_loader.rb +1 -1
- data/lib/puppet/pops/model/factory.rb +42 -2
- data/lib/puppet/pops/model/model_tree_dumper.rb +1 -1
- data/lib/puppet/pops/parser/egrammar.ra +30 -9
- data/lib/puppet/pops/parser/eparser.rb +1094 -1043
- data/lib/puppet/pops/patterns.rb +1 -1
- data/lib/puppet/pops/serialization/from_data_converter.rb +1 -1
- data/lib/puppet/pops/serialization/json_path.rb +1 -1
- data/lib/puppet/pops/serialization/to_data_converter.rb +12 -3
- data/lib/puppet/pops/types/p_object_type.rb +31 -3
- data/lib/puppet/pops/types/p_sem_ver_range_type.rb +3 -3
- data/lib/puppet/pops/types/p_timespan_type.rb +1 -1
- data/lib/puppet/pops/types/p_timestamp_type.rb +1 -1
- data/lib/puppet/pops/types/string_converter.rb +15 -12
- data/lib/puppet/pops/types/type_calculator.rb +1 -1
- data/lib/puppet/pops/types/type_factory.rb +7 -0
- data/lib/puppet/pops/types/type_formatter.rb +1 -1
- data/lib/puppet/pops/types/type_mismatch_describer.rb +86 -130
- data/lib/puppet/pops/types/type_parser.rb +10 -4
- data/lib/puppet/pops/types/types.rb +81 -22
- data/lib/puppet/provider/package/aix.rb +4 -4
- data/lib/puppet/provider/package/yum.rb +1 -0
- data/lib/puppet/type.rb +1 -1
- data/lib/puppet/type/mount.rb +1 -1
- data/lib/puppet/type/sshkey.rb +9 -1
- data/lib/puppet/util.rb +1 -1
- data/lib/puppet/util/command_line.rb +1 -1
- data/lib/puppet/util/log.rb +15 -10
- data/lib/puppet/util/windows/api_types.rb +9 -5
- data/lib/puppet/util/windows/process.rb +9 -1
- data/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +1 -3
- data/lib/puppet/version.rb +1 -1
- data/locales/ja/puppet.po +9270 -0
- data/locales/puppet.pot +272 -212
- data/spec/fixtures/unit/provider/package/yum/yum-check-update-plugin-output.txt +36 -0
- data/spec/integration/indirector/file_content/file_server_spec.rb +17 -0
- data/spec/integration/indirector/file_metadata/file_server_spec.rb +10 -0
- data/spec/integration/util/windows/process_spec.rb +45 -0
- data/spec/lib/puppet_spec/modules.rb +10 -0
- data/spec/shared_contexts/types_setup.rb +19 -4
- data/spec/spec_helper.rb +6 -7
- data/spec/unit/face/help_spec.rb +2 -2
- data/spec/unit/file_serving/configuration_spec.rb +14 -4
- data/spec/unit/file_serving/mount/modules_spec.rb +1 -1
- data/spec/unit/file_serving/mount/tasks_spec.rb +72 -0
- data/spec/unit/functions/epp_spec.rb +5 -0
- data/spec/unit/functions/regsubst_spec.rb +1 -1
- data/spec/unit/gettext_config_spec.rb +57 -0
- data/spec/unit/indirector/request_spec.rb +41 -0
- data/spec/unit/info_service_spec.rb +66 -2
- data/spec/unit/module_spec.rb +81 -1
- data/spec/unit/parser/ast/leaf_spec.rb +3 -4
- data/spec/unit/pops/evaluator/access_ops_spec.rb +5 -0
- data/spec/unit/pops/factory_spec.rb +5 -1
- data/spec/unit/pops/parser/parser_spec.rb +138 -0
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +74 -1
- data/spec/unit/pops/types/p_init_type_spec.rb +1 -1
- data/spec/unit/pops/types/p_object_type_spec.rb +217 -33
- data/spec/unit/pops/types/p_timespan_type_spec.rb +7 -0
- data/spec/unit/pops/types/p_timestamp_type_spec.rb +7 -0
- data/spec/unit/pops/types/string_converter_spec.rb +48 -11
- data/spec/unit/pops/types/type_calculator_spec.rb +37 -5
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +12 -0
- data/spec/unit/pops/types/type_parser_spec.rb +25 -0
- data/spec/unit/pops/validator/validator_spec.rb +2 -2
- data/spec/unit/provider/package/aix_spec.rb +26 -1
- data/spec/unit/provider/package/yum_spec.rb +10 -0
- data/spec/unit/task_spec.rb +102 -0
- data/spec/unit/util/log_spec.rb +32 -3
- data/spec/unit/util/windows/api_types_spec.rb +51 -0
- metadata +3488 -3452
- checksums.yaml +0 -7
data/lib/puppet/pops/patterns.rb
CHANGED
@@ -48,7 +48,7 @@ module Puppet::Pops::Patterns
|
|
48
48
|
|
49
49
|
# VAR_NAME matches the name part of a variable (The $ character is not included)
|
50
50
|
# Note, that only the final segment may start with an underscore.
|
51
|
-
VAR_NAME = %r{\A(?:(::)?[a-z]\w*)*(?:(::)?
|
51
|
+
VAR_NAME = %r{\A(?:((::)?[a-z]\w*)*(?:(::)?_\w*)?)\z}
|
52
52
|
|
53
53
|
# PARAM_NAME matches the name part of a parameter (The $ character is not included)
|
54
54
|
PARAM_NAME = %r{\A[a-z_]\w*\z}
|
@@ -160,7 +160,7 @@ module Serialization
|
|
160
160
|
elsif value.is_a?(String)
|
161
161
|
build(pcore_type.create(value))
|
162
162
|
else
|
163
|
-
raise SerializationError, _('Cannot create a %{type_name} from a %{arg_class') %
|
163
|
+
raise SerializationError, _('Cannot create a %{type_name} from a %{arg_class}') %
|
164
164
|
{ :type_name => pcore_type.name, :arg_class => value.class.name }
|
165
165
|
end
|
166
166
|
end
|
@@ -26,7 +26,7 @@ module JsonPath
|
|
26
26
|
# with '$' which denotes the value that is passed into the parser. This parser can easily
|
27
27
|
# be extended with more elaborate resolution mechanisms involving document sets.
|
28
28
|
#
|
29
|
-
# The parser is limited to constructs generated by the {JsonPath#
|
29
|
+
# The parser is limited to constructs generated by the {JsonPath#to_json_path}
|
30
30
|
# method.
|
31
31
|
#
|
32
32
|
# @api private
|
@@ -71,11 +71,20 @@ module Serialization
|
|
71
71
|
def to_data(value)
|
72
72
|
if value.nil? || Types::PScalarDataType::DEFAULT.instance?(value)
|
73
73
|
value
|
74
|
-
elsif value
|
75
|
-
if
|
74
|
+
elsif :default == value
|
75
|
+
if @rich_data
|
76
76
|
{ PCORE_TYPE_KEY => PCORE_TYPE_DEFAULT }
|
77
77
|
else
|
78
|
-
|
78
|
+
serialization_issue(Issues::SERIALIZATION_DEFAULT_CONVERTED_TO_STRING, :path => path_to_s)
|
79
|
+
'default'
|
80
|
+
end
|
81
|
+
elsif value.is_a?(Symbol)
|
82
|
+
if @symbol_as_string
|
83
|
+
value.to_s
|
84
|
+
elsif @rich_data
|
85
|
+
{ PCORE_TYPE_KEY => PCORE_TYPE_SYMBOL, PCORE_VALUE_KEY => value.to_s }
|
86
|
+
else
|
87
|
+
unknown_to_string_with_warning(value)
|
79
88
|
end
|
80
89
|
elsif value.instance_of?(Array)
|
81
90
|
process(value) do
|
@@ -5,6 +5,7 @@ module Types
|
|
5
5
|
|
6
6
|
KEY_ATTRIBUTES = 'attributes'.freeze
|
7
7
|
KEY_CHECKS = 'checks'.freeze
|
8
|
+
KEY_CONSTANTS = 'constants'.freeze
|
8
9
|
KEY_EQUALITY = 'equality'.freeze
|
9
10
|
KEY_EQUALITY_INCLUDE_TYPE = 'equality_include_type'.freeze
|
10
11
|
KEY_FINAL = 'final'.freeze
|
@@ -32,6 +33,8 @@ class PObjectType < PMetaType
|
|
32
33
|
KEY_VALUE => PAnyType::DEFAULT,
|
33
34
|
TypeFactory.optional(KEY_ANNOTATIONS) => TYPE_ANNOTATIONS
|
34
35
|
})
|
36
|
+
|
37
|
+
TYPE_CONSTANTS = TypeFactory.hash_kv(Pcore::TYPE_MEMBER_NAME, PAnyType::DEFAULT)
|
35
38
|
TYPE_ATTRIBUTES = TypeFactory.hash_kv(Pcore::TYPE_MEMBER_NAME, TypeFactory.not_undef)
|
36
39
|
TYPE_ATTRIBUTE_CALLABLE = TypeFactory.callable(0,0)
|
37
40
|
|
@@ -53,6 +56,7 @@ class PObjectType < PMetaType
|
|
53
56
|
TypeFactory.optional(KEY_NAME) => TYPE_OBJECT_NAME,
|
54
57
|
TypeFactory.optional(KEY_PARENT) => PTypeType::DEFAULT,
|
55
58
|
TypeFactory.optional(KEY_ATTRIBUTES) => TYPE_ATTRIBUTES,
|
59
|
+
TypeFactory.optional(KEY_CONSTANTS) => TYPE_CONSTANTS,
|
56
60
|
TypeFactory.optional(KEY_FUNCTIONS) => TYPE_FUNCTIONS,
|
57
61
|
TypeFactory.optional(KEY_EQUALITY) => TYPE_EQUALITY,
|
58
62
|
TypeFactory.optional(KEY_EQUALITY_INCLUDE_TYPE) => PBooleanType::DEFAULT,
|
@@ -143,12 +147,16 @@ class PObjectType < PMetaType
|
|
143
147
|
# @api private
|
144
148
|
def assert_can_be_overridden(member)
|
145
149
|
raise Puppet::ParseError, "#{member.label} attempts to override #{label}" unless self.class == member.class
|
146
|
-
raise Puppet::ParseError, "#{member.label} attempts to override final #{label}" if @final
|
150
|
+
raise Puppet::ParseError, "#{member.label} attempts to override final #{label}" if @final && !(constant? && member.constant?)
|
147
151
|
raise Puppet::ParseError, "#{member.label} attempts to override #{label} without having override => true" unless member.override?
|
148
152
|
raise Puppet::ParseError, "#{member.label} attempts to override #{label} with a type that does not match" unless @type.assignable?(member.type)
|
149
153
|
member
|
150
154
|
end
|
151
155
|
|
156
|
+
def constant?
|
157
|
+
false
|
158
|
+
end
|
159
|
+
|
152
160
|
# @return [Boolean] `true` if this feature cannot be overridden
|
153
161
|
# @api public
|
154
162
|
def final?
|
@@ -295,6 +303,10 @@ class PObjectType < PMetaType
|
|
295
303
|
hash
|
296
304
|
end
|
297
305
|
|
306
|
+
def constant?
|
307
|
+
@kind == ATTRIBUTE_KIND_CONSTANT
|
308
|
+
end
|
309
|
+
|
298
310
|
# @return [Booelan] true if the given value equals the default value for this attribute
|
299
311
|
def default_value?(value)
|
300
312
|
@value == value
|
@@ -594,8 +606,24 @@ class PObjectType < PMetaType
|
|
594
606
|
end
|
595
607
|
end
|
596
608
|
|
597
|
-
|
598
|
-
|
609
|
+
constants = init_hash[KEY_CONSTANTS]
|
610
|
+
attr_specs = init_hash[KEY_ATTRIBUTES] || {}
|
611
|
+
unless constants.nil? || constants.empty?
|
612
|
+
constants.each do |key, value|
|
613
|
+
raise Puppet::ParseError, "attribute #{label}[#{key}] is defined as both a constant and an attribute" if attr_specs.include?(key)
|
614
|
+
attr_spec = {
|
615
|
+
# Type must be generic here, or overrides would become impossible
|
616
|
+
KEY_TYPE => TypeCalculator.infer(value).generalize,
|
617
|
+
KEY_VALUE => value,
|
618
|
+
KEY_KIND => ATTRIBUTE_KIND_CONSTANT
|
619
|
+
}
|
620
|
+
# Indicate override if parent member exists. Type check etc. will take place later on.
|
621
|
+
attr_spec[KEY_OVERRIDE] = true if parent_members.include?(key)
|
622
|
+
attr_specs[key] = attr_spec
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
unless attr_specs.empty?
|
599
627
|
@attributes = Hash[attr_specs.map do |key, attr_spec|
|
600
628
|
unless attr_spec.is_a?(Hash)
|
601
629
|
attr_type = TypeAsserter.assert_instance_of(nil, PTypeType::DEFAULT, attr_spec) { "attribute #{label}[#{key}]" }
|
@@ -111,7 +111,7 @@ class PSemVerRangeType < PAnyType
|
|
111
111
|
@new_function ||= Puppet::Functions.create_loaded_function(:new_VersionRange, type.loader) do
|
112
112
|
local_types do
|
113
113
|
type 'SemVerRangeString = String[1]'
|
114
|
-
type 'SemVerRangeHash = Struct[{min=>Variant[
|
114
|
+
type 'SemVerRangeHash = Struct[{min=>Variant[Default,SemVer],Optional[max]=>Variant[Default,SemVer],Optional[exclude_max]=>Boolean}]'
|
115
115
|
end
|
116
116
|
|
117
117
|
# Constructs a VersionRange from a String with a format specified by
|
@@ -136,8 +136,8 @@ class PSemVerRangeType < PAnyType
|
|
136
136
|
# default.
|
137
137
|
#
|
138
138
|
dispatch :from_versions do
|
139
|
-
param 'Variant[
|
140
|
-
param 'Variant[
|
139
|
+
param 'Variant[Default,SemVer]', :min
|
140
|
+
param 'Variant[Default,SemVer]', :max
|
141
141
|
optional_param 'Boolean', :exclude_max
|
142
142
|
end
|
143
143
|
|
@@ -106,7 +106,7 @@ module Types
|
|
106
106
|
def self.new_function(type)
|
107
107
|
@new_function ||= Puppet::Functions.create_loaded_function(:new_timespan, type.loader) do
|
108
108
|
local_types do
|
109
|
-
type 'Formats = Variant[String[2],Array[String[2]
|
109
|
+
type 'Formats = Variant[String[2],Array[String[2], 1]]'
|
110
110
|
end
|
111
111
|
|
112
112
|
dispatch :from_seconds do
|
@@ -11,7 +11,7 @@ module Types
|
|
11
11
|
def self.new_function(type)
|
12
12
|
@new_function ||= Puppet::Functions.create_loaded_function(:new_timestamp, type.loader) do
|
13
13
|
local_types do
|
14
|
-
type 'Formats = Variant[String[2],Array[String[2]
|
14
|
+
type 'Formats = Variant[String[2],Array[String[2], 1]]'
|
15
15
|
end
|
16
16
|
|
17
17
|
dispatch :now do
|
@@ -85,7 +85,8 @@ class StringConverter
|
|
85
85
|
|
86
86
|
attr_reader :orig_fmt
|
87
87
|
|
88
|
-
|
88
|
+
FMT_PATTERN_STR = '^%([\s\[+#0{<(|-]*)([1-9][0-9]*)?(?:\.([0-9]+))?([a-zA-Z])$'
|
89
|
+
FMT_PATTERN = Regexp.compile(FMT_PATTERN_STR)
|
89
90
|
DELIMITERS = [ '[', '{', '(', '<', '|',]
|
90
91
|
DELIMITER_MAP = {
|
91
92
|
'[' => ['[', ']'],
|
@@ -265,13 +266,13 @@ class StringConverter
|
|
265
266
|
}.freeze
|
266
267
|
|
267
268
|
DEFAULT_ARRAY_FORMAT = Format.new('%a')
|
268
|
-
DEFAULT_ARRAY_FORMAT.separator = ','.freeze
|
269
|
-
DEFAULT_ARRAY_FORMAT.separator2 = ','.freeze
|
269
|
+
DEFAULT_ARRAY_FORMAT.separator = ', '.freeze
|
270
|
+
DEFAULT_ARRAY_FORMAT.separator2 = ', '.freeze
|
270
271
|
DEFAULT_ARRAY_FORMAT.container_string_formats = DEFAULT_CONTAINER_FORMATS
|
271
272
|
DEFAULT_ARRAY_FORMAT.freeze
|
272
273
|
|
273
274
|
DEFAULT_HASH_FORMAT = Format.new('%h')
|
274
|
-
DEFAULT_HASH_FORMAT.separator = ','.freeze
|
275
|
+
DEFAULT_HASH_FORMAT.separator = ', '.freeze
|
275
276
|
DEFAULT_HASH_FORMAT.separator2 = ' => '.freeze
|
276
277
|
DEFAULT_HASH_FORMAT.container_string_formats = DEFAULT_CONTAINER_FORMATS
|
277
278
|
DEFAULT_HASH_FORMAT.freeze
|
@@ -541,7 +542,7 @@ class StringConverter
|
|
541
542
|
|
542
543
|
def validate_container_input(fmt)
|
543
544
|
if (fmt.keys - FMT_KEYS).size > 0
|
544
|
-
raise ArgumentError, "only #{FMT_KEYS
|
545
|
+
raise ArgumentError, "only #{FMT_KEYS.map {|k| "'#{k}'"}.join(', ')} are allowed in a container format, got #{fmt}"
|
545
546
|
end
|
546
547
|
result = Format.new(fmt['format'])
|
547
548
|
result.separator = fmt['separator']
|
@@ -901,12 +902,10 @@ class StringConverter
|
|
901
902
|
f = get_format(val_type, format_map)
|
902
903
|
case f.format
|
903
904
|
when :p
|
904
|
-
|
905
|
-
rx_s = rx_s.gsub(/\//, '\/') unless Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
|
906
|
-
str_regexp = "/#{rx_s}/"
|
905
|
+
str_regexp = PRegexpType.regexp_to_s_with_delimiters(val)
|
907
906
|
f.orig_fmt == '%p' ? str_regexp : Kernel.format(f.orig_fmt.gsub('p', 's'), str_regexp)
|
908
907
|
when :s
|
909
|
-
str_regexp =
|
908
|
+
str_regexp = PRegexpType.regexp_to_s(val)
|
910
909
|
str_regexp = puppet_quote(str_regexp) if f.alt?
|
911
910
|
f.orig_fmt == '%s' ? str_regexp : Kernel.format(f.orig_fmt, str_regexp)
|
912
911
|
else
|
@@ -976,12 +975,13 @@ class StringConverter
|
|
976
975
|
# or, if indenting, and previous was an array or hash, then break and continue on next line
|
977
976
|
# indented.
|
978
977
|
if (sz_break && !is_a_or_h?(v)) || (format.alt? && i > 0 && is_a_or_h?(val[i-1]) && !is_a_or_h?(v))
|
978
|
+
buf.rstrip! unless buf[-1] == "\n"
|
979
979
|
buf << "\n"
|
980
980
|
buf << children_indentation.padding
|
981
|
-
elsif !(format.alt? && is_a_or_h?(v))
|
982
|
-
buf << ' '
|
983
981
|
end
|
984
982
|
end
|
983
|
+
# remove trailing space added by separator if followed by break
|
984
|
+
buf.rstrip! if buf[-1] == ' ' && str_val[0] == "\n"
|
985
985
|
buf << str_val
|
986
986
|
end
|
987
987
|
buf << delims[1]
|
@@ -1023,7 +1023,10 @@ class StringConverter
|
|
1023
1023
|
string_formats = format.container_string_formats || DEFAULT_CONTAINER_FORMATS
|
1024
1024
|
delims = format.delimiter_pair(DEFAULT_HASH_DELIMITERS)
|
1025
1025
|
|
1026
|
-
|
1026
|
+
if format.alt?
|
1027
|
+
sep = sep.rstrip unless sep[-1] == "\n"
|
1028
|
+
sep = "#{sep}\n"
|
1029
|
+
end
|
1027
1030
|
|
1028
1031
|
cond_break = ''
|
1029
1032
|
padding = ''
|
@@ -361,6 +361,13 @@ module TypeFactory
|
|
361
361
|
@rich_data_t ||= TypeParser.singleton.parse('RichData', Loaders.static_loader)
|
362
362
|
end
|
363
363
|
|
364
|
+
# Produces the RichData type
|
365
|
+
# @api public
|
366
|
+
#
|
367
|
+
def self.rich_data_key
|
368
|
+
@rich_data_key_t ||= TypeParser.singleton.parse('RichDataKey', Loaders.static_loader)
|
369
|
+
end
|
370
|
+
|
364
371
|
# Creates an instance of the Undef type
|
365
372
|
# @api public
|
366
373
|
def self.undef
|
@@ -545,7 +545,7 @@ class TypeFormatter
|
|
545
545
|
def string_Numeric(t) ; @bld << t.to_s ; end
|
546
546
|
|
547
547
|
# @api private
|
548
|
-
def string_Regexp(t) ; @bld << t
|
548
|
+
def string_Regexp(t) ; @bld << PRegexpType.regexp_to_s_with_delimiters(t); end
|
549
549
|
|
550
550
|
# @api private
|
551
551
|
def string_String(t)
|
@@ -92,51 +92,6 @@ module Types
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
# Module to handle present/past tense.
|
96
|
-
#
|
97
|
-
# All method names prefixed with "it_" to avoid conflict with Mocha expectations. Adding a method
|
98
|
-
# named 'expects' just doesn't work.
|
99
|
-
#
|
100
|
-
# @deprecated Will be removed in Puppet 5
|
101
|
-
# @api private
|
102
|
-
module TenseVariants
|
103
|
-
def it_expects(tense)
|
104
|
-
case tense
|
105
|
-
when :present
|
106
|
-
'expects'
|
107
|
-
else
|
108
|
-
'expected'
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def it_does_not_expect(tense)
|
113
|
-
case tense
|
114
|
-
when :present
|
115
|
-
'does not expect'
|
116
|
-
else
|
117
|
-
'did not expect'
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def it_has_no(tense)
|
122
|
-
case tense
|
123
|
-
when :present
|
124
|
-
'has no'
|
125
|
-
else
|
126
|
-
'did not have a'
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def it_references(tense)
|
131
|
-
case tense
|
132
|
-
when :present
|
133
|
-
'references'
|
134
|
-
else
|
135
|
-
'referenced'
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
95
|
# @api private
|
141
96
|
class Mismatch
|
142
97
|
attr_reader :path
|
@@ -293,11 +248,6 @@ module Types
|
|
293
248
|
super(path)
|
294
249
|
@expected = (expected.is_a?(Array) ? PVariantType.maybe_create(expected) : expected).normalize
|
295
250
|
@actual = actual.normalize
|
296
|
-
@optional = false
|
297
|
-
end
|
298
|
-
|
299
|
-
def set_optional
|
300
|
-
@optional = true
|
301
251
|
end
|
302
252
|
|
303
253
|
def ==(o)
|
@@ -307,12 +257,6 @@ module Types
|
|
307
257
|
def hash
|
308
258
|
[canonical_path, expected, actual].hash
|
309
259
|
end
|
310
|
-
|
311
|
-
def swap_expected(expected)
|
312
|
-
copy = self.clone
|
313
|
-
copy.instance_variable_set(:@expected, expected)
|
314
|
-
copy
|
315
|
-
end
|
316
260
|
end
|
317
261
|
|
318
262
|
# @api private
|
@@ -328,15 +272,12 @@ module Types
|
|
328
272
|
e = expected
|
329
273
|
a = actual
|
330
274
|
multi = false
|
331
|
-
if
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
e = [PUndefType::DEFAULT, e] unless er.is_a?(PVariantType) && er.types.include?(PUndefType::DEFAULT)
|
338
|
-
end
|
339
|
-
elsif e.is_a?(PVariantType)
|
275
|
+
if e.is_a?(POptionalType)
|
276
|
+
e = e.optional_type
|
277
|
+
optional = true
|
278
|
+
end
|
279
|
+
|
280
|
+
if e.is_a?(PVariantType)
|
340
281
|
e = e.types
|
341
282
|
end
|
342
283
|
|
@@ -348,6 +289,7 @@ module Types
|
|
348
289
|
e = e.map { |t| t.simple_name }.uniq
|
349
290
|
a = a.simple_name
|
350
291
|
end
|
292
|
+
e.insert(0, 'Undef') if optional
|
351
293
|
case e.size
|
352
294
|
when 1
|
353
295
|
e = e[0]
|
@@ -366,6 +308,10 @@ module Types
|
|
366
308
|
e = e.simple_name
|
367
309
|
a = a.simple_name
|
368
310
|
end
|
311
|
+
if optional
|
312
|
+
e = "Undef or #{e}"
|
313
|
+
multi = true
|
314
|
+
end
|
369
315
|
end
|
370
316
|
if multi
|
371
317
|
"#{variant}#{position} expects a value of type #{e}, got #{label(a)}"
|
@@ -473,7 +419,13 @@ module Types
|
|
473
419
|
# @api private
|
474
420
|
class PatternMismatch < TypeMismatch
|
475
421
|
def message(variant, position)
|
476
|
-
|
422
|
+
e = expected
|
423
|
+
value_pfx = ''
|
424
|
+
if e.is_a?(POptionalType)
|
425
|
+
e = e.optional_type
|
426
|
+
value_pfx = 'an undef value or '
|
427
|
+
end
|
428
|
+
"#{variant}#{position} expects #{value_pfx}a match for #{e.to_alias_expanded_s}, got #{actual_string}"
|
477
429
|
end
|
478
430
|
|
479
431
|
def actual_string
|
@@ -747,14 +699,23 @@ module Types
|
|
747
699
|
end
|
748
700
|
end
|
749
701
|
|
750
|
-
def describe_PVariantType(expected, actual, path)
|
702
|
+
def describe_PVariantType(expected, original, actual, path)
|
751
703
|
variant_descriptions = []
|
752
|
-
expected.types
|
704
|
+
types = expected.types
|
705
|
+
types = [PUndefType::DEFAULT] + types if original.is_a?(POptionalType)
|
706
|
+
types.each_with_index do |vt, index|
|
753
707
|
d = describe(vt, actual, path + [VariantPathElement.new(index)])
|
754
708
|
return EMPTY_ARRAY if d.empty?
|
755
709
|
variant_descriptions << d
|
756
710
|
end
|
757
|
-
merge_descriptions(path.length, SizeMismatch, variant_descriptions)
|
711
|
+
descriptions = merge_descriptions(path.length, SizeMismatch, variant_descriptions)
|
712
|
+
if original.is_a?(PTypeAliasType) && descriptions.size == 1
|
713
|
+
# All variants failed in this alias so we report it as a mismatch on the alias
|
714
|
+
# rather than reporting individual failures of the variants
|
715
|
+
[TypeMismatch.new(path, original, actual)]
|
716
|
+
else
|
717
|
+
descriptions
|
718
|
+
end
|
758
719
|
end
|
759
720
|
|
760
721
|
def merge_descriptions(varying_path_position, size_mismatch_class, variant_descriptions)
|
@@ -778,33 +739,24 @@ module Types
|
|
778
739
|
descriptions.size == 1 ? [descriptions[0].chop_path(varying_path_position)] : descriptions
|
779
740
|
end
|
780
741
|
|
781
|
-
def describe_POptionalType(expected, actual, path)
|
742
|
+
def describe_POptionalType(expected, original, actual, path)
|
782
743
|
return EMPTY_ARRAY if actual.is_a?(PUndefType)
|
783
|
-
|
784
|
-
descriptions.each { |description| description.set_optional }
|
785
|
-
descriptions
|
744
|
+
internal_describe(expected.optional_type, original.is_a?(PTypeAliasType) ? original : expected, actual, path)
|
786
745
|
end
|
787
746
|
|
788
|
-
def describe_PEnumType(expected, actual, path)
|
789
|
-
[PatternMismatch.new(path,
|
747
|
+
def describe_PEnumType(expected, original, actual, path)
|
748
|
+
[PatternMismatch.new(path, original, actual)]
|
790
749
|
end
|
791
750
|
|
792
|
-
def describe_PPatternType(expected, actual, path)
|
793
|
-
[PatternMismatch.new(path,
|
751
|
+
def describe_PPatternType(expected, original, actual, path)
|
752
|
+
[PatternMismatch.new(path, original, actual)]
|
794
753
|
end
|
795
754
|
|
796
|
-
def describe_PTypeAliasType(expected, actual, path)
|
797
|
-
resolved_type
|
798
|
-
describe(resolved_type, actual, path).map do |description|
|
799
|
-
if description.is_a?(ExpectedActualMismatch)
|
800
|
-
description.swap_expected(expected)
|
801
|
-
else
|
802
|
-
description
|
803
|
-
end
|
804
|
-
end
|
755
|
+
def describe_PTypeAliasType(expected, original, actual, path)
|
756
|
+
internal_describe(expected.resolved_type.normalize, expected, actual, path)
|
805
757
|
end
|
806
758
|
|
807
|
-
def describe_PArrayType(expected, actual, path)
|
759
|
+
def describe_PArrayType(expected, original, actual, path)
|
808
760
|
descriptions = []
|
809
761
|
element_type = expected.element_type || PAnyType::DEFAULT
|
810
762
|
if actual.is_a?(PTupleType)
|
@@ -822,17 +774,17 @@ module Types
|
|
822
774
|
expected_size = expected.size_type
|
823
775
|
actual_size = actual.size_type || PCollectionType::DEFAULT_SIZE
|
824
776
|
if expected_size.nil? || expected_size.assignable?(actual_size)
|
825
|
-
descriptions << TypeMismatch.new(path,
|
777
|
+
descriptions << TypeMismatch.new(path, original, PArrayType.new(actual.element_type))
|
826
778
|
else
|
827
779
|
descriptions << SizeMismatch.new(path, expected_size, actual_size)
|
828
780
|
end
|
829
781
|
else
|
830
|
-
descriptions << TypeMismatch.new(path,
|
782
|
+
descriptions << TypeMismatch.new(path, original, actual)
|
831
783
|
end
|
832
784
|
descriptions
|
833
785
|
end
|
834
786
|
|
835
|
-
def describe_PHashType(expected, actual, path)
|
787
|
+
def describe_PHashType(expected, original, actual, path)
|
836
788
|
descriptions = []
|
837
789
|
key_type = expected.key_type || PAnyType::DEFAULT
|
838
790
|
value_type = expected.value_type || PAnyType::DEFAULT
|
@@ -852,17 +804,17 @@ module Types
|
|
852
804
|
expected_size = expected.size_type
|
853
805
|
actual_size = actual.size_type || PCollectionType::DEFAULT_SIZE
|
854
806
|
if expected_size.nil? || expected_size.assignable?(actual_size)
|
855
|
-
descriptions << TypeMismatch.new(path,
|
807
|
+
descriptions << TypeMismatch.new(path, original, PHashType.new(actual.key_type, actual.value_type))
|
856
808
|
else
|
857
809
|
descriptions << SizeMismatch.new(path, expected_size, actual_size)
|
858
810
|
end
|
859
811
|
else
|
860
|
-
descriptions << TypeMismatch.new(path,
|
812
|
+
descriptions << TypeMismatch.new(path, original, actual)
|
861
813
|
end
|
862
814
|
descriptions
|
863
815
|
end
|
864
816
|
|
865
|
-
def describe_PStructType(expected, actual, path)
|
817
|
+
def describe_PStructType(expected, original, actual, path)
|
866
818
|
elements = expected.elements
|
867
819
|
descriptions = []
|
868
820
|
if actual.is_a?(PStructType)
|
@@ -882,25 +834,25 @@ module Types
|
|
882
834
|
actual_size = actual.size_type || PCollectionType::DEFAULT_SIZE
|
883
835
|
expected_size = PIntegerType.new(elements.count { |e| !e.key_type.assignable?(PUndefType::DEFAULT) }, elements.size)
|
884
836
|
if expected_size.assignable?(actual_size)
|
885
|
-
descriptions << TypeMismatch.new(path,
|
837
|
+
descriptions << TypeMismatch.new(path, original, PHashType.new(actual.key_type, actual.value_type))
|
886
838
|
else
|
887
839
|
descriptions << SizeMismatch.new(path, expected_size, actual_size)
|
888
840
|
end
|
889
841
|
else
|
890
|
-
descriptions << TypeMismatch.new(path,
|
842
|
+
descriptions << TypeMismatch.new(path, original, actual)
|
891
843
|
end
|
892
844
|
descriptions
|
893
845
|
end
|
894
846
|
|
895
|
-
def describe_PTupleType(expected, actual, path)
|
896
|
-
describe_tuple(expected, actual, path, SizeMismatch)
|
847
|
+
def describe_PTupleType(expected, original, actual, path)
|
848
|
+
describe_tuple(expected, original, actual, path, SizeMismatch)
|
897
849
|
end
|
898
850
|
|
899
851
|
def describe_argument_tuple(expected, actual, path)
|
900
|
-
describe_tuple(expected, actual, path, CountMismatch)
|
852
|
+
describe_tuple(expected, expected, actual, path, CountMismatch)
|
901
853
|
end
|
902
854
|
|
903
|
-
def describe_tuple(expected, actual, path, size_mismatch_class)
|
855
|
+
def describe_tuple(expected, original, actual, path, size_mismatch_class)
|
904
856
|
return EMPTY_ARRAY if expected == actual || expected.types.empty? && (actual.is_a?(PArrayType))
|
905
857
|
expected_size = expected.size_type || TypeFactory.range(*expected.size_range)
|
906
858
|
|
@@ -928,7 +880,7 @@ module Types
|
|
928
880
|
# Array of anything can not be assigned (unless tuple is tuple of anything) - this case
|
929
881
|
# was handled at the top of this method.
|
930
882
|
#
|
931
|
-
[TypeMismatch.new(path,
|
883
|
+
[TypeMismatch.new(path, original, actual)]
|
932
884
|
else
|
933
885
|
expected_size = expected.size_type || TypeFactory.range(*expected.size_range)
|
934
886
|
actual_size = actual.size_type || PCollectionType::DEFAULT_SIZE
|
@@ -943,11 +895,11 @@ module Types
|
|
943
895
|
end
|
944
896
|
end
|
945
897
|
else
|
946
|
-
[TypeMismatch.new(path,
|
898
|
+
[TypeMismatch.new(path, original, actual)]
|
947
899
|
end
|
948
900
|
end
|
949
901
|
|
950
|
-
def describe_PCallableType(expected, actual, path)
|
902
|
+
def describe_PCallableType(expected, original, actual, path)
|
951
903
|
if actual.is_a?(PCallableType)
|
952
904
|
# nil param_types means, any other Callable is assignable
|
953
905
|
if expected.param_types.nil? && expected.return_type.nil?
|
@@ -977,12 +929,12 @@ module Types
|
|
977
929
|
end
|
978
930
|
end
|
979
931
|
else
|
980
|
-
[TypeMismatch.new(path,
|
932
|
+
[TypeMismatch.new(path, original, actual)]
|
981
933
|
end
|
982
934
|
end
|
983
935
|
|
984
|
-
def describe_PAnyType(expected, actual, path)
|
985
|
-
expected.assignable?(actual) ? EMPTY_ARRAY : [TypeMismatch.new(path,
|
936
|
+
def describe_PAnyType(expected, original, actual, path)
|
937
|
+
expected.assignable?(actual) ? EMPTY_ARRAY : [TypeMismatch.new(path, original, actual)]
|
986
938
|
end
|
987
939
|
|
988
940
|
class UnresolvedTypeFinder
|
@@ -1008,33 +960,37 @@ module Types
|
|
1008
960
|
if unresolved
|
1009
961
|
[UnresolvedTypeReference.new(path, unresolved)]
|
1010
962
|
else
|
1011
|
-
expected
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
963
|
+
internal_describe(expected.normalize, expected, actual, path)
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
967
|
+
def internal_describe(expected, original, actual, path)
|
968
|
+
case expected
|
969
|
+
when PVariantType
|
970
|
+
describe_PVariantType(expected, original, actual, path)
|
971
|
+
when PStructType
|
972
|
+
describe_PStructType(expected, original, actual, path)
|
973
|
+
when PHashType
|
974
|
+
describe_PHashType(expected, original, actual, path)
|
975
|
+
when PTupleType
|
976
|
+
describe_PTupleType(expected, original, actual, path)
|
977
|
+
when PArrayType
|
978
|
+
describe_PArrayType(expected, original, actual, path)
|
979
|
+
when PCallableType
|
980
|
+
describe_PCallableType(expected, original, actual, path)
|
981
|
+
when POptionalType
|
982
|
+
describe_POptionalType(expected, original, actual, path)
|
983
|
+
when PPatternType
|
984
|
+
describe_PPatternType(expected, original, actual, path)
|
985
|
+
when PEnumType
|
986
|
+
describe_PEnumType(expected, original, actual, path)
|
987
|
+
when PTypeAliasType
|
988
|
+
describe_PTypeAliasType(expected, original, actual, path)
|
989
|
+
else
|
990
|
+
describe_PAnyType(expected, original, actual, path)
|
1036
991
|
end
|
1037
992
|
end
|
993
|
+
private :internal_describe
|
1038
994
|
|
1039
995
|
# Produces a string for the signature(s)
|
1040
996
|
#
|