# frozen_string_literal: true module Fixtury # A Fixtury::SchemaNode implementation that represents a top-level schema # or a namespace within a schema. class Schema include ::Fixtury::SchemaNode # @param name [String] the name of the schema, defaults to "" to represent # a new top-level schema. def initialize(name: "", **options) super(name: name, **options) end # Object#acts_like? adherence. def acts_like_fixtury_schema? true end # Open up self for child definitions. # @param block [Proc] The block to be executed in the context of the schema. # @return [Fixtury::Schema] self def define(&block) instance_eval(&block) self end # Returns "schema" if top-level, otherwise returns "namespace". # @return [String] the type of the schema node. def schema_node_type first_ancestor? ? "schema" : "namespace" end # Create a child schema at the given relative name. If a child by the name # already exists it will be reopened as long as it's a fixtury schema. # # @param relative_name [String] The relative name of the child schema. # @param options [Hash] Additional options for the child schema, applied after instantiation. # @param block [Proc] A block of code to be executed in the context of the child schema. # @return [Fixtury::Schema] The child schema. # @raise [Fixtury::Errors::AlreadyDefinedError] if the child is already defined and not a fixtury schema. def namespace(relative_name, **options, &block) child = get("./#{relative_name}") if child && !child.acts_like?(:fixtury_schema) raise Errors::AlreadyDefinedError, child.pathname end child ||= self.class.new(name: relative_name, parent: self) child.apply_options!(options) child.instance_eval(&block) if block_given? child end # Create a fixture definition at the given relative name. If the name is already # used, a Fixtury::Errors::AlreadyDefinedError will be raised. # # @param relative_name [String] The relative name of the fixture. # @param options [Hash] Additional options for the fixture. # @param block [Proc] The block representing the build function of the fixture. # @return [Fixtury::Definition] The fixture definition. # def fixture(relative_name, **options, &block) ::Fixtury::Definition.new( name: relative_name, parent: self, **options, &block ) end end end