puppet 5.1.0-universal-darwin → 5.2.0-universal-darwin

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.

Files changed (108) hide show
  1. data/lib/puppet.rb +6 -53
  2. data/lib/puppet/application.rb +14 -7
  3. data/lib/puppet/application/agent.rb +6 -2
  4. data/lib/puppet/application/apply.rb +6 -2
  5. data/lib/puppet/application/cert.rb +6 -2
  6. data/lib/puppet/application/describe.rb +6 -2
  7. data/lib/puppet/application/device.rb +40 -29
  8. data/lib/puppet/application/doc.rb +6 -2
  9. data/lib/puppet/application/filebucket.rb +6 -2
  10. data/lib/puppet/application/lookup.rb +6 -2
  11. data/lib/puppet/application/master.rb +6 -2
  12. data/lib/puppet/application/resource.rb +6 -2
  13. data/lib/puppet/face/catalog.rb +1 -1
  14. data/lib/puppet/face/certificate_request.rb +1 -1
  15. data/lib/puppet/face/certificate_revocation_list.rb +1 -1
  16. data/lib/puppet/face/help.rb +17 -13
  17. data/lib/puppet/file_serving/configuration.rb +3 -0
  18. data/lib/puppet/file_serving/configuration/parser.rb +2 -0
  19. data/lib/puppet/file_serving/mount/tasks.rb +21 -0
  20. data/lib/puppet/functions/epp.rb +3 -0
  21. data/lib/puppet/functions/lookup.rb +2 -1
  22. data/lib/puppet/generate/models/type/property.rb +1 -1
  23. data/lib/puppet/gettext/config.rb +70 -0
  24. data/lib/puppet/gettext/stubs.rb +11 -0
  25. data/lib/puppet/indirector/request.rb +4 -4
  26. data/lib/puppet/info_service.rb +10 -0
  27. data/lib/puppet/info_service/task_information_service.rb +32 -0
  28. data/lib/puppet/module.rb +43 -12
  29. data/lib/puppet/module/task.rb +90 -0
  30. data/lib/puppet/parser/ast/leaf.rb +1 -1
  31. data/lib/puppet/parser/functions/dig.rb +11 -2
  32. data/lib/puppet/parser/functions/epp.rb +3 -0
  33. data/lib/puppet/parser/functions/new.rb +8 -8
  34. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
  35. data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -0
  36. data/lib/puppet/pops/issues.rb +11 -5
  37. data/lib/puppet/pops/loader/static_loader.rb +1 -1
  38. data/lib/puppet/pops/model/factory.rb +42 -2
  39. data/lib/puppet/pops/model/model_tree_dumper.rb +1 -1
  40. data/lib/puppet/pops/parser/egrammar.ra +30 -9
  41. data/lib/puppet/pops/parser/eparser.rb +1094 -1043
  42. data/lib/puppet/pops/patterns.rb +1 -1
  43. data/lib/puppet/pops/serialization/from_data_converter.rb +1 -1
  44. data/lib/puppet/pops/serialization/json_path.rb +1 -1
  45. data/lib/puppet/pops/serialization/to_data_converter.rb +12 -3
  46. data/lib/puppet/pops/types/p_object_type.rb +31 -3
  47. data/lib/puppet/pops/types/p_sem_ver_range_type.rb +3 -3
  48. data/lib/puppet/pops/types/p_timespan_type.rb +1 -1
  49. data/lib/puppet/pops/types/p_timestamp_type.rb +1 -1
  50. data/lib/puppet/pops/types/string_converter.rb +15 -12
  51. data/lib/puppet/pops/types/type_calculator.rb +1 -1
  52. data/lib/puppet/pops/types/type_factory.rb +7 -0
  53. data/lib/puppet/pops/types/type_formatter.rb +1 -1
  54. data/lib/puppet/pops/types/type_mismatch_describer.rb +86 -130
  55. data/lib/puppet/pops/types/type_parser.rb +10 -4
  56. data/lib/puppet/pops/types/types.rb +81 -22
  57. data/lib/puppet/provider/package/aix.rb +4 -4
  58. data/lib/puppet/provider/package/yum.rb +1 -0
  59. data/lib/puppet/type.rb +1 -1
  60. data/lib/puppet/type/mount.rb +1 -1
  61. data/lib/puppet/type/sshkey.rb +9 -1
  62. data/lib/puppet/util.rb +1 -1
  63. data/lib/puppet/util/command_line.rb +1 -1
  64. data/lib/puppet/util/log.rb +15 -10
  65. data/lib/puppet/util/windows/api_types.rb +9 -5
  66. data/lib/puppet/util/windows/process.rb +9 -1
  67. data/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +1 -3
  68. data/lib/puppet/version.rb +1 -1
  69. data/locales/ja/puppet.po +9270 -0
  70. data/locales/puppet.pot +272 -212
  71. data/spec/fixtures/unit/provider/package/yum/yum-check-update-plugin-output.txt +36 -0
  72. data/spec/integration/indirector/file_content/file_server_spec.rb +17 -0
  73. data/spec/integration/indirector/file_metadata/file_server_spec.rb +10 -0
  74. data/spec/integration/util/windows/process_spec.rb +45 -0
  75. data/spec/lib/puppet_spec/modules.rb +10 -0
  76. data/spec/shared_contexts/types_setup.rb +19 -4
  77. data/spec/spec_helper.rb +6 -7
  78. data/spec/unit/face/help_spec.rb +2 -2
  79. data/spec/unit/file_serving/configuration_spec.rb +14 -4
  80. data/spec/unit/file_serving/mount/modules_spec.rb +1 -1
  81. data/spec/unit/file_serving/mount/tasks_spec.rb +72 -0
  82. data/spec/unit/functions/epp_spec.rb +5 -0
  83. data/spec/unit/functions/regsubst_spec.rb +1 -1
  84. data/spec/unit/gettext_config_spec.rb +57 -0
  85. data/spec/unit/indirector/request_spec.rb +41 -0
  86. data/spec/unit/info_service_spec.rb +66 -2
  87. data/spec/unit/module_spec.rb +81 -1
  88. data/spec/unit/parser/ast/leaf_spec.rb +3 -4
  89. data/spec/unit/pops/evaluator/access_ops_spec.rb +5 -0
  90. data/spec/unit/pops/factory_spec.rb +5 -1
  91. data/spec/unit/pops/parser/parser_spec.rb +138 -0
  92. data/spec/unit/pops/serialization/to_from_hr_spec.rb +74 -1
  93. data/spec/unit/pops/types/p_init_type_spec.rb +1 -1
  94. data/spec/unit/pops/types/p_object_type_spec.rb +217 -33
  95. data/spec/unit/pops/types/p_timespan_type_spec.rb +7 -0
  96. data/spec/unit/pops/types/p_timestamp_type_spec.rb +7 -0
  97. data/spec/unit/pops/types/string_converter_spec.rb +48 -11
  98. data/spec/unit/pops/types/type_calculator_spec.rb +37 -5
  99. data/spec/unit/pops/types/type_mismatch_describer_spec.rb +12 -0
  100. data/spec/unit/pops/types/type_parser_spec.rb +25 -0
  101. data/spec/unit/pops/validator/validator_spec.rb +2 -2
  102. data/spec/unit/provider/package/aix_spec.rb +26 -1
  103. data/spec/unit/provider/package/yum_spec.rb +10 -0
  104. data/spec/unit/task_spec.rb +102 -0
  105. data/spec/unit/util/log_spec.rb +32 -3
  106. data/spec/unit/util/windows/api_types_spec.rb +51 -0
  107. metadata +3476 -3450
  108. checksums.yaml +0 -7
@@ -517,4 +517,45 @@ describe Puppet::Indirector::Request do
517
517
  expect(request(:node => 'example.com', :ip => '127.0.0.1')).to be_remote
518
518
  end
519
519
  end
520
+
521
+ describe "failover" do
522
+ it "should use the provided failover host and port" do
523
+ Puppet.override(:server => 'myhost', :serverport => 666) do
524
+ req = Puppet::Indirector::Request.new('node', 'find', 'localhost', nil)
525
+ req.do_request() do |request|
526
+ expect(request.server).to eq('myhost')
527
+ expect(request.port).to eq(666)
528
+ end
529
+ end
530
+ end
531
+
532
+ it "should not use raw settings when failover fails" do
533
+ Puppet.override(:server => nil, :serverport => nil) do
534
+ req = Puppet::Indirector::Request.new('node', 'find', 'localhost', nil)
535
+ req.do_request() do |request|
536
+ expect(request.server).to be_nil
537
+ expect(request.port).to be_nil
538
+ expect(Puppet.settings[:server]).not_to be_nil
539
+ expect(Puppet.settings[:masterport]).not_to be_nil
540
+ end
541
+ end
542
+ end
543
+
544
+ it "should use server_list when set and failover has not occured" do
545
+ Puppet.settings[:server_list] = [['myhost',666]]
546
+ req = Puppet::Indirector::Request.new('node', 'find', 'localhost', nil)
547
+ req.do_request() do |request|
548
+ expect(request.server).to eq('myhost')
549
+ expect(request.port).to eq(666)
550
+ end
551
+ end
552
+
553
+ it "should use server when server_list is not set" do
554
+ req = Puppet::Indirector::Request.new('node', 'find', 'localhost', nil)
555
+ req.do_request() do |request|
556
+ expect(request.server).to eq(Puppet.settings[:server])
557
+ expect(request.port).to eq(Puppet.settings[:masterport])
558
+ end
559
+ end
560
+ end
520
561
  end
@@ -1,14 +1,78 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet_spec/files'
3
+ require 'puppet_spec/modules'
3
4
 
4
5
  require 'puppet/pops'
5
6
  require 'puppet/info_service'
6
7
  require 'puppet/pops/evaluator/literal_evaluator'
7
8
 
8
9
  describe "Puppet::InfoService" do
9
- context 'classes_per_environment service' do
10
- include PuppetSpec::Files
10
+ include PuppetSpec::Files
11
+
12
+ context 'task information service' do
13
+ let(:mod_name) { 'test1' }
14
+ let(:task_name) { "#{mod_name}::thingtask" }
15
+ let(:modpath) { tmpdir('modpath') }
16
+ let(:env_name) { 'testing' }
17
+ let(:env) { Puppet::Node::Environment.create(env_name.to_sym, [modpath]) }
18
+ let(:env_loader) { Puppet::Environments::Static.new(env) }
19
+
20
+ context 'tasks_per_environment method' do
21
+ it "returns task data for the tasks in an environment" do
22
+ Puppet.override(:environments => env_loader) do
23
+ mod = PuppetSpec::Modules.create(mod_name, modpath, {:environment => env, :tasks => [['thingtask']]})
24
+ expect(Puppet::InfoService.tasks_per_environment(env_name)).to eq([{:name => task_name, :module => {:name => mod_name}}])
25
+ end
26
+ end
27
+
28
+ it "should throw EnvironmentNotFound if given a nonexistent environment" do
29
+ expect{ Puppet::InfoService.tasks_per_environment('utopia') }.to raise_error(Puppet::Environments::EnvironmentNotFound)
30
+ end
31
+ end
32
+
33
+ context 'task_data method' do
34
+ before do
35
+ Puppet.override(:environments => env_loader) do
36
+ @mod = PuppetSpec::Modules.create(mod_name, modpath, {:environment => env, :tasks => [['thingtask', 'thingtask.json']]})
37
+ @result = Puppet::InfoService.task_data(env_name, mod_name, task_name)
38
+ end
39
+ end
40
+ describe 'in the happy case' do
41
+ it 'returns the right set of keys' do
42
+ expect(@result.keys.sort).to eq([:files, :metadata_file])
43
+ end
44
+ it 'specifies the metadata_file correctly' do
45
+ task = @mod.tasks[0]
46
+ expect(@result[:metadata_file]).to eq(task.metadata_file)
47
+ end
48
+
49
+ it 'specifies the other files correctly' do
50
+ task = @mod.tasks[0]
51
+ expect(@result[:files]).to eq(task.files)
52
+ end
53
+ end
11
54
 
55
+ it "should raise EnvironmentNotFound if given a nonexistent environment" do
56
+ expect{ Puppet::InfoService.task_data('utopia', mod_name, task_name) }.to raise_error(Puppet::Environments::EnvironmentNotFound)
57
+ end
58
+
59
+ it "should raise MissingModule if the module does not exist" do
60
+ Puppet.override(:environments => env_loader) do
61
+ expect { Puppet::InfoService.task_data(env_name, 'notamodule', 'notamodule::thingtask') }
62
+ .to raise_error(Puppet::Module::MissingModule)
63
+ end
64
+ end
65
+
66
+ it "should raise TaskNotFound if the task does not exist" do
67
+ Puppet.override(:environments => env_loader) do
68
+ expect { Puppet::InfoService.task_data(env_name, mod_name, 'testing1::notatask') }
69
+ .to raise_error(Puppet::Module::Task::TaskNotFound)
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ context 'classes_per_environment service' do
12
76
  let(:code_dir) do
13
77
  dir_containing('manifests', {
14
78
  'foo.pp' => <<-CODE,
@@ -222,7 +222,9 @@ describe Puppet::Module do
222
222
  env = Puppet::Node::Environment.create(:testing, [@modpath])
223
223
 
224
224
  ['test_gte_req', 'test_specific_req', 'foobar'].each do |mod_name|
225
- metadata_file = "#{@modpath}/#{mod_name}/metadata.json"
225
+ mod_dir = "#{@modpath}/#{mod_name}"
226
+ metadata_file = "#{mod_dir}/metadata.json"
227
+ tasks_dir = "#{mod_dir}/tasks"
226
228
  Puppet::FileSystem.stubs(:exist?).with(metadata_file).returns true
227
229
  end
228
230
  mod = PuppetSpec::Modules.create(
@@ -553,6 +555,84 @@ describe Puppet::Module do
553
555
  it "should return the path to the plugin directory" do
554
556
  expect(mod.plugin_directory).to eq(File.join(path, "lib"))
555
557
  end
558
+
559
+ it "should return the path to the tasks directory" do
560
+ expect(mod.tasks_directory).to eq(File.join(path, "tasks"))
561
+ end
562
+
563
+ describe "when finding tasks" do
564
+ before do
565
+ Puppet::FileSystem.unstub(:exist?)
566
+ @modpath = tmpdir('modpath')
567
+ Puppet.settings[:modulepath] = @modpath
568
+ end
569
+
570
+ it "should have an empty array for the tasks when the tasks directory does not exist" do
571
+ mod = PuppetSpec::Modules.create('tasks_test_nodir', @modpath, :environment => env)
572
+ expect(mod.tasks).to eq([])
573
+ end
574
+
575
+ it "should have an empty array for the tasks when the tasks directory does exist and is empty" do
576
+ mod = PuppetSpec::Modules.create('tasks_test_empty', @modpath, {:environment => env,
577
+ :tasks => []})
578
+ expect(mod.tasks).to eq([])
579
+ end
580
+
581
+ it "should list the expected tasks when the required files exist" do
582
+ fake_tasks = [['task1'], ['task2.sh', 'task2.json']]
583
+ mod = PuppetSpec::Modules.create('tasks_smoke', @modpath, {:environment => env,
584
+ :tasks => fake_tasks})
585
+
586
+ expect(mod.tasks.count).to eq(2)
587
+ expect(mod.tasks.map{|t| t.name}.sort).to eq(['tasks_smoke::task1', 'tasks_smoke::task2'])
588
+ expect(mod.tasks.map{|t| t.class}).to eq([Puppet::Module::Task] * 2)
589
+ end
590
+
591
+ it "should be able to find individual task files when they exist" do
592
+ task_exe = 'stateskatetask.stk'
593
+ mod = PuppetSpec::Modules.create('task_file_smoke', @modpath, {:environment => env,
594
+ :tasks => [[task_exe]]})
595
+
596
+ expect(mod.task_file(task_exe)).to eq("#{mod.path}/tasks/#{task_exe}")
597
+ end
598
+
599
+ it "should return nil when asked for an individual task file if it does not exist" do
600
+ mod = PuppetSpec::Modules.create('task_file_neg', @modpath, {:environment => env,
601
+ :tasks => []})
602
+ expect(mod.task_file('nosuchtask')).to be_nil
603
+ end
604
+
605
+ describe "does the task finding" do
606
+ before :each do
607
+ Puppet::FileSystem.unstub(:exist?)
608
+ Puppet::Module::Task.unstub(:tasks_in_module)
609
+ end
610
+
611
+ let(:mod_name) { 'tasks_test_lazy' }
612
+ let(:mod_tasks_dir) { File.join(@modpath, mod_name, 'tasks') }
613
+
614
+ it "after the module is initialized" do
615
+ Puppet::FileSystem.expects(:exist?).with(mod_tasks_dir).never
616
+ Puppet::Module::Task.expects(:tasks_in_module).never
617
+ Puppet::Module.new(mod_name, @modpath, env)
618
+ end
619
+
620
+ it "when the tasks method is called" do
621
+ Puppet::Module::Task.expects(:tasks_in_module)
622
+ mod = PuppetSpec::Modules.create(mod_name, @modpath, {:environment => env,
623
+ :tasks => [['itascanstaccatotask']]})
624
+ mod.tasks
625
+ end
626
+
627
+ it "only once for the lifetime of the module object" do
628
+ Dir.expects(:glob).with("#{mod_tasks_dir}/*").once.returns ['allalaskataskattacktactics']
629
+ mod = PuppetSpec::Modules.create(mod_name, @modpath, {:environment => env,
630
+ :tasks => []})
631
+ mod.tasks
632
+ mod.tasks
633
+ end
634
+ end
635
+ end
556
636
  end
557
637
 
558
638
  describe Puppet::Module, "when finding matching manifests" do
@@ -60,13 +60,12 @@ describe Puppet::Parser::AST::Regex do
60
60
  end
61
61
  end
62
62
 
63
- it "should return the regex source with to_s" do
63
+ it 'should return the PRegexpType#regexp_to_s_with_delimiters with to_s' do
64
64
  regex = stub 'regex'
65
65
  Regexp.stubs(:new).returns(regex)
66
66
 
67
- val = Puppet::Parser::AST::Regex.new :value => "/ab/"
68
-
69
- regex.expects(:source)
67
+ val = Puppet::Parser::AST::Regex.new :value => '/ab/'
68
+ Puppet::Pops::Types::PRegexpType.expects(:regexp_to_s_with_delimiters)
70
69
 
71
70
  val.to_s
72
71
  end
@@ -539,6 +539,11 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
539
539
  expect(evaluate(type_expr)).to eql(tf.callable([String], Integer))
540
540
  end
541
541
 
542
+ # Variant Type
543
+ it 'does not allow Variant declarations with non-type arguments' do
544
+ type_expr = fqr('Variant').access_at(fqr('Integer'), 'not a type')
545
+ expect { evaluate(type_expr) }.to raise_error(/Cannot use String where Any-Type is expected/)
546
+ end
542
547
  end
543
548
 
544
549
  matcher :be_the_type do |type|
@@ -45,7 +45,11 @@ describe Puppet::Pops::Model::Factory do
45
45
  end
46
46
 
47
47
  it "Multiple expressions should produce a block expression" do
48
- model = block_or_expression([literal(1) + literal(2), literal(2) + literal(3)]).model
48
+ braces = mock 'braces'
49
+ braces.stubs(:offset).returns(0)
50
+ braces.stubs(:length).returns(0)
51
+
52
+ model = block_or_expression([literal(1) + literal(2), literal(2) + literal(3)], braces, braces).model
49
53
  expect(model.is_a?(Puppet::Pops::Model::BlockExpression)).to eq(true)
50
54
  expect(model.statements.size).to eq(2)
51
55
  end
@@ -30,6 +30,144 @@ describe Puppet::Pops::Parser::Parser do
30
30
  expect(model.body.length).to eq(0)
31
31
  end
32
32
 
33
+ it "should give single resource expressions the correct offset inside an if/else statement" do
34
+ parser = Puppet::Pops::Parser::Parser.new()
35
+ model = parser.parse_string(<<-EOF).model
36
+ class firewall {
37
+ if(true) {
38
+ service { 'if service':
39
+ ensure => stopped
40
+ }
41
+ } else {
42
+ service { 'else service':
43
+ ensure => running
44
+ }
45
+ }
46
+ }
47
+ EOF
48
+
49
+ then_service = model.body.body.statements[0].then_expr
50
+ expect(then_service.class).to eq(Puppet::Pops::Model::ResourceExpression)
51
+ expect(then_service.offset).to eq(34)
52
+
53
+ else_service = model.body.body.statements[0].else_expr
54
+ expect(else_service.class).to eq(Puppet::Pops::Model::ResourceExpression)
55
+ expect(else_service.offset).to eq(106)
56
+ end
57
+
58
+ it "should give block expressions and their contained resources the correct offset inside an if/else statement" do
59
+ parser = Puppet::Pops::Parser::Parser.new()
60
+ model = parser.parse_string(<<-EOF).model
61
+ class firewall {
62
+ if(true) {
63
+ service { 'if service 1':
64
+ ensure => running
65
+ }
66
+
67
+ service { 'if service 2':
68
+ ensure => stopped
69
+ }
70
+ } else {
71
+ service { 'else service 1':
72
+ ensure => running
73
+ }
74
+
75
+ service { 'else service 2':
76
+ ensure => stopped
77
+ }
78
+ }
79
+ }
80
+ EOF
81
+
82
+ if_expr = model.body.body.statements[0]
83
+ block_expr = model.body.body.statements[0].then_expr
84
+ expect(if_expr.class).to eq(Puppet::Pops::Model::IfExpression)
85
+ expect(if_expr.offset).to eq(19)
86
+ expect(block_expr.class).to eq(Puppet::Pops::Model::BlockExpression)
87
+ expect(block_expr.offset).to eq(28)
88
+ expect(block_expr.statements[0].class).to eq(Puppet::Pops::Model::ResourceExpression)
89
+ expect(block_expr.statements[0].offset).to eq(34)
90
+ expect(block_expr.statements[1].class).to eq(Puppet::Pops::Model::ResourceExpression)
91
+ expect(block_expr.statements[1].offset).to eq(98)
92
+
93
+ block_expr = model.body.body.statements[0].else_expr
94
+ expect(block_expr.class).to eq(Puppet::Pops::Model::BlockExpression)
95
+ expect(block_expr.offset).to eq(166)
96
+ expect(block_expr.statements[0].class).to eq(Puppet::Pops::Model::ResourceExpression)
97
+ expect(block_expr.statements[0].offset).to eq(172)
98
+ expect(block_expr.statements[1].class).to eq(Puppet::Pops::Model::ResourceExpression)
99
+ expect(block_expr.statements[1].offset).to eq(238)
100
+ end
101
+
102
+ it "should give single resource expressions the correct offset inside an unless/else statement" do
103
+ parser = Puppet::Pops::Parser::Parser.new()
104
+ model = parser.parse_string(<<-EOF).model
105
+ class firewall {
106
+ unless(true) {
107
+ service { 'if service':
108
+ ensure => stopped
109
+ }
110
+ } else {
111
+ service { 'else service':
112
+ ensure => running
113
+ }
114
+ }
115
+ }
116
+ EOF
117
+
118
+ then_service = model.body.body.statements[0].then_expr
119
+ expect(then_service.class).to eq(Puppet::Pops::Model::ResourceExpression)
120
+ expect(then_service.offset).to eq(38)
121
+
122
+ else_service = model.body.body.statements[0].else_expr
123
+ expect(else_service.class).to eq(Puppet::Pops::Model::ResourceExpression)
124
+ expect(else_service.offset).to eq(110)
125
+ end
126
+
127
+ it "should give block expressions and their contained resources the correct offset inside an unless/else statement" do
128
+ parser = Puppet::Pops::Parser::Parser.new()
129
+ model = parser.parse_string(<<-EOF).model
130
+ class firewall {
131
+ unless(true) {
132
+ service { 'if service 1':
133
+ ensure => running
134
+ }
135
+
136
+ service { 'if service 2':
137
+ ensure => stopped
138
+ }
139
+ } else {
140
+ service { 'else service 1':
141
+ ensure => running
142
+ }
143
+
144
+ service { 'else service 2':
145
+ ensure => stopped
146
+ }
147
+ }
148
+ }
149
+ EOF
150
+
151
+ if_expr = model.body.body.statements[0]
152
+ block_expr = model.body.body.statements[0].then_expr
153
+ expect(if_expr.class).to eq(Puppet::Pops::Model::UnlessExpression)
154
+ expect(if_expr.offset).to eq(19)
155
+ expect(block_expr.class).to eq(Puppet::Pops::Model::BlockExpression)
156
+ expect(block_expr.offset).to eq(32)
157
+ expect(block_expr.statements[0].class).to eq(Puppet::Pops::Model::ResourceExpression)
158
+ expect(block_expr.statements[0].offset).to eq(38)
159
+ expect(block_expr.statements[1].class).to eq(Puppet::Pops::Model::ResourceExpression)
160
+ expect(block_expr.statements[1].offset).to eq(102)
161
+
162
+ block_expr = model.body.body.statements[0].else_expr
163
+ expect(block_expr.class).to eq(Puppet::Pops::Model::BlockExpression)
164
+ expect(block_expr.offset).to eq(170)
165
+ expect(block_expr.statements[0].class).to eq(Puppet::Pops::Model::ResourceExpression)
166
+ expect(block_expr.statements[0].offset).to eq(176)
167
+ expect(block_expr.statements[1].class).to eq(Puppet::Pops::Model::ResourceExpression)
168
+ expect(block_expr.statements[1].offset).to eq(242)
169
+ end
170
+
33
171
  it "multi byte characters in a comment are counted as individual bytes" do
34
172
  parser = Puppet::Pops::Parser::Parser.new()
35
173
  model = parser.parse_string("# \u{0400}comment\n").model
@@ -465,7 +465,7 @@ module Serialization
465
465
  end
466
466
 
467
467
  context 'and symbol_as_string is set to true' do
468
- let(:to_converter) { ToDataConverter.new(:symbol_as_string => true) }
468
+ let(:to_converter) { ToDataConverter.new(:rich_data => false, :symbol_as_string => true) }
469
469
 
470
470
  it 'A Hash with Symbol keys is silently converted to hash with String keys' do
471
471
  val = { :one => 'one', :two => 'two' }
@@ -477,6 +477,71 @@ module Serialization
477
477
  end
478
478
  expect(warnings).to be_empty
479
479
  end
480
+
481
+ it 'A Hash with Symbol values is silently converted to hash with String values' do
482
+ val = { 'one' => :one, 'two' => :two }
483
+ Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
484
+ write(val)
485
+ val2 = read
486
+ expect(val2).to be_a(Hash)
487
+ expect(val2).to eql({ 'one' => 'one', 'two' => 'two' })
488
+ end
489
+ expect(warnings).to be_empty
490
+ end
491
+
492
+ it 'A Hash with default values will have the values converted to string with a warning' do
493
+ val = { 'key' => :default }
494
+ Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
495
+ write(val)
496
+ val2 = read
497
+ expect(val2).to be_a(Hash)
498
+ expect(val2).to eql({ 'key' => 'default' })
499
+ end
500
+ expect(warnings).to eql(["['key'] contains the special value default. It will be converted to the String 'default'"])
501
+ end
502
+ end
503
+ end
504
+
505
+ context 'with rich_data is set to true' do
506
+ let(:to_converter) { ToDataConverter.new(:message_prefix => 'Test Hash', :rich_data => true) }
507
+ let(:logs) { [] }
508
+ let(:warnings) { logs.select { |log| log.level == :warning }.map { |log| log.message } }
509
+
510
+ context 'and symbol_as_string is set to true' do
511
+ let(:to_converter) { ToDataConverter.new(:rich_data => true, :symbol_as_string => true) }
512
+
513
+ it 'A Hash with Symbol keys is silently converted to hash with String keys' do
514
+ val = { :one => 'one', :two => 'two' }
515
+ Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
516
+ write(val)
517
+ val2 = read
518
+ expect(val2).to be_a(Hash)
519
+ expect(val2).to eql({ 'one' => 'one', 'two' => 'two' })
520
+ end
521
+ expect(warnings).to be_empty
522
+ end
523
+
524
+ it 'A Hash with Symbol values is silently converted to hash with String values' do
525
+ val = { 'one' => :one, 'two' => :two }
526
+ Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
527
+ write(val)
528
+ val2 = read
529
+ expect(val2).to be_a(Hash)
530
+ expect(val2).to eql({ 'one' => 'one', 'two' => 'two' })
531
+ end
532
+ expect(warnings).to be_empty
533
+ end
534
+
535
+ it 'A Hash with default values will not loose type information' do
536
+ val = { 'key' => :default }
537
+ Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
538
+ write(val)
539
+ val2 = read
540
+ expect(val2).to be_a(Hash)
541
+ expect(val2).to eql({ 'key' => :default })
542
+ end
543
+ expect(warnings).to be_empty
544
+ end
480
545
  end
481
546
  end
482
547
 
@@ -489,6 +554,14 @@ module Serialization
489
554
  expect { write(val) }.to raise_error(/Endless recursion detected when attempting to serialize value of class Hash/)
490
555
  end
491
556
  end
557
+
558
+ context 'will fail when' do
559
+ it 'the value of a type description is something other than a String or a Hash' do
560
+ expect do
561
+ from_converter.convert({ '__pcore_type__' => { '__pcore_type__' => 'Pcore::TimestampType', '__pcore_value__' => 12345 }})
562
+ end.to raise_error(/Cannot create a Pcore::TimestampType from a (Fixnum|Integer)/)
563
+ end
564
+ end
492
565
  end
493
566
  end
494
567
  end