summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Lindberg <henrik.lindberg@cloudsmith.com>2014-09-29 20:03:00 -0700
committerHenrik Lindberg <henrik.lindberg@cloudsmith.com>2014-09-29 20:03:00 -0700
commit7b4f1bc25ef5e442e587a00de3f19d75fc7ed6c6 (patch)
tree62ca79af8d02bc057b4d95bfcb76ae108dd65f3e
parent6d0d748f9e2832266aa7b4a278660983cdebb89a (diff)
downloadpuppet-7b4f1bc25ef5e442e587a00de3f19d75fc7ed6c6.tar.gz
PUP-3366 Fix issues with string/enum type assignable calculations
There were errors in the calculation of string/enum calculation. Basically Enum == String, if String is size constrained then Enum < String. This fixes this calculation. There were no tests for this, they are now added.
-rw-r--r--lib/puppet/pops/types/type_calculator.rb11
-rw-r--r--spec/unit/pops/types/type_calculator_spec.rb26
2 files changed, 31 insertions, 6 deletions
diff --git a/lib/puppet/pops/types/type_calculator.rb b/lib/puppet/pops/types/type_calculator.rb
index 644d007cd..1fe7fbea4 100644
--- a/lib/puppet/pops/types/type_calculator.rb
+++ b/lib/puppet/pops/types/type_calculator.rb
@@ -1155,7 +1155,7 @@ class Puppet::Pops::Types::TypeCalculator
case t2
when Types::PStringType
# if the set of strings are all found in the set of enums
- t2.values.all? { |s| t.values.any? { |e| e == s }}
+ !t2.values.empty?() && t2.values.all? { |s| t.values.any? { |e| e == s }}
when Types::PVariantType
t2.types.all? {|variant_t| assignable_PEnumType(t, variant_t) }
when Types::PEnumType
@@ -1184,7 +1184,7 @@ class Puppet::Pops::Types::TypeCalculator
assignable_PIntegerType(size_t, @collection_default_size_t)
when Types::PEnumType
- if t2.values
+ if t2.values && !t2.values.empty?
# true if all enum values are within range
min, max = t2.values.map(&:size).minmax
trange = from_to_ordered(size_t.from, size_t.to)
@@ -1192,8 +1192,9 @@ class Puppet::Pops::Types::TypeCalculator
# If t2 min and max are within the range of t
trange[0] <= t2range[0] && trange[1] >= t2range[1]
else
- # no string can match this enum anyway since it does not accept anything
- false
+ # enum represents all enums, and thus all strings, a sized constrained string can thus not
+ # be assigned any enum (unless it is max size).
+ assignable_PIntegerType(size_t, @collection_default_size_t)
end
else
# no other type matches string
@@ -1539,8 +1540,6 @@ class Puppet::Pops::Types::TypeCalculator
# translate to string, and skip Unit types
types = t.param_types.types.map {|t2| string(t2) unless t2.class == Types::PUnitType }.compact
- params_part= types.join(', ')
-
s = "Callable[" << types.join(', ')
unless range.empty?
(s << ', ') unless types.empty?
diff --git a/spec/unit/pops/types/type_calculator_spec.rb b/spec/unit/pops/types/type_calculator_spec.rb
index 0bd475263..e60a53651 100644
--- a/spec/unit/pops/types/type_calculator_spec.rb
+++ b/spec/unit/pops/types/type_calculator_spec.rb
@@ -10,6 +10,9 @@ describe 'The type calculator' do
t.to = to
t
end
+ def constrained_t(t, from, to)
+ Puppet::Pops::Types::TypeFactory.constrain_size(t, from, to)
+ end
def pattern_t(*patterns)
Puppet::Pops::Types::TypeFactory.pattern(*patterns)
@@ -848,6 +851,29 @@ describe 'The type calculator' do
end
end
+ context 'when dealing with string and enum combinations' do
+ it 'should accept assigning any enum to unrestricted string' do
+ calculator.assignable?(string_t(), enum_t('blue')).should == true
+ calculator.assignable?(string_t(), enum_t('blue', 'red')).should == true
+ end
+
+ it 'should not accept assigning longer enum value to size restricted string' do
+ calculator.assignable?(constrained_t(string_t(),2,2), enum_t('a','blue')).should == false
+ end
+
+ it 'should accept assigning any string to empty enum' do
+ calculator.assignable?(enum_t(), string_t()).should == true
+ end
+
+ it 'should accept assigning empty enum to any string' do
+ calculator.assignable?(string_t(), enum_t()).should == true
+ end
+
+ it 'should not accept assigning empty enum to size constrained string' do
+ calculator.assignable?(constrained_t(string_t(),2,2), enum_t()).should == false
+ end
+ end
+
context 'when dealing with tuples' do
it 'matches empty tuples' do
tuple1 = tuple_t()