puppet 4.5.3-universal-darwin → 4.6.1-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.
- checksums.yaml +7 -0
- data/Gemfile +10 -1
- data/ext/debian/control +2 -4
- data/ext/project_data.yaml +4 -4
- data/install.rb +6 -2
- data/lib/puppet.rb +3 -1
- data/lib/puppet/agent/locker.rb +1 -1
- data/lib/puppet/application.rb +6 -4
- data/lib/puppet/application/agent.rb +2 -1
- data/lib/puppet/application/cert.rb +35 -2
- data/lib/puppet/application/device.rb +1 -1
- data/lib/puppet/application/generate.rb +5 -0
- data/lib/puppet/application/lookup.rb +3 -3
- data/lib/puppet/application_support.rb +1 -1
- data/lib/puppet/compilable_resource_type.rb +15 -0
- data/lib/puppet/configurer.rb +67 -10
- data/lib/puppet/configurer/plugin_handler.rb +2 -4
- data/lib/puppet/data_providers/hiera_config.rb +1 -1
- data/lib/puppet/defaults.rb +34 -7
- data/lib/puppet/environments.rb +4 -2
- data/lib/puppet/error.rb +1 -1
- data/lib/puppet/external/dot.rb +1 -1
- data/lib/puppet/face/ca.rb +4 -1
- data/lib/puppet/face/certificate.rb +7 -1
- data/lib/puppet/face/epp.rb +5 -5
- data/lib/puppet/face/generate.rb +64 -0
- data/lib/puppet/face/help.rb +19 -13
- data/lib/puppet/face/man.rb +1 -1
- data/lib/puppet/feature/external_facts.rb +1 -1
- data/lib/puppet/file_system.rb +16 -0
- data/lib/puppet/file_system/file_impl.rb +5 -0
- data/lib/puppet/file_system/memory_impl.rb +4 -0
- data/lib/puppet/file_system/path_pattern.rb +1 -0
- data/lib/puppet/file_system/windows.rb +19 -0
- data/lib/puppet/functions.rb +3 -5
- data/lib/puppet/functions/assert_type.rb +1 -1
- data/lib/puppet/functions/defined.rb +7 -5
- data/lib/puppet/functions/dig.rb +2 -18
- data/lib/puppet/functions/hiera.rb +1 -1
- data/lib/puppet/functions/lest.rb +1 -37
- data/lib/puppet/functions/new.rb +2 -473
- data/lib/puppet/functions/reverse_each.rb +2 -59
- data/lib/puppet/functions/scanf.rb +4 -4
- data/lib/puppet/functions/step.rb +1 -63
- data/lib/puppet/functions/then.rb +1 -61
- data/lib/puppet/functions/type.rb +1 -40
- data/lib/puppet/functions/unwrap.rb +40 -0
- data/lib/puppet/generate/models/type/property.rb +70 -0
- data/lib/puppet/generate/models/type/type.rb +57 -0
- data/lib/puppet/generate/templates/type/pcore.erb +41 -0
- data/lib/puppet/generate/type.rb +239 -0
- data/lib/puppet/graph/simple_graph.rb +2 -6
- data/lib/puppet/indirector/catalog/static_compiler.rb +5 -2
- data/lib/puppet/indirector/facts/facter.rb +1 -1
- data/lib/puppet/indirector/key/ca.rb +2 -2
- data/lib/puppet/indirector/request.rb +25 -4
- data/lib/puppet/indirector/rest.rb +73 -3
- data/lib/puppet/info_service/class_information_service.rb +1 -2
- data/lib/puppet/interface/documentation.rb +1 -1
- data/lib/puppet/loaders.rb +2 -0
- data/lib/puppet/metatype/manager.rb +6 -6
- data/lib/puppet/module.rb +8 -1
- data/lib/puppet/module_tool.rb +2 -2
- data/lib/puppet/module_tool/checksums.rb +1 -1
- data/lib/puppet/module_tool/errors/installer.rb +2 -2
- data/lib/puppet/module_tool/metadata.rb +1 -1
- data/lib/puppet/network/http/api/indirected_routes.rb +23 -32
- data/lib/puppet/network/http/rack/rest.rb +15 -1
- data/lib/puppet/network/rights.rb +1 -11
- data/lib/puppet/node/environment.rb +7 -3
- data/lib/puppet/node/facts.rb +1 -1
- data/lib/puppet/parameter.rb +23 -3
- data/lib/puppet/parameter/boolean.rb +1 -1
- data/lib/puppet/parameter/value.rb +1 -1
- data/lib/puppet/parser.rb +0 -1
- data/lib/puppet/parser/ast/pops_bridge.rb +1 -1
- data/lib/puppet/parser/ast/resource.rb +5 -0
- data/lib/puppet/parser/ast/resource_instance.rb +5 -1
- data/lib/puppet/parser/ast/resourceparam.rb +5 -0
- data/lib/puppet/parser/compiler.rb +14 -17
- data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +1 -1
- data/lib/puppet/parser/environment_compiler.rb +10 -0
- data/lib/puppet/parser/functions/create_resources.rb +39 -24
- data/lib/puppet/parser/functions/defined.rb +2 -26
- data/lib/puppet/parser/functions/dig.rb +29 -0
- data/lib/puppet/parser/functions/lest.rb +49 -0
- data/lib/puppet/parser/functions/new.rb +530 -0
- data/lib/puppet/parser/functions/require.rb +1 -1
- data/lib/puppet/parser/functions/reverse_each.rb +83 -0
- data/lib/puppet/parser/functions/scanf.rb +4 -4
- data/lib/puppet/parser/functions/step.rb +84 -0
- data/lib/puppet/parser/functions/then.rb +73 -0
- data/lib/puppet/parser/functions/type.rb +53 -0
- data/lib/puppet/parser/resource.rb +16 -7
- data/lib/puppet/parser/scope.rb +36 -28
- data/lib/puppet/parser/type_loader.rb +1 -1
- data/lib/puppet/plugins/data_providers/data_provider.rb +1 -1
- data/lib/puppet/pops.rb +13 -0
- data/lib/puppet/pops/adapters.rb +49 -49
- data/lib/puppet/pops/binder/scheme_handler/confdir_scheme.rb +1 -1
- data/lib/puppet/pops/evaluator/access_operator.rb +39 -2
- data/lib/puppet/pops/evaluator/closure.rb +39 -13
- data/lib/puppet/pops/evaluator/collector_transformer.rb +10 -1
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +16 -11
- data/lib/puppet/pops/evaluator/external_syntax_support.rb +1 -1
- data/lib/puppet/pops/evaluator/json_strict_literal_evaluator.rb +0 -1
- data/lib/puppet/pops/evaluator/literal_evaluator.rb +0 -1
- data/lib/puppet/pops/evaluator/relationship_operator.rb +1 -2
- data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +119 -0
- data/lib/puppet/pops/evaluator/runtime3_support.rb +19 -45
- data/lib/puppet/pops/functions/function.rb +5 -0
- data/lib/puppet/pops/issues.rb +1 -1
- data/lib/puppet/pops/label_provider.rb +2 -2
- data/lib/puppet/pops/loader/base_loader.rb +12 -15
- data/lib/puppet/pops/loader/loader.rb +15 -50
- data/lib/puppet/pops/loader/loader_paths.rb +28 -2
- data/lib/puppet/pops/loader/module_loaders.rb +16 -1
- data/lib/puppet/pops/loader/null_loader.rb +17 -1
- data/lib/puppet/pops/loader/puppet_function_instantiator.rb +12 -11
- data/lib/puppet/pops/loader/puppet_resource_type_impl_instantiator.rb +80 -0
- data/lib/puppet/pops/loader/ruby_function_instantiator.rb +2 -3
- data/lib/puppet/pops/loader/runtime3_type_loader.rb +52 -13
- data/lib/puppet/pops/loader/static_loader.rb +55 -0
- data/lib/puppet/pops/loader/type_definition_instantiator.rb +30 -14
- data/lib/puppet/pops/loader/typed_name.rb +50 -0
- data/lib/puppet/pops/loaders.rb +64 -19
- data/lib/puppet/pops/merge_strategy.rb +7 -7
- data/lib/puppet/pops/migration/migration_checker.rb +4 -0
- data/lib/puppet/pops/model/model_label_provider.rb +2 -0
- data/lib/puppet/pops/parser/egrammar.ra +8 -5
- data/lib/puppet/pops/parser/eparser.rb +1550 -1498
- data/lib/puppet/pops/parser/evaluating_parser.rb +1 -1
- data/lib/puppet/pops/parser/interpolation_support.rb +7 -0
- data/lib/puppet/pops/parser/lexer2.rb +14 -1
- data/lib/puppet/pops/parser/locator.rb +30 -1
- data/lib/puppet/pops/parser/parser_support.rb +0 -3
- data/lib/puppet/pops/parser/slurp_support.rb +3 -3
- data/lib/puppet/pops/patterns.rb +9 -1
- data/lib/puppet/pops/pcore.rb +67 -11
- data/lib/puppet/pops/puppet_stack.rb +43 -0
- data/lib/puppet/pops/resource/param.rb +51 -0
- data/lib/puppet/pops/resource/resource_type_impl.rb +301 -0
- data/lib/puppet/pops/resource/resource_type_set.pcore +21 -0
- data/lib/puppet/pops/serialization.rb +17 -0
- data/lib/puppet/pops/serialization/abstract_reader.rb +149 -0
- data/lib/puppet/pops/serialization/abstract_writer.rb +179 -0
- data/lib/puppet/pops/serialization/deserializer.rb +60 -0
- data/lib/puppet/pops/serialization/extension.rb +126 -0
- data/lib/puppet/pops/serialization/instance_reader.rb +19 -0
- data/lib/puppet/pops/serialization/instance_writer.rb +14 -0
- data/lib/puppet/pops/serialization/json.rb +247 -0
- data/lib/puppet/pops/serialization/object.rb +63 -0
- data/lib/puppet/pops/serialization/rgen.rb +151 -0
- data/lib/puppet/pops/serialization/serializer.rb +91 -0
- data/lib/puppet/pops/serialization/time_factory.rb +66 -0
- data/lib/puppet/pops/types/annotatable.rb +36 -0
- data/lib/puppet/pops/types/implementation_registry.rb +3 -8
- data/lib/puppet/pops/types/p_meta_type.rb +83 -0
- data/lib/puppet/pops/types/p_object_type.rb +110 -117
- data/lib/puppet/pops/types/p_runtime_type.rb +13 -0
- data/lib/puppet/pops/types/p_sem_ver_range_type.rb +23 -0
- data/lib/puppet/pops/types/p_sem_ver_type.rb +30 -2
- data/lib/puppet/pops/types/p_sensitive_type.rb +69 -0
- data/lib/puppet/pops/types/p_type_set_type.rb +361 -0
- data/lib/puppet/pops/types/puppet_object.rb +0 -5
- data/lib/puppet/pops/types/ruby_generator.rb +9 -2
- data/lib/puppet/pops/types/type_calculator.rb +6 -1
- data/lib/puppet/pops/types/type_factory.rb +14 -12
- data/lib/puppet/pops/types/type_formatter.rb +78 -33
- data/lib/puppet/pops/types/type_mismatch_describer.rb +0 -2
- data/lib/puppet/pops/types/type_parser.rb +27 -2
- data/lib/puppet/pops/types/type_set_reference.rb +59 -0
- data/lib/puppet/pops/types/types.rb +366 -13
- data/lib/puppet/pops/validation.rb +4 -4
- data/lib/puppet/pops/validation/checker4_0.rb +5 -2
- data/lib/puppet/pops/visitor.rb +2 -2
- data/lib/puppet/property.rb +64 -5
- data/lib/puppet/provider.rb +1 -1
- data/lib/puppet/provider/aixobject.rb +3 -3
- data/lib/puppet/provider/group/aix.rb +4 -4
- data/lib/puppet/provider/macauthorization/macauthorization.rb +1 -1
- data/lib/puppet/provider/mailalias/aliases.rb +1 -1
- data/lib/puppet/provider/mcx/mcxcontent.rb +2 -2
- data/lib/puppet/provider/mount/parsed.rb +1 -1
- data/lib/puppet/provider/nameservice/directoryservice.rb +5 -5
- data/lib/puppet/provider/package/appdmg.rb +3 -3
- data/lib/puppet/provider/package/apple.rb +1 -1
- data/lib/puppet/provider/package/dnf.rb +5 -0
- data/lib/puppet/provider/package/nim.rb +1 -1
- data/lib/puppet/provider/package/pacman.rb +2 -2
- data/lib/puppet/provider/package/pip.rb +5 -3
- data/lib/puppet/provider/package/pip3.rb +1 -1
- data/lib/puppet/provider/package/pkg.rb +5 -5
- data/lib/puppet/provider/package/pkgdmg.rb +4 -4
- data/lib/puppet/provider/package/pkgin.rb +1 -1
- data/lib/puppet/provider/package/pkgutil.rb +1 -1
- data/lib/puppet/provider/package/portage.rb +48 -8
- data/lib/puppet/provider/package/sun.rb +1 -1
- data/lib/puppet/provider/package/tdnf.rb +28 -0
- data/lib/puppet/provider/package/yum.rb +22 -4
- data/lib/puppet/provider/parsedfile.rb +2 -2
- data/lib/puppet/provider/service/base.rb +1 -1
- data/lib/puppet/provider/service/bsd.rb +1 -1
- data/lib/puppet/provider/service/daemontools.rb +2 -2
- data/lib/puppet/provider/service/debian.rb +3 -3
- data/lib/puppet/provider/service/init.rb +5 -3
- data/lib/puppet/provider/service/launchd.rb +16 -2
- data/lib/puppet/provider/service/runit.rb +1 -1
- data/lib/puppet/provider/service/smf.rb +8 -1
- data/lib/puppet/provider/service/systemd.rb +39 -6
- data/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
- data/lib/puppet/provider/user/aix.rb +3 -2
- data/lib/puppet/provider/user/directoryservice.rb +4 -3
- data/lib/puppet/provider/user/hpux.rb +1 -1
- data/lib/puppet/provider/user/user_role_add.rb +1 -1
- data/lib/puppet/provider/user/windows_adsi.rb +3 -0
- data/lib/puppet/provider/zfs/zfs.rb +1 -1
- data/lib/puppet/reference/type.rb +1 -1
- data/lib/puppet/resource.rb +33 -7
- data/lib/puppet/resource/capability_finder.rb +74 -54
- data/lib/puppet/resource/status.rb +11 -2
- data/lib/puppet/settings.rb +17 -6
- data/lib/puppet/settings/environment_conf.rb +1 -1
- data/lib/puppet/settings/server_list_setting.rb +20 -0
- data/lib/puppet/ssl/certificate_authority.rb +32 -9
- data/lib/puppet/ssl/certificate_authority/interface.rb +164 -24
- data/lib/puppet/ssl/host.rb +3 -3
- data/lib/puppet/ssl/oids.rb +10 -0
- data/lib/puppet/ssl/validator/default_validator.rb +2 -2
- data/lib/puppet/test/test_helper.rb +2 -2
- data/lib/puppet/transaction.rb +12 -0
- data/lib/puppet/transaction/additional_resource_generator.rb +1 -1
- data/lib/puppet/transaction/event.rb +29 -2
- data/lib/puppet/transaction/event_manager.rb +1 -1
- data/lib/puppet/transaction/persistence.rb +84 -0
- data/lib/puppet/transaction/report.rb +49 -2
- data/lib/puppet/transaction/resource_harness.rb +98 -18
- data/lib/puppet/type.rb +63 -21
- data/lib/puppet/type/augeas.rb +3 -3
- data/lib/puppet/type/cron.rb +1 -1
- data/lib/puppet/type/file.rb +39 -2
- data/lib/puppet/type/file/data_sync.rb +13 -5
- data/lib/puppet/type/host.rb +1 -1
- data/lib/puppet/type/mount.rb +2 -6
- data/lib/puppet/type/notify.rb +1 -1
- data/lib/puppet/type/package.rb +1 -1
- data/lib/puppet/type/resources.rb +1 -1
- data/lib/puppet/type/scheduled_task.rb +1 -1
- data/lib/puppet/type/ssh_authorized_key.rb +2 -2
- data/lib/puppet/type/tidy.rb +1 -1
- data/lib/puppet/type/yumrepo.rb +3 -3
- data/lib/puppet/type/zone.rb +1 -1
- data/lib/puppet/util.rb +2 -2
- data/lib/puppet/util/classgen.rb +1 -1
- data/lib/puppet/util/command_line.rb +6 -2
- data/lib/puppet/util/command_line/trollop.rb +1 -1
- data/lib/puppet/util/execution.rb +2 -2
- data/lib/puppet/util/http_proxy.rb +1 -1
- data/lib/puppet/util/inifile.rb +1 -1
- data/lib/puppet/util/instance_loader.rb +1 -1
- data/lib/puppet/util/logging.rb +1 -1
- data/lib/puppet/util/multi_match.rb +1 -1
- data/lib/puppet/util/plist.rb +15 -5
- data/lib/puppet/util/profiler.rb +1 -1
- data/lib/puppet/util/profiler/around_profiler.rb +1 -1
- data/lib/puppet/util/psych_support.rb +1 -1
- data/lib/puppet/util/rdoc.rb +2 -2
- data/lib/puppet/util/rubygems.rb +1 -1
- data/lib/puppet/util/watcher/periodic_watcher.rb +2 -2
- data/lib/puppet/util/windows/access_control_entry.rb +1 -1
- data/lib/puppet/util/windows/adsi.rb +30 -8
- data/lib/puppet/util/windows/api_types.rb +1 -1
- data/lib/puppet/util/windows/file.rb +59 -0
- data/lib/puppet/util/windows/process.rb +10 -0
- data/lib/puppet/util/windows/security.rb +1 -1
- data/lib/puppet/util/windows/user.rb +22 -4
- data/lib/puppet/util/yaml.rb +15 -3
- data/lib/puppet/vendor/deep_merge/test/test_deep_merge.rb +1 -1
- data/lib/puppet/vendor/rgen_patch.rb +1 -1
- data/lib/puppet/version.rb +2 -2
- data/spec/fixtures/unit/pops/loaders/loaders/no_modules/manifests/site.pp +10 -0
- data/spec/integration/agent/logging_spec.rb +15 -14
- data/spec/integration/application/apply_spec.rb +1 -0
- data/spec/integration/directory_environments_spec.rb +16 -0
- data/spec/integration/environments/settings_spec.rb +32 -4
- data/spec/integration/faces/documentation_spec.rb +1 -1
- data/spec/integration/network/http/api/indirected_routes_spec.rb +33 -0
- data/spec/integration/node/environment_spec.rb +21 -0
- data/spec/integration/parser/collection_spec.rb +10 -0
- data/spec/integration/parser/compiler_spec.rb +76 -840
- data/spec/integration/parser/functions/require_spec.rb +3 -3
- data/spec/integration/parser/parameter_defaults_spec.rb +6 -2
- data/spec/integration/parser/pcore_resource_spec.rb +208 -0
- data/spec/integration/parser/resource_expressions_spec.rb +4 -2
- data/spec/integration/provider/yumrepo_spec.rb +4 -1
- data/spec/integration/transaction/report_spec.rb +666 -0
- data/spec/integration/type/file_spec.rb +11 -12
- data/spec/integration/util/windows/adsi_spec.rb +99 -0
- data/spec/integration/util/windows/principal_spec.rb +109 -60
- data/spec/integration/util/windows/process_spec.rb +4 -2
- data/spec/integration/util/windows/security_spec.rb +34 -8
- data/spec/integration/util/windows/user_spec.rb +26 -4
- data/spec/lib/puppet_spec/files.rb +2 -2
- data/spec/lib/puppet_spec/network.rb +12 -8
- data/spec/shared_examples/rhel_package_provider.rb +341 -0
- data/spec/spec_helper.rb +8 -2
- data/spec/unit/application/cert_spec.rb +20 -0
- data/spec/unit/configurer/plugin_handler_spec.rb +0 -26
- data/spec/unit/configurer_spec.rb +46 -0
- data/spec/unit/defaults_spec.rb +14 -0
- data/spec/unit/face/generate_spec.rb +230 -0
- data/spec/unit/face/help_spec.rb +53 -0
- data/spec/unit/face/parser_spec.rb +6 -0
- data/spec/unit/face/plugin_spec.rb +0 -4
- data/spec/unit/file_system_spec.rb +85 -0
- data/spec/unit/functions/lookup_spec.rb +4 -4
- data/spec/unit/functions/match_spec.rb +2 -2
- data/spec/unit/functions/regsubst_spec.rb +1 -1
- data/spec/unit/functions/split_spec.rb +1 -1
- data/spec/unit/functions/unwrap_spec.rb +29 -0
- data/spec/unit/functions/versioncmp_spec.rb +1 -1
- data/spec/unit/functions4_spec.rb +8 -8
- data/spec/unit/indirector/facts/facter_spec.rb +1 -9
- data/spec/unit/indirector/rest_spec.rb +95 -9
- data/spec/unit/module_spec.rb +43 -7
- data/spec/unit/module_tool/applications/installer_spec.rb +10 -1
- data/spec/unit/module_tool/applications/unpacker_spec.rb +2 -1
- data/spec/unit/module_tool/applications/upgrader_spec.rb +8 -0
- data/spec/unit/module_tool/tar/mini_spec.rb +3 -3
- data/spec/unit/network/http/api/indirected_routes_spec.rb +49 -58
- data/spec/unit/network/http/api/master/v3_spec.rb +7 -4
- data/spec/unit/network/rights_spec.rb +1 -1
- data/spec/unit/parameter_spec.rb +11 -0
- data/spec/unit/parser/compiler_spec.rb +19 -33
- data/spec/unit/{appmgmt_spec.rb → parser/environment_compiler_spec.rb} +12 -1
- data/spec/unit/parser/functions/create_resources_spec.rb +76 -4
- data/spec/unit/parser/functions/require_spec.rb +2 -2
- data/spec/unit/parser/resource_spec.rb +21 -11
- data/spec/unit/parser/scope_spec.rb +1 -5
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +1 -1
- data/spec/unit/pops/loaders/dependency_loader_spec.rb +1 -1
- data/spec/unit/pops/loaders/loader_paths_spec.rb +1 -1
- data/spec/unit/pops/loaders/loaders_spec.rb +63 -5
- data/spec/unit/pops/loaders/module_loaders_spec.rb +2 -2
- data/spec/unit/pops/loaders/static_loader_spec.rb +1 -1
- data/spec/unit/pops/parser/lexer2_spec.rb +27 -3
- data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +8 -0
- data/spec/unit/pops/parser/parse_calls_spec.rb +9 -0
- data/spec/unit/pops/puppet_stack_spec.rb +79 -0
- data/spec/unit/pops/resource/resource_type_impl_spec.rb +37 -0
- data/spec/unit/pops/serialization/packer_spec.rb +153 -0
- data/spec/unit/pops/serialization/rgen_spec.rb +88 -0
- data/spec/unit/pops/serialization/serialization_spec.rb +228 -0
- data/spec/unit/pops/types/p_object_type_spec.rb +44 -2
- data/spec/unit/pops/types/p_sem_ver_type_spec.rb +42 -0
- data/spec/unit/pops/types/p_sensitive_type_spec.rb +139 -0
- data/spec/unit/pops/types/p_type_set_type_spec.rb +424 -0
- data/spec/unit/pops/types/ruby_generator_spec.rb +497 -181
- data/spec/unit/pops/types/type_calculator_spec.rb +10 -4
- data/spec/unit/pops/types/type_formatter_spec.rb +1 -1
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +2 -2
- data/spec/unit/pops/types/type_parser_spec.rb +1 -1
- data/spec/unit/pops/types/types_spec.rb +1 -1
- data/spec/unit/pops/validator/validator_spec.rb +18 -1
- data/spec/unit/property_spec.rb +48 -11
- data/spec/unit/provider/group/windows_adsi_spec.rb +11 -1
- data/spec/unit/provider/package/dnf_spec.rb +1 -99
- data/spec/unit/provider/package/pacman_spec.rb +4 -4
- data/spec/unit/provider/package/pip_spec.rb +14 -0
- data/spec/unit/provider/package/pkg_spec.rb +6 -0
- data/spec/unit/provider/package/pkgdmg_spec.rb +0 -3
- data/spec/unit/provider/package/portage_spec.rb +64 -8
- data/spec/unit/provider/package/tdnf_spec.rb +18 -0
- data/spec/unit/provider/package/windows/package_spec.rb +4 -1
- data/spec/unit/provider/package/windows_spec.rb +8 -2
- data/spec/unit/provider/package/yum_spec.rb +6 -377
- data/spec/unit/provider/service/base_spec.rb +6 -0
- data/spec/unit/provider/service/debian_spec.rb +16 -7
- data/spec/unit/provider/service/gentoo_spec.rb +6 -0
- data/spec/unit/provider/service/init_spec.rb +7 -0
- data/spec/unit/provider/service/launchd_spec.rb +35 -4
- data/spec/unit/provider/service/openrc_spec.rb +6 -0
- data/spec/unit/provider/service/smf_spec.rb +31 -6
- data/spec/unit/provider/service/src_spec.rb +6 -0
- data/spec/unit/provider/service/systemd_spec.rb +70 -20
- data/spec/unit/provider/service/upstart_spec.rb +6 -0
- data/spec/unit/provider/user/aix_spec.rb +7 -0
- data/spec/unit/provider/user/directoryservice_spec.rb +30 -1
- data/spec/unit/provider/user/windows_adsi_spec.rb +19 -0
- data/spec/unit/resource/capability_finder_spec.rb +51 -3
- data/spec/unit/resource/catalog_spec.rb +5 -0
- data/spec/unit/resource/type_spec.rb +2 -2
- data/spec/unit/resource_spec.rb +19 -0
- data/spec/unit/settings_spec.rb +13 -0
- data/spec/unit/ssl/certificate_authority/interface_spec.rb +176 -10
- data/spec/unit/ssl/certificate_authority_spec.rb +63 -22
- data/spec/unit/ssl/host_spec.rb +1 -1
- data/spec/unit/ssl/oids_spec.rb +24 -21
- data/spec/unit/transaction/event_spec.rb +3 -1
- data/spec/unit/transaction/persistence_spec.rb +173 -0
- data/spec/unit/transaction/report_spec.rb +64 -1
- data/spec/unit/transaction/resource_harness_spec.rb +91 -0
- data/spec/unit/type/file/content_spec.rb +47 -15
- data/spec/unit/type/file_spec.rb +28 -0
- data/spec/unit/type/mount_spec.rb +5 -12
- data/spec/unit/type/yumrepo_spec.rb +1 -5
- data/spec/unit/type_spec.rb +32 -0
- data/spec/unit/util/command_line_spec.rb +11 -0
- data/spec/unit/util/execution_spec.rb +1 -1
- data/spec/unit/util/plist_spec.rb +16 -3
- data/spec/unit/util/storage_spec.rb +4 -1
- data/spec/unit/util/windows/adsi_spec.rb +23 -2
- data/spec/unit/util/windows/file_spec.rb +56 -1
- data/spec/unit/util/windows/sid_spec.rb +31 -7
- data/spec/unit/util/yaml_spec.rb +12 -0
- data/spec/unit/util_spec.rb +87 -20
- metadata +89 -34
- data/ext/puppetlisten/puppetlisten.rb +0 -77
- data/ext/puppetlisten/puppetrun.rb +0 -38
- data/lib/puppet/resource/type_collection_helper.rb +0 -7
- data/spec/unit/parser/functions/defined_spec.rb +0 -120
- data/spec/unit/resource/type_collection_helper_spec.rb +0 -24
@@ -0,0 +1,424 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/pops'
|
3
|
+
require 'puppet_spec/compiler'
|
4
|
+
|
5
|
+
module Puppet::Pops
|
6
|
+
module Types
|
7
|
+
describe 'The TypeSet Type' do
|
8
|
+
include PuppetSpec::Compiler
|
9
|
+
|
10
|
+
let(:parser) { TypeParser.singleton }
|
11
|
+
let(:pp_parser) { Parser::EvaluatingParser.new }
|
12
|
+
let(:env) { Puppet::Node::Environment.create('test', []) }
|
13
|
+
let(:loaders) { Loaders.new(env) }
|
14
|
+
let(:loader) { loaders.find_loader(nil) }
|
15
|
+
|
16
|
+
def type_set_t(name, body_string, name_authority)
|
17
|
+
i12n_literal_hash = pp_parser.parse_string("{#{body_string}}").current.body
|
18
|
+
typeset = PTypeSetType.new(name, i12n_literal_hash, name_authority)
|
19
|
+
loader.set_entry(Loader::TypedName.new(:type, name.downcase, name_authority), typeset)
|
20
|
+
typeset
|
21
|
+
end
|
22
|
+
|
23
|
+
# Creates and parses an alias type declaration of a TypeSet, e.g.
|
24
|
+
# ```
|
25
|
+
# type <name> = TypeSet[{<body_string>}]
|
26
|
+
# ```
|
27
|
+
# The declaration implies the name authority {Pcore::RUNTIME_NAME_AUTHORITY}
|
28
|
+
#
|
29
|
+
# @param name [String] the name of the type set
|
30
|
+
# @param body [String] the body (initialization hash) of the type-set
|
31
|
+
# @return [PTypeSetType] the created type set
|
32
|
+
def parse_type_set(name, body, name_authority = Pcore::RUNTIME_NAME_AUTHORITY)
|
33
|
+
type_set_t(name, body, name_authority)
|
34
|
+
parser.parse(name, loader)
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when validating the initialization hash' do
|
38
|
+
context 'it will allow that it' do
|
39
|
+
it 'has no types and no references' do
|
40
|
+
ts = <<-OBJECT
|
41
|
+
version => '1.0.0',
|
42
|
+
pcore_version => '1.0.0',
|
43
|
+
OBJECT
|
44
|
+
expect { parse_type_set('MySet', ts) }.not_to raise_error
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'has only references' do
|
48
|
+
parse_type_set('FirstSet', <<-OBJECT)
|
49
|
+
version => '1.0.0',
|
50
|
+
pcore_version => '1.0.0',
|
51
|
+
types => {
|
52
|
+
Car => Object[{}]
|
53
|
+
}
|
54
|
+
OBJECT
|
55
|
+
|
56
|
+
expect { parse_type_set('SecondSet', <<-OBJECT) }.not_to raise_error
|
57
|
+
version => '1.0.0',
|
58
|
+
pcore_version => '1.0.0',
|
59
|
+
references => {
|
60
|
+
First => {
|
61
|
+
name => 'FirstSet',
|
62
|
+
version_range => '1.x'
|
63
|
+
}
|
64
|
+
}
|
65
|
+
OBJECT
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'has multiple references to equally named TypeSets using different name authorities' do
|
69
|
+
parse_type_set('FirstSet', <<-OBJECT, 'http://example.com/ns1')
|
70
|
+
version => '1.0.0',
|
71
|
+
pcore_version => '1.0.0',
|
72
|
+
types => {
|
73
|
+
Car => Object[{}]
|
74
|
+
}
|
75
|
+
OBJECT
|
76
|
+
|
77
|
+
parse_type_set('FirstSet', <<-OBJECT, 'http://example.com/ns2')
|
78
|
+
version => '1.0.0',
|
79
|
+
pcore_version => '1.0.0',
|
80
|
+
types => {
|
81
|
+
Car => Object[{}]
|
82
|
+
}
|
83
|
+
OBJECT
|
84
|
+
|
85
|
+
expect { parse_type_set('SecondSet', <<-OBJECT) }.not_to raise_error
|
86
|
+
version => '1.0.0',
|
87
|
+
pcore_version => '1.0.0',
|
88
|
+
references => {
|
89
|
+
First_1 => {
|
90
|
+
name_authority => 'http://example.com/ns1',
|
91
|
+
name => 'FirstSet',
|
92
|
+
version_range => '1.x'
|
93
|
+
},
|
94
|
+
First_2 => {
|
95
|
+
name => 'FirstSet',
|
96
|
+
name_authority => 'http://example.com/ns2',
|
97
|
+
version_range => '1.x'
|
98
|
+
}
|
99
|
+
}
|
100
|
+
OBJECT
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'it raises an error when' do
|
105
|
+
it 'pcore_version is missing' do
|
106
|
+
ts = <<-OBJECT
|
107
|
+
version => '1.0.0',
|
108
|
+
OBJECT
|
109
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
110
|
+
/expected a value for key 'pcore_version'/)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'version is missing' do
|
114
|
+
ts = <<-OBJECT
|
115
|
+
pcore_version => '1.0.0',
|
116
|
+
OBJECT
|
117
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
118
|
+
/expected a value for key 'version'/)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'the version is an invalid semantic version' do
|
122
|
+
ts = <<-OBJECT
|
123
|
+
version => '1.x',
|
124
|
+
pcore_version => '1.0.0',
|
125
|
+
OBJECT
|
126
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(Semantic::Version::ValidationFailure)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'the pcore_version is an invalid semantic version' do
|
130
|
+
ts = <<-OBJECT
|
131
|
+
version => '1.0.0',
|
132
|
+
pcore_version => '1.x',
|
133
|
+
OBJECT
|
134
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(Semantic::Version::ValidationFailure)
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'the pcore_version is outside of the range of that is parsable by this runtime' do
|
138
|
+
ts = <<-OBJECT
|
139
|
+
version => '1.0.0',
|
140
|
+
pcore_version => '2.0.0',
|
141
|
+
OBJECT
|
142
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(ArgumentError,
|
143
|
+
/The pcore version for TypeSet 'MySet' is not understood by this runtime. Expected range 1\.x, got 2\.0\.0/)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'the name authority is an invalid URI' do
|
147
|
+
ts = <<-OBJECT
|
148
|
+
version => '1.0.0',
|
149
|
+
pcore_version => '1.0.0',
|
150
|
+
name_authority => 'not a valid URI'
|
151
|
+
OBJECT
|
152
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
153
|
+
/entry 'name_authority' expected a match for Pattern\[.*\], got 'not a valid URI'/m)
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'the types map' do
|
157
|
+
it 'is empty' do
|
158
|
+
ts = <<-OBJECT
|
159
|
+
pcore_version => '1.0.0',
|
160
|
+
version => '1.0.0',
|
161
|
+
types => {}
|
162
|
+
OBJECT
|
163
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
164
|
+
/entry 'types' expected size to be at least 1, got 0/)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'is not a map' do
|
168
|
+
ts = <<-OBJECT
|
169
|
+
pcore_version => '1.0.0',
|
170
|
+
version => '1.0.0',
|
171
|
+
types => []
|
172
|
+
OBJECT
|
173
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(Puppet::Error,
|
174
|
+
/entry 'types' expected a Hash value, got Array/)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'contains values that are not types' do
|
178
|
+
ts = <<-OBJECT
|
179
|
+
pcore_version => '1.0.0',
|
180
|
+
version => '1.0.0',
|
181
|
+
types => {
|
182
|
+
Car => 'brum'
|
183
|
+
}
|
184
|
+
OBJECT
|
185
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(Puppet::Error,
|
186
|
+
/The expression <'brum'> is not a valid type specification/)
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'contains keys that are not SimpleNames' do
|
190
|
+
ts = <<-OBJECT
|
191
|
+
pcore_version => '1.0.0',
|
192
|
+
version => '1.0.0',
|
193
|
+
types => {
|
194
|
+
car => Integer
|
195
|
+
}
|
196
|
+
OBJECT
|
197
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
198
|
+
/key of entry 'car' expected a match for Pattern\[\/\\A\[A-Z\]\\w\*\\z\/\], got 'car'/)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'the references hash' do
|
203
|
+
it 'is empty' do
|
204
|
+
ts = <<-OBJECT
|
205
|
+
pcore_version => '1.0.0',
|
206
|
+
version => '1.0.0',
|
207
|
+
references => {}
|
208
|
+
OBJECT
|
209
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
210
|
+
/entry 'references' expected size to be at least 1, got 0/)
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'is not a hash' do
|
214
|
+
ts = <<-OBJECT
|
215
|
+
pcore_version => '1.0.0',
|
216
|
+
version => '1.0.0',
|
217
|
+
references => []
|
218
|
+
OBJECT
|
219
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
220
|
+
/entry 'references' expected a Hash value, got Array/)
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'contains something other than reference initialization maps' do
|
224
|
+
ts = <<-OBJECT
|
225
|
+
pcore_version => '1.0.0',
|
226
|
+
version => '1.0.0',
|
227
|
+
references => {Ref => 2}
|
228
|
+
OBJECT
|
229
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
230
|
+
/entry 'references' entry 'Ref' expected a Struct value, got Integer/)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'contains several initialization that refers to the same TypeSet' do
|
234
|
+
ts = <<-OBJECT
|
235
|
+
pcore_version => '1.0.0',
|
236
|
+
version => '1.0.0',
|
237
|
+
references => {
|
238
|
+
A => { name => 'Vehicle::Cars', version_range => '1.x' },
|
239
|
+
V => { name => 'Vehicle::Cars', version_range => '1.x' },
|
240
|
+
}
|
241
|
+
OBJECT
|
242
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(ArgumentError,
|
243
|
+
/references TypeSet 'http:\/\/puppet\.com\/2016\.1\/runtime\/Vehicle::Cars' more than once using overlapping version ranges/)
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'contains an initialization maps with an alias that collides with a type name' do
|
247
|
+
ts = <<-OBJECT
|
248
|
+
pcore_version => '1.0.0',
|
249
|
+
version => '1.0.0',
|
250
|
+
types => {
|
251
|
+
Car => Object[{}]
|
252
|
+
},
|
253
|
+
references => {
|
254
|
+
Car => { name => 'Vehicle::Car', version_range => '1.x' }
|
255
|
+
}
|
256
|
+
OBJECT
|
257
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(ArgumentError,
|
258
|
+
/references a TypeSet using alias 'Car'. The alias collides with the name of a declared type/)
|
259
|
+
end
|
260
|
+
|
261
|
+
context 'contains an initialization map that' do
|
262
|
+
it 'has no version range' do
|
263
|
+
ts = <<-OBJECT
|
264
|
+
pcore_version => '1.0.0',
|
265
|
+
version => '1.0.0',
|
266
|
+
references => { Ref => { name => 'X' } }
|
267
|
+
OBJECT
|
268
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
269
|
+
/entry 'references' entry 'Ref' expected a value for key 'version_range'/)
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'has no name' do
|
273
|
+
ts = <<-OBJECT
|
274
|
+
pcore_version => '1.0.0',
|
275
|
+
version => '1.0.0',
|
276
|
+
references => { Ref => { version_range => '1.x' } }
|
277
|
+
OBJECT
|
278
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
279
|
+
/entry 'references' entry 'Ref' expected a value for key 'name'/)
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'has a name that is not a QRef' do
|
283
|
+
ts = <<-OBJECT
|
284
|
+
pcore_version => '1.0.0',
|
285
|
+
version => '1.0.0',
|
286
|
+
references => { Ref => { name => 'cars', version_range => '1.x' } }
|
287
|
+
OBJECT
|
288
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
289
|
+
/entry 'references' entry 'Ref' entry 'name' expected a match for Pattern\[\/\\A\[A-Z\]\[\\w\]\*\(\?:::\[A-Z\]\[\\w\]\*\)\*\\z\/\], got 'cars'/)
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'has a version_range that is not a valid SemVer range' do
|
293
|
+
ts = <<-OBJECT
|
294
|
+
pcore_version => '1.0.0',
|
295
|
+
version => '1.0.0',
|
296
|
+
references => { Ref => { name => 'Cars', version_range => 'X' } }
|
297
|
+
OBJECT
|
298
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(ArgumentError,
|
299
|
+
/Unparsable version range: "X"/)
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'has an alias that is not a SimpleName' do
|
303
|
+
ts = <<-OBJECT
|
304
|
+
pcore_version => '1.0.0',
|
305
|
+
version => '1.0.0',
|
306
|
+
references => { 'cars' => { name => 'X', version_range => '1.x' } }
|
307
|
+
OBJECT
|
308
|
+
expect { parse_type_set('MySet', ts) }.to raise_error(TypeAssertionError,
|
309
|
+
/entry 'references' key of entry 'cars' expected a match for Pattern\[\/\\A\[A-Z\]\\w\*\\z\/\], got 'cars'/)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'when declaring types' do
|
317
|
+
it 'can declare a type Alias' do
|
318
|
+
expect { parse_type_set('TheSet', <<-OBJECT) }.not_to raise_error
|
319
|
+
version => '1.0.0',
|
320
|
+
pcore_version => '1.0.0',
|
321
|
+
types => { PositiveInt => Integer[0, default] }
|
322
|
+
OBJECT
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'can declare a type and Object type' do
|
326
|
+
expect { parse_type_set('TheSet', <<-OBJECT) }.not_to raise_error
|
327
|
+
version => '1.0.0',
|
328
|
+
pcore_version => '1.0.0',
|
329
|
+
types => { Complex => Object[{}] }
|
330
|
+
OBJECT
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'can declare an Object type that references other types in the same set' do
|
334
|
+
expect { parse_type_set('TheSet', <<-OBJECT) }.not_to raise_error
|
335
|
+
version => '1.0.0',
|
336
|
+
pcore_version => '1.0.0',
|
337
|
+
types => {
|
338
|
+
Real => Float,
|
339
|
+
Complex => Object[{
|
340
|
+
attributes => {
|
341
|
+
real => Real,
|
342
|
+
imaginary => Real
|
343
|
+
}
|
344
|
+
}]
|
345
|
+
}
|
346
|
+
OBJECT
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'can declare an alias that references itself' do
|
350
|
+
expect { parse_type_set('TheSet', <<-OBJECT) }.not_to raise_error
|
351
|
+
version => '1.0.0',
|
352
|
+
pcore_version => '1.0.0',
|
353
|
+
types => {
|
354
|
+
Tree => Hash[String,Variant[String,Tree]]
|
355
|
+
}
|
356
|
+
OBJECT
|
357
|
+
end
|
358
|
+
|
359
|
+
it 'can declare a type that references types in another type set' do
|
360
|
+
parse_type_set('Vehicles', <<-OBJECT)
|
361
|
+
version => '1.0.0',
|
362
|
+
pcore_version => '1.0.0',
|
363
|
+
types => {
|
364
|
+
Car => Object[{}],
|
365
|
+
Bicycle => Object[{}]
|
366
|
+
}
|
367
|
+
OBJECT
|
368
|
+
expect { parse_type_set('TheSet', <<-OBJECT) }.not_to raise_error
|
369
|
+
version => '1.0.0',
|
370
|
+
pcore_version => '1.0.0',
|
371
|
+
types => {
|
372
|
+
Transports => Variant[Vecs::Car,Vecs::Bicycle]
|
373
|
+
},
|
374
|
+
references => {
|
375
|
+
Vecs => {
|
376
|
+
name => 'Vehicles',
|
377
|
+
version_range => '1.x'
|
378
|
+
}
|
379
|
+
}
|
380
|
+
OBJECT
|
381
|
+
end
|
382
|
+
|
383
|
+
it 'can declare a type that references types in a type set referenced by another type set' do
|
384
|
+
parse_type_set('Vehicles', <<-OBJECT)
|
385
|
+
version => '1.0.0',
|
386
|
+
pcore_version => '1.0.0',
|
387
|
+
types => {
|
388
|
+
Car => Object[{}],
|
389
|
+
Bicycle => Object[{}]
|
390
|
+
}
|
391
|
+
OBJECT
|
392
|
+
parse_type_set('Transports', <<-OBJECT)
|
393
|
+
version => '1.0.0',
|
394
|
+
pcore_version => '1.0.0',
|
395
|
+
types => {
|
396
|
+
Transports => Variant[Vecs::Car,Vecs::Bicycle]
|
397
|
+
},
|
398
|
+
references => {
|
399
|
+
Vecs => {
|
400
|
+
name => 'Vehicles',
|
401
|
+
version_range => '1.x'
|
402
|
+
}
|
403
|
+
}
|
404
|
+
OBJECT
|
405
|
+
expect { parse_type_set('TheSet', <<-OBJECT) }.not_to raise_error
|
406
|
+
version => '1.0.0',
|
407
|
+
pcore_version => '1.0.0',
|
408
|
+
types => {
|
409
|
+
MotorPowered => Variant[T::Vecs::Car],
|
410
|
+
Pedaled => Variant[T::Vecs::Bicycle],
|
411
|
+
All => T::Transports
|
412
|
+
},
|
413
|
+
references => {
|
414
|
+
T => {
|
415
|
+
name => 'Transports',
|
416
|
+
version_range => '1.x'
|
417
|
+
}
|
418
|
+
}
|
419
|
+
OBJECT
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
@@ -12,247 +12,563 @@ module Types
|
|
12
12
|
describe 'Puppet Ruby Generator' do
|
13
13
|
include PuppetSpec::Compiler
|
14
14
|
|
15
|
-
|
16
|
-
<<-CODE
|
17
|
-
type MyModule::FirstGenerated = Object[{
|
18
|
-
attributes => {
|
19
|
-
name => String,
|
20
|
-
age => { type => Integer, value => 30 },
|
21
|
-
what => { type => String, value => 'what is this', kind => constant }
|
22
|
-
}
|
23
|
-
}]
|
24
|
-
type MyModule::SecondGenerated = Object[{
|
25
|
-
parent => MyModule::FirstGenerated,
|
26
|
-
attributes => {
|
27
|
-
address => String,
|
28
|
-
zipcode => String,
|
29
|
-
email => String,
|
30
|
-
another => { type => Optional[MyModule::FirstGenerated], value => undef },
|
31
|
-
number => Integer
|
32
|
-
}
|
33
|
-
}]
|
34
|
-
CODE
|
35
|
-
end
|
36
|
-
|
37
|
-
let!(:parser) { TypeParser.new }
|
15
|
+
let!(:parser) { TypeParser.singleton }
|
38
16
|
let(:generator) { RubyGenerator.new }
|
39
17
|
|
40
|
-
context 'when generating
|
18
|
+
context 'when generating from Object types' do
|
19
|
+
def source
|
20
|
+
<<-CODE
|
21
|
+
type MyModule::FirstGenerated = Object[{
|
22
|
+
attributes => {
|
23
|
+
name => String,
|
24
|
+
age => { type => Integer, value => 30 },
|
25
|
+
what => { type => String, value => 'what is this', kind => constant }
|
26
|
+
}
|
27
|
+
}]
|
28
|
+
type MyModule::SecondGenerated = Object[{
|
29
|
+
parent => MyModule::FirstGenerated,
|
30
|
+
attributes => {
|
31
|
+
address => String,
|
32
|
+
zipcode => String,
|
33
|
+
email => String,
|
34
|
+
another => { type => Optional[MyModule::FirstGenerated], value => undef },
|
35
|
+
number => Integer
|
36
|
+
}
|
37
|
+
}]
|
38
|
+
CODE
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when generating anonymous classes' do
|
41
42
|
|
42
|
-
|
43
|
+
scope = nil
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
let(:first_type) { parser.parse('MyModule::FirstGenerated', scope) }
|
46
|
+
let(:second_type) { parser.parse('MyModule::SecondGenerated', scope) }
|
47
|
+
let(:first) { generator.create_class(first_type) }
|
48
|
+
let(:second) { generator.create_class(second_type) }
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
before(:each) do
|
51
|
+
eval_and_collect_notices(source) do |topscope, catalog|
|
52
|
+
scope = topscope
|
53
|
+
end
|
52
54
|
end
|
53
|
-
end
|
54
55
|
|
55
|
-
|
56
|
+
after(:each) { typeset = nil }
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
context 'the generated class' do
|
59
|
+
it 'inherits the PuppetObject module' do
|
60
|
+
expect(first < PuppetObject).to be_truthy
|
61
|
+
end
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
it 'is the superclass of a generated subclass' do
|
64
|
+
expect(second < first).to be_truthy
|
65
|
+
end
|
64
66
|
end
|
65
|
-
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
context 'the #create class method' do
|
69
|
+
it 'has an arity that reflects optional arguments' do
|
70
|
+
expect(first.method(:create).arity).to eql(-2)
|
71
|
+
expect(second.method(:create).arity).to eql(-6)
|
72
|
+
end
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
it 'creates an instance of the class' do
|
75
|
+
inst = first.create('Bob Builder', 52)
|
76
|
+
expect(inst).to be_a(first)
|
77
|
+
expect(inst.name).to eq('Bob Builder')
|
78
|
+
expect(inst.age).to eq(52)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'will perform type assertion of the arguments' do
|
82
|
+
expect { first.create('Bob Builder', '52') }.to(
|
83
|
+
raise_error(TypeAssertionError,
|
84
|
+
'MyModule::FirstGenerated[age] had wrong type, expected an Integer value, got String')
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'will not accept nil as given value for an optional parameter that does not accept nil' do
|
89
|
+
expect { first.create('Bob Builder', nil) }.to(
|
90
|
+
raise_error(TypeAssertionError,
|
91
|
+
'MyModule::FirstGenerated[age] had wrong type, expected an Integer value, got Undef')
|
92
|
+
)
|
93
|
+
end
|
79
94
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
95
|
+
it 'reorders parameters to but the optional parameters last' do
|
96
|
+
inst = second.create('Bob Builder', '42 Cool Street', '12345', 'bob@example.com', 23)
|
97
|
+
expect(inst.name).to eq('Bob Builder')
|
98
|
+
expect(inst.address).to eq('42 Cool Street')
|
99
|
+
expect(inst.zipcode).to eq('12345')
|
100
|
+
expect(inst.email).to eq('bob@example.com')
|
101
|
+
expect(inst.number).to eq(23)
|
102
|
+
expect(inst.what).to eql('what is this')
|
103
|
+
expect(inst.age).to eql(30)
|
104
|
+
expect(inst.another).to be_nil
|
105
|
+
end
|
85
106
|
end
|
86
107
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
108
|
+
context 'the #from_hash class method' do
|
109
|
+
it 'has an arity of one' do
|
110
|
+
expect(first.method(:from_hash).arity).to eql(1)
|
111
|
+
expect(second.method(:from_hash).arity).to eql(1)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'creates an instance of the class' do
|
115
|
+
inst = first.from_hash('name' => 'Bob Builder', 'age' => 52)
|
116
|
+
expect(inst).to be_a(first)
|
117
|
+
expect(inst.name).to eq('Bob Builder')
|
118
|
+
expect(inst.age).to eq(52)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'accepts an initializer where optional keys are missing' do
|
122
|
+
inst = first.from_hash('name' => 'Bob Builder')
|
123
|
+
expect(inst).to be_a(first)
|
124
|
+
expect(inst.name).to eq('Bob Builder')
|
125
|
+
expect(inst.age).to eq(30)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'does not accept an initializer where optional values are nil and type does not accept nil' do
|
129
|
+
expect { first.from_hash('name' => 'Bob Builder', 'age' => nil) }.to(
|
130
|
+
raise_error(TypeAssertionError,
|
131
|
+
"MyModule::FirstGenerated initializer had wrong type, entry 'age' expected an Integer value, got Undef")
|
132
|
+
)
|
133
|
+
end
|
92
134
|
end
|
93
135
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
expect(inst.zipcode).to eq('12345')
|
99
|
-
expect(inst.email).to eq('bob@example.com')
|
100
|
-
expect(inst.number).to eq(23)
|
101
|
-
expect(inst.what).to eql('what is this')
|
102
|
-
expect(inst.age).to eql(30)
|
103
|
-
expect(inst.another).to be_nil
|
136
|
+
context 'creates an instance' do
|
137
|
+
it 'that the TypeCalculator infers to the Object type' do
|
138
|
+
expect(TypeCalculator.infer(first.from_hash('name' => 'Bob Builder'))).to eq(first_type)
|
139
|
+
end
|
104
140
|
end
|
105
141
|
end
|
106
142
|
|
107
|
-
context '
|
108
|
-
|
109
|
-
|
110
|
-
|
143
|
+
context 'when generating static code' do
|
144
|
+
module_def = nil
|
145
|
+
|
146
|
+
before(:each) do
|
147
|
+
# Ideally, this would be in a before(:all) but that is impossible since lots of Puppet
|
148
|
+
# environment specific settings are configured by the spec_helper in before(:each)
|
149
|
+
if module_def.nil?
|
150
|
+
first_type = nil
|
151
|
+
second_type = nil
|
152
|
+
eval_and_collect_notices(source) do |scope, catalog|
|
153
|
+
first_type = parser.parse('MyModule::FirstGenerated', scope)
|
154
|
+
second_type = parser.parse('MyModule::SecondGenerated', scope)
|
155
|
+
|
156
|
+
loader = Loaders.find_loader(nil)
|
157
|
+
Loaders.implementation_registry.register_type_mapping(
|
158
|
+
PRuntimeType.new(:ruby, [/^PuppetSpec::RubyGenerator::(\w+)$/, 'MyModule::\1']),
|
159
|
+
[/^MyModule::(\w+)$/, 'PuppetSpec::RubyGenerator::\1'], loader)
|
160
|
+
|
161
|
+
module_def = generator.module_definition([first_type, second_type], 'Generated stuff')
|
162
|
+
end
|
163
|
+
Loaders.clear
|
164
|
+
Puppet[:code] = nil
|
165
|
+
|
166
|
+
# Create the actual classes in the PuppetSpec::RubyGenerator module
|
167
|
+
Puppet.override(:loaders => Puppet::Pops::Loaders.new(Puppet::Node::Environment.create(:testing, []))) do
|
168
|
+
eval(module_def, root_binding)
|
169
|
+
end
|
170
|
+
end
|
111
171
|
end
|
112
172
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
expect(inst.name).to eq('Bob Builder')
|
117
|
-
expect(inst.age).to eq(52)
|
173
|
+
after(:all) do
|
174
|
+
# Don't want generated module to leak outside this test
|
175
|
+
PuppetSpec.send(:remove_const, :RubyGenerator)
|
118
176
|
end
|
119
177
|
|
120
|
-
it '
|
121
|
-
|
122
|
-
expect(
|
123
|
-
|
124
|
-
expect(
|
178
|
+
it 'the #_ptype class method returns a resolved Type' do
|
179
|
+
first_type = PuppetSpec::RubyGenerator::FirstGenerated._ptype
|
180
|
+
expect(first_type).to be_a(PObjectType)
|
181
|
+
second_type = PuppetSpec::RubyGenerator::SecondGenerated._ptype
|
182
|
+
expect(second_type).to be_a(PObjectType)
|
183
|
+
expect(second_type.parent).to eql(first_type)
|
125
184
|
end
|
126
185
|
|
127
|
-
it '
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
)
|
186
|
+
it 'the #_plocation class method returns a file URI' do
|
187
|
+
loc = PuppetSpec::RubyGenerator::SecondGenerated._plocation
|
188
|
+
expect(loc).to be_a(URI)
|
189
|
+
expect(loc.to_s).to match(/^file:\/.*ruby_generator_spec.rb\?line=\d+$/)
|
132
190
|
end
|
133
|
-
end
|
134
191
|
|
135
|
-
|
136
|
-
|
137
|
-
|
192
|
+
context 'the #create class method' do
|
193
|
+
it 'has an arity that reflects optional arguments' do
|
194
|
+
expect(PuppetSpec::RubyGenerator::FirstGenerated.method(:create).arity).to eql(-2)
|
195
|
+
expect(PuppetSpec::RubyGenerator::SecondGenerated.method(:create).arity).to eql(-6)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'creates an instance of the class' do
|
199
|
+
inst = PuppetSpec::RubyGenerator::FirstGenerated.create('Bob Builder', 52)
|
200
|
+
expect(inst).to be_a(PuppetSpec::RubyGenerator::FirstGenerated)
|
201
|
+
expect(inst.name).to eq('Bob Builder')
|
202
|
+
expect(inst.age).to eq(52)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'will perform type assertion of the arguments' do
|
206
|
+
expect { PuppetSpec::RubyGenerator::FirstGenerated.create('Bob Builder', '52') }.to(
|
207
|
+
raise_error(TypeAssertionError,
|
208
|
+
'MyModule::FirstGenerated[age] had wrong type, expected an Integer value, got String')
|
209
|
+
)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'will not accept nil as given value for an optional parameter that does not accept nil' do
|
213
|
+
expect { PuppetSpec::RubyGenerator::FirstGenerated.create('Bob Builder', nil) }.to(
|
214
|
+
raise_error(TypeAssertionError,
|
215
|
+
'MyModule::FirstGenerated[age] had wrong type, expected an Integer value, got Undef')
|
216
|
+
)
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'reorders parameters to but the optional parameters last' do
|
220
|
+
inst = PuppetSpec::RubyGenerator::SecondGenerated.create('Bob Builder', '42 Cool Street', '12345', 'bob@example.com', 23)
|
221
|
+
expect(inst.name).to eq('Bob Builder')
|
222
|
+
expect(inst.address).to eq('42 Cool Street')
|
223
|
+
expect(inst.zipcode).to eq('12345')
|
224
|
+
expect(inst.email).to eq('bob@example.com')
|
225
|
+
expect(inst.number).to eq(23)
|
226
|
+
expect(inst.what).to eql('what is this')
|
227
|
+
expect(inst.age).to eql(30)
|
228
|
+
expect(inst.another).to be_nil
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'the #from_hash class method' do
|
233
|
+
it 'has an arity of one' do
|
234
|
+
expect(PuppetSpec::RubyGenerator::FirstGenerated.method(:from_hash).arity).to eql(1)
|
235
|
+
expect(PuppetSpec::RubyGenerator::SecondGenerated.method(:from_hash).arity).to eql(1)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'creates an instance of the class' do
|
239
|
+
inst = PuppetSpec::RubyGenerator::FirstGenerated.from_hash('name' => 'Bob Builder', 'age' => 52)
|
240
|
+
expect(inst).to be_a(PuppetSpec::RubyGenerator::FirstGenerated)
|
241
|
+
expect(inst.name).to eq('Bob Builder')
|
242
|
+
expect(inst.age).to eq(52)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'accepts an initializer where optional keys are missing' do
|
246
|
+
inst = PuppetSpec::RubyGenerator::FirstGenerated.from_hash('name' => 'Bob Builder')
|
247
|
+
expect(inst).to be_a(PuppetSpec::RubyGenerator::FirstGenerated)
|
248
|
+
expect(inst.name).to eq('Bob Builder')
|
249
|
+
expect(inst.age).to eq(30)
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'does not accept an initializer where optional values are nil and type does not accept nil' do
|
253
|
+
expect { PuppetSpec::RubyGenerator::FirstGenerated.from_hash('name' => 'Bob Builder', 'age' => nil) }.to(
|
254
|
+
raise_error(TypeAssertionError,
|
255
|
+
"MyModule::FirstGenerated initializer had wrong type, entry 'age' expected an Integer value, got Undef")
|
256
|
+
)
|
257
|
+
end
|
138
258
|
end
|
139
259
|
end
|
140
260
|
end
|
141
261
|
|
142
|
-
context 'when generating
|
143
|
-
|
262
|
+
context 'when generating from TypeSets' do
|
263
|
+
def source
|
264
|
+
<<-CODE
|
265
|
+
type MyModule = TypeSet[{
|
266
|
+
pcore_version => '1.0.0',
|
267
|
+
version => '1.0.0',
|
268
|
+
types => {
|
269
|
+
MyInteger => Integer,
|
270
|
+
FirstGenerated => Object[{
|
271
|
+
attributes => {
|
272
|
+
name => String,
|
273
|
+
age => { type => Integer, value => 30 },
|
274
|
+
what => { type => String, value => 'what is this', kind => constant }
|
275
|
+
}
|
276
|
+
}],
|
277
|
+
SecondGenerated => Object[{
|
278
|
+
parent => FirstGenerated,
|
279
|
+
attributes => {
|
280
|
+
address => String,
|
281
|
+
zipcode => String,
|
282
|
+
email => String,
|
283
|
+
another => { type => Optional[FirstGenerated], value => undef },
|
284
|
+
number => MyInteger
|
285
|
+
}
|
286
|
+
}]
|
287
|
+
},
|
288
|
+
}]
|
289
|
+
|
290
|
+
type OtherModule = TypeSet[{
|
291
|
+
pcore_version => '1.0.0',
|
292
|
+
version => '1.0.0',
|
293
|
+
types => {
|
294
|
+
MyFloat => Float,
|
295
|
+
ThirdGenerated => Object[{
|
296
|
+
attributes => {
|
297
|
+
first => My::FirstGenerated
|
298
|
+
}
|
299
|
+
}],
|
300
|
+
FourthGenerated => Object[{
|
301
|
+
parent => My::SecondGenerated,
|
302
|
+
attributes => {
|
303
|
+
complex => { type => Optional[ThirdGenerated], value => undef },
|
304
|
+
n1 => My::MyInteger,
|
305
|
+
n2 => MyFloat
|
306
|
+
}
|
307
|
+
}]
|
308
|
+
},
|
309
|
+
references => {
|
310
|
+
My => { name => 'MyModule', version_range => '1.x' }
|
311
|
+
}
|
312
|
+
}]
|
313
|
+
CODE
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'when generating anonymous classes' do
|
144
317
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
318
|
+
typeset = nil
|
319
|
+
|
320
|
+
let(:first_type) { typeset['My::FirstGenerated'] }
|
321
|
+
let(:second_type) { typeset['My::SecondGenerated'] }
|
322
|
+
let(:third_type) { typeset['ThirdGenerated'] }
|
323
|
+
let(:fourth_type) { typeset['FourthGenerated'] }
|
324
|
+
let(:first) { generator.create_class(first_type) }
|
325
|
+
let(:second) { generator.create_class(second_type) }
|
326
|
+
let(:third) { generator.create_class(third_type) }
|
327
|
+
let(:fourth) { generator.create_class(fourth_type) }
|
328
|
+
|
329
|
+
before(:each) do
|
151
330
|
eval_and_collect_notices(source) do |scope, catalog|
|
152
|
-
|
153
|
-
|
331
|
+
typeset = parser.parse('OtherModule', scope)
|
332
|
+
end
|
333
|
+
end
|
154
334
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
335
|
+
after(:each) { typeset = nil }
|
336
|
+
|
337
|
+
context 'the typeset' do
|
338
|
+
it 'produces expected string representation' do
|
339
|
+
typeset.to_s == "TypeSet[{"+
|
340
|
+
"pcore_version => '1.0.0', "+
|
341
|
+
"name_authority => 'http://puppet.com/2016.1/runtime', "+
|
342
|
+
"name => 'OtherModule', "+
|
343
|
+
"version => '1.0.0', "+
|
344
|
+
"types => {"+
|
345
|
+
"MyFloat => Float, "+
|
346
|
+
"ThirdGenerated => Object[{"+
|
347
|
+
"attributes => {"+
|
348
|
+
"'first' => MyModule::FirstGenerated}}], "+
|
349
|
+
"FourthGenerated => Object[{"+
|
350
|
+
"parent => MyModule::SecondGenerated, "+
|
351
|
+
"attributes => {"+
|
352
|
+
"'complex' => {"+
|
353
|
+
"type => Optional[ThirdGenerated], "+
|
354
|
+
"value => ?}, "+
|
355
|
+
"'n1' => MyModule::MyInteger, "+
|
356
|
+
"'n2' => MyFloat}}]}, "+
|
357
|
+
"references => [{"+
|
358
|
+
"'name' => 'MyModule', "+
|
359
|
+
"'alias' => 'My', "+
|
360
|
+
"'version_range' => '1.x'}]}]"
|
361
|
+
end
|
362
|
+
end
|
159
363
|
|
160
|
-
|
364
|
+
context 'the generated class' do
|
365
|
+
it 'inherits the PuppetObject module' do
|
366
|
+
expect(first < PuppetObject).to be_truthy
|
161
367
|
end
|
162
|
-
Loaders.clear
|
163
|
-
Puppet[:code] = nil
|
164
368
|
|
165
|
-
|
166
|
-
|
167
|
-
eval(module_def, root_binding)
|
369
|
+
it 'is the superclass of a generated subclass' do
|
370
|
+
expect(second < first).to be_truthy
|
168
371
|
end
|
169
372
|
end
|
170
|
-
end
|
171
373
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
374
|
+
context 'the #create class method' do
|
375
|
+
it 'has an arity that reflects optional arguments' do
|
376
|
+
expect(first.method(:create).arity).to eql(-2)
|
377
|
+
expect(second.method(:create).arity).to eql(-6)
|
378
|
+
expect(third.method(:create).arity).to eql(1)
|
379
|
+
expect(fourth.method(:create).arity).to eql(-8)
|
380
|
+
end
|
176
381
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
end
|
382
|
+
it 'creates an instance of the class' do
|
383
|
+
inst = first.create('Bob Builder', 52)
|
384
|
+
expect(inst).to be_a(first)
|
385
|
+
expect(inst.name).to eq('Bob Builder')
|
386
|
+
expect(inst.age).to eq(52)
|
387
|
+
end
|
184
388
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
389
|
+
it 'will perform type assertion of the arguments' do
|
390
|
+
expect { first.create('Bob Builder', '52') }.to(
|
391
|
+
raise_error(TypeAssertionError,
|
392
|
+
'MyModule::FirstGenerated[age] had wrong type, expected an Integer value, got String')
|
393
|
+
)
|
394
|
+
end
|
395
|
+
|
396
|
+
it 'will not accept nil as given value for an optional parameter that does not accept nil' do
|
397
|
+
expect { first.create('Bob Builder', nil) }.to(
|
398
|
+
raise_error(TypeAssertionError,
|
399
|
+
'MyModule::FirstGenerated[age] had wrong type, expected an Integer value, got Undef')
|
400
|
+
)
|
401
|
+
end
|
190
402
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
403
|
+
it 'reorders parameters to but the optional parameters last' do
|
404
|
+
inst = second.create('Bob Builder', '42 Cool Street', '12345', 'bob@example.com', 23)
|
405
|
+
expect(inst.name).to eq('Bob Builder')
|
406
|
+
expect(inst.address).to eq('42 Cool Street')
|
407
|
+
expect(inst.zipcode).to eq('12345')
|
408
|
+
expect(inst.email).to eq('bob@example.com')
|
409
|
+
expect(inst.number).to eq(23)
|
410
|
+
expect(inst.what).to eql('what is this')
|
411
|
+
expect(inst.age).to eql(30)
|
412
|
+
expect(inst.another).to be_nil
|
413
|
+
end
|
195
414
|
end
|
196
415
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
416
|
+
context 'the #from_hash class method' do
|
417
|
+
it 'has an arity of one' do
|
418
|
+
expect(first.method(:from_hash).arity).to eql(1)
|
419
|
+
expect(second.method(:from_hash).arity).to eql(1)
|
420
|
+
end
|
421
|
+
|
422
|
+
it 'creates an instance of the class' do
|
423
|
+
inst = first.from_hash('name' => 'Bob Builder', 'age' => 52)
|
424
|
+
expect(inst).to be_a(first)
|
425
|
+
expect(inst.name).to eq('Bob Builder')
|
426
|
+
expect(inst.age).to eq(52)
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'accepts an initializer where optional keys are missing' do
|
430
|
+
inst = first.from_hash('name' => 'Bob Builder')
|
431
|
+
expect(inst).to be_a(first)
|
432
|
+
expect(inst.name).to eq('Bob Builder')
|
433
|
+
expect(inst.age).to eq(30)
|
434
|
+
end
|
435
|
+
|
436
|
+
it 'does not accept an initializer where optional values are nil and type does not accept nil' do
|
437
|
+
expect { first.from_hash('name' => 'Bob Builder', 'age' => nil) }.to(
|
438
|
+
raise_error(TypeAssertionError,
|
439
|
+
"MyModule::FirstGenerated initializer had wrong type, entry 'age' expected an Integer value, got Undef")
|
440
|
+
)
|
441
|
+
end
|
202
442
|
end
|
203
443
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
)
|
444
|
+
context 'creates an instance' do
|
445
|
+
it 'that the TypeCalculator infers to the Object type' do
|
446
|
+
expect(TypeCalculator.infer(first.from_hash('name' => 'Bob Builder'))).to eq(first_type)
|
447
|
+
end
|
209
448
|
end
|
449
|
+
end
|
210
450
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
451
|
+
context 'when generating static code' do
|
452
|
+
module_def = nil
|
453
|
+
module_def2 = nil
|
454
|
+
|
455
|
+
before(:each) do
|
456
|
+
# Ideally, this would be in a before(:all) but that is impossible since lots of Puppet
|
457
|
+
# environment specific settings are configured by the spec_helper in before(:each)
|
458
|
+
if module_def.nil?
|
459
|
+
typeset = nil
|
460
|
+
eval_and_collect_notices(source) do |scope, catalog|
|
461
|
+
typeset1 = parser.parse('MyModule', scope)
|
462
|
+
typeset2 = parser.parse('OtherModule', scope)
|
463
|
+
|
464
|
+
loader = Loaders.find_loader(nil)
|
465
|
+
Loaders.implementation_registry.register_type_mapping(
|
466
|
+
PRuntimeType.new(:ruby, [/^PuppetSpec::RubyGenerator::My::(\w+)$/, 'MyModule::\1']),
|
467
|
+
[/^MyModule::(\w+)$/, 'PuppetSpec::RubyGenerator::My::\1'], loader)
|
468
|
+
|
469
|
+
Loaders.implementation_registry.register_type_mapping(
|
470
|
+
PRuntimeType.new(:ruby, [/^PuppetSpec::RubyGenerator::Other::(\w+)$/, 'OtherModule::\1']),
|
471
|
+
[/^OtherModule::(\w+)$/, 'PuppetSpec::RubyGenerator::Other::\1'], loader)
|
472
|
+
|
473
|
+
module_def = generator.module_definition_from_typeset(typeset1)
|
474
|
+
module_def2 = generator.module_definition_from_typeset(typeset2)
|
475
|
+
end
|
476
|
+
Loaders.clear
|
477
|
+
Puppet[:code] = nil
|
478
|
+
|
479
|
+
# Create the actual classes in the PuppetSpec::RubyGenerator module
|
480
|
+
Puppet.override(:loaders => Puppet::Pops::Loaders.new(Puppet::Node::Environment.create(:testing, []))) do
|
481
|
+
eval(module_def, root_binding)
|
482
|
+
eval(module_def2, root_binding)
|
483
|
+
end
|
484
|
+
end
|
216
485
|
end
|
217
486
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
expect(inst.address).to eq('42 Cool Street')
|
222
|
-
expect(inst.zipcode).to eq('12345')
|
223
|
-
expect(inst.email).to eq('bob@example.com')
|
224
|
-
expect(inst.number).to eq(23)
|
225
|
-
expect(inst.what).to eql('what is this')
|
226
|
-
expect(inst.age).to eql(30)
|
227
|
-
expect(inst.another).to be_nil
|
487
|
+
after(:all) do
|
488
|
+
# Don't want generated module to leak outside this test
|
489
|
+
PuppetSpec.send(:remove_const, :RubyGenerator)
|
228
490
|
end
|
229
|
-
end
|
230
491
|
|
231
|
-
|
232
|
-
|
233
|
-
expect(
|
234
|
-
|
492
|
+
it 'the #_ptype class method returns a resolved Type' do
|
493
|
+
first_type = PuppetSpec::RubyGenerator::My::FirstGenerated._ptype
|
494
|
+
expect(first_type).to be_a(PObjectType)
|
495
|
+
second_type = PuppetSpec::RubyGenerator::My::SecondGenerated._ptype
|
496
|
+
expect(second_type).to be_a(PObjectType)
|
497
|
+
expect(second_type.parent).to eql(first_type)
|
235
498
|
end
|
236
499
|
|
237
|
-
it '
|
238
|
-
|
239
|
-
expect(
|
240
|
-
expect(
|
241
|
-
expect(inst.age).to eq(52)
|
500
|
+
it 'the #_plocation class method returns a file URI' do
|
501
|
+
loc = PuppetSpec::RubyGenerator::My::SecondGenerated._plocation
|
502
|
+
expect(loc).to be_a(URI)
|
503
|
+
expect(loc.to_s).to match(/^file:\/.*ruby_generator_spec.rb\?line=\d+$/)
|
242
504
|
end
|
243
505
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
506
|
+
context 'the #create class method' do
|
507
|
+
it 'has an arity that reflects optional arguments' do
|
508
|
+
expect(PuppetSpec::RubyGenerator::My::FirstGenerated.method(:create).arity).to eql(-2)
|
509
|
+
expect(PuppetSpec::RubyGenerator::My::SecondGenerated.method(:create).arity).to eql(-6)
|
510
|
+
end
|
511
|
+
|
512
|
+
it 'creates an instance of the class' do
|
513
|
+
inst = PuppetSpec::RubyGenerator::My::FirstGenerated.create('Bob Builder', 52)
|
514
|
+
expect(inst).to be_a(PuppetSpec::RubyGenerator::My::FirstGenerated)
|
515
|
+
expect(inst.name).to eq('Bob Builder')
|
516
|
+
expect(inst.age).to eq(52)
|
517
|
+
end
|
518
|
+
|
519
|
+
it 'will perform type assertion of the arguments' do
|
520
|
+
expect { PuppetSpec::RubyGenerator::My::FirstGenerated.create('Bob Builder', '52') }.to(
|
521
|
+
raise_error(TypeAssertionError,
|
522
|
+
'MyModule::FirstGenerated[age] had wrong type, expected an Integer value, got String')
|
523
|
+
)
|
524
|
+
end
|
525
|
+
|
526
|
+
it 'will not accept nil as given value for an optional parameter that does not accept nil' do
|
527
|
+
expect { PuppetSpec::RubyGenerator::My::FirstGenerated.create('Bob Builder', nil) }.to(
|
528
|
+
raise_error(TypeAssertionError,
|
529
|
+
'MyModule::FirstGenerated[age] had wrong type, expected an Integer value, got Undef')
|
530
|
+
)
|
531
|
+
end
|
532
|
+
|
533
|
+
it 'reorders parameters to but the optional parameters last' do
|
534
|
+
inst = PuppetSpec::RubyGenerator::My::SecondGenerated.create('Bob Builder', '42 Cool Street', '12345', 'bob@example.com', 23)
|
535
|
+
expect(inst.name).to eq('Bob Builder')
|
536
|
+
expect(inst.address).to eq('42 Cool Street')
|
537
|
+
expect(inst.zipcode).to eq('12345')
|
538
|
+
expect(inst.email).to eq('bob@example.com')
|
539
|
+
expect(inst.number).to eq(23)
|
540
|
+
expect(inst.what).to eql('what is this')
|
541
|
+
expect(inst.age).to eql(30)
|
542
|
+
expect(inst.another).to be_nil
|
543
|
+
end
|
249
544
|
end
|
250
545
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
546
|
+
context 'the #from_hash class method' do
|
547
|
+
it 'has an arity of one' do
|
548
|
+
expect(PuppetSpec::RubyGenerator::My::FirstGenerated.method(:from_hash).arity).to eql(1)
|
549
|
+
expect(PuppetSpec::RubyGenerator::My::SecondGenerated.method(:from_hash).arity).to eql(1)
|
550
|
+
end
|
551
|
+
|
552
|
+
it 'creates an instance of the class' do
|
553
|
+
inst = PuppetSpec::RubyGenerator::My::FirstGenerated.from_hash('name' => 'Bob Builder', 'age' => 52)
|
554
|
+
expect(inst).to be_a(PuppetSpec::RubyGenerator::My::FirstGenerated)
|
555
|
+
expect(inst.name).to eq('Bob Builder')
|
556
|
+
expect(inst.age).to eq(52)
|
557
|
+
end
|
558
|
+
|
559
|
+
it 'accepts an initializer where optional keys are missing' do
|
560
|
+
inst = PuppetSpec::RubyGenerator::My::FirstGenerated.from_hash('name' => 'Bob Builder')
|
561
|
+
expect(inst).to be_a(PuppetSpec::RubyGenerator::My::FirstGenerated)
|
562
|
+
expect(inst.name).to eq('Bob Builder')
|
563
|
+
expect(inst.age).to eq(30)
|
564
|
+
end
|
565
|
+
|
566
|
+
it 'does not accept an initializer where optional values are nil and type does not accept nil' do
|
567
|
+
expect { PuppetSpec::RubyGenerator::My::FirstGenerated.from_hash('name' => 'Bob Builder', 'age' => nil) }.to(
|
568
|
+
raise_error(TypeAssertionError,
|
569
|
+
"MyModule::FirstGenerated initializer had wrong type, entry 'age' expected an Integer value, got Undef")
|
570
|
+
)
|
571
|
+
end
|
256
572
|
end
|
257
573
|
end
|
258
574
|
end
|