Skip to content

Commit

Permalink
Move contracts support into module
Browse files Browse the repository at this point in the history
  • Loading branch information
denisdefreyne committed Jun 18, 2016
1 parent 27b0456 commit 2d134ba
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 75 deletions.
1 change: 1 addition & 0 deletions lib/nanoc/base.rb
Expand Up @@ -22,6 +22,7 @@ module Nanoc::Int
end

require_relative 'base/core_ext'
require_relative 'base/contracts_support'

require_relative 'base/entities'
require_relative 'base/repos'
Expand Down
17 changes: 17 additions & 0 deletions lib/nanoc/base/contracts_support.rb
@@ -0,0 +1,17 @@
module Nanoc::Int
# @api private
module ContractsSupport
def self.included(base)
return if base.include?(::Contracts::Core)

base.include(::Contracts::Core)
base.extend(self)
base.const_set('C', ::Contracts)
end

def contract(*args)
# TODO: conditionally enable for testing only (or CONTRACTS=true)
Contract(*args)
end
end
end
8 changes: 3 additions & 5 deletions lib/nanoc/base/entities/code_snippet.rb
Expand Up @@ -3,9 +3,7 @@ module Nanoc::Int
#
# @api private
class CodeSnippet
include Contracts::Core

C = Contracts
include Nanoc::Int::ContractsSupport

# A string containing the actual code in this code snippet.
#
Expand All @@ -17,7 +15,7 @@ class CodeSnippet
# @return [String]
attr_reader :filename

Contract String, String => C::Any
contract String, String => C::Any
# Creates a new code snippet.
#
# @param [String] data The raw source code which will be executed before
Expand All @@ -29,7 +27,7 @@ def initialize(data, filename)
@filename = filename
end

Contract C::None => nil
contract C::None => nil
# Loads the code by executing it.
#
# @return [void]
Expand Down
28 changes: 13 additions & 15 deletions lib/nanoc/base/entities/configuration.rb
Expand Up @@ -3,9 +3,7 @@ module Nanoc::Int
#
# @api private
class Configuration
include Contracts::Core

C = Contracts
include Nanoc::Int::ContractsSupport

NONE = Object.new.freeze

Expand Down Expand Up @@ -35,15 +33,15 @@ class Configuration
string_pattern_type: 'glob',
}.freeze

Contract Hash => C::Any
contract Hash => C::Any
# Creates a new configuration with the given hash.
#
# @param [Hash] hash The actual configuration hash
def initialize(hash = {})
@wrapped = hash.__nanoc_symbolize_keys_recursively
end

Contract C::None => self
contract C::None => self
def with_defaults
new_wrapped = DEFAULT_CONFIG.merge(@wrapped)
new_wrapped[:data_sources] = new_wrapped[:data_sources].map do |ds|
Expand All @@ -53,22 +51,22 @@ def with_defaults
self.class.new(new_wrapped)
end

Contract C::None => Hash
contract C::None => Hash
def to_h
@wrapped
end

Contract C::Any => C::Bool
contract C::Any => C::Bool
def key?(key)
@wrapped.key?(key)
end

Contract C::Any => C::Any
contract C::Any => C::Any
def [](key)
@wrapped[key]
end

Contract C::Any, C::Maybe[C::Any], C::Maybe[C::Func[C::None => C::Any]] => C::Any
contract C::Any, C::Maybe[C::Any], C::Maybe[C::Func[C::None => C::Any]] => C::Any
def fetch(key, fallback = NONE, &_block)
@wrapped.fetch(key) do
if !fallback.equal?(NONE)
Expand All @@ -81,34 +79,34 @@ def fetch(key, fallback = NONE, &_block)
end
end

Contract C::Any, C::Any => C::Any
contract C::Any, C::Any => C::Any
def []=(key, value)
@wrapped[key] = value
end

Contract C::Or[Hash, self] => self
contract C::Or[Hash, self] => self
def merge(hash)
self.class.new(@wrapped.merge(hash.to_h))
end

Contract C::Any => self
contract C::Any => self
def without(key)
self.class.new(@wrapped.reject { |k, _v| k == key })
end

Contract C::Any => self
contract C::Any => self
def update(hash)
@wrapped.update(hash)
self
end

Contract C::Func[C::Any, C::Any => C::Any] => self
contract C::Func[C::Any, C::Any => C::Any] => self
def each
@wrapped.each { |k, v| yield(k, v) }
self
end

Contract C::None => self
contract C::None => self
def freeze
super
@wrapped.__nanoc_freeze_recursively
Expand Down
20 changes: 9 additions & 11 deletions lib/nanoc/base/entities/content.rb
Expand Up @@ -10,14 +10,12 @@ module Int
#
# @api private
class Content
include Contracts::Core

C = Contracts
include Nanoc::Int::ContractsSupport

# @return [String, nil]
attr_reader :filename

Contract C::Maybe[String] => C::Any
contract C::Maybe[String] => C::Any
# @param [String, nil] filename
def initialize(filename)
if filename && Pathname.new(filename).relative?
Expand All @@ -27,14 +25,14 @@ def initialize(filename)
@filename = filename
end

Contract C::None => self
contract C::None => self
def freeze
super
@filename.freeze
self
end

Contract C::Or[Nanoc::Int::Content, String, Proc], C::KeywordArgs[binary: C::Optional[C::Bool], filename: C::Optional[C::Maybe[String]]] => self
contract C::Or[Nanoc::Int::Content, String, Proc], C::KeywordArgs[binary: C::Optional[C::Bool], filename: C::Optional[C::Maybe[String]]] => self
# @param [Nanoc::Int::Content, String, Proc] content The uncompiled item
# content (if it is textual content) or the path to the filename
# containing the content (if this is binary content).
Expand Down Expand Up @@ -65,26 +63,26 @@ def binary?

# @api private
class TextualContent < Content
Contract C::None => String
contract C::None => String
# @return [String]
def string
@string.value
end

Contract C::Or[String, Proc], C::KeywordArgs[filename: C::Optional[C::Maybe[String]]] => C::Any
contract C::Or[String, Proc], C::KeywordArgs[filename: C::Optional[C::Maybe[String]]] => C::Any
def initialize(string, filename: nil)
super(filename)
@string = Nanoc::Int::LazyValue.new(string)
end

Contract C::None => self
contract C::None => self
def freeze
super
@string.freeze
self
end

Contract C::None => C::Bool
contract C::None => C::Bool
def binary?
false
end
Expand All @@ -103,7 +101,7 @@ def marshal_load(array)

# @api private
class BinaryContent < Content
Contract C::None => C::Bool
contract C::None => C::Bool
def binary?
true
end
Expand Down
24 changes: 11 additions & 13 deletions lib/nanoc/base/entities/document.rb
Expand Up @@ -2,9 +2,7 @@ module Nanoc
module Int
# @api private
class Document
include Contracts::Core

C = Contracts
include Nanoc::Int::ContractsSupport

# @return [Nanoc::Int::Content]
attr_reader :content
Expand All @@ -20,12 +18,12 @@ def attributes
# @return [String, nil]
attr_accessor :checksum_data

CContent = C::Or[String, Nanoc::Int::Content]
CAttributes = C::Or[Hash, Proc]
CIdentifier = C::Or[String, Nanoc::Identifier]
CChecksumData = C::Optional[C::Maybe[String]]
cContent = C::Or[String, Nanoc::Int::Content]
cAttributes = C::Or[Hash, Proc]
cIdentifier = C::Or[String, Nanoc::Identifier]
cChecksumData = C::Optional[C::Maybe[String]]

Contract CContent, CAttributes, CIdentifier, C::KeywordArgs[checksum_data: CChecksumData] => C::Any
contract cContent, cAttributes, cIdentifier, C::KeywordArgs[checksum_data: cChecksumData] => C::Any
# @param [String, Nanoc::Int::Content] content
#
# @param [Hash, Proc] attributes
Expand All @@ -40,7 +38,7 @@ def initialize(content, attributes, identifier, checksum_data: nil)
@checksum_data = checksum_data
end

Contract C::None => self
contract C::None => self
# @return [void]
def freeze
super
Expand All @@ -49,25 +47,25 @@ def freeze
self
end

Contract C::None => String
contract C::None => String
# @abstract
#
# @return Unique reference to this object
def reference
raise NotImplementedError
end

Contract C::None => String
contract C::None => String
def inspect
"<#{self.class} identifier=\"#{identifier}\">"
end

Contract C::None => C::Num
contract C::None => C::Num
def hash
self.class.hash ^ identifier.hash
end

Contract C::Any => C::Bool
contract C::Any => C::Bool
def ==(other)
other.respond_to?(:identifier) && identifier == other.identifier
end
Expand Down
16 changes: 7 additions & 9 deletions lib/nanoc/base/entities/identifiable_collection.rb
@@ -1,35 +1,33 @@
module Nanoc::Int
# @api private
class IdentifiableCollection
include Contracts::Core
include Nanoc::Int::ContractsSupport
include Enumerable

extend Forwardable

C = Contracts

def_delegator :@objects, :each
def_delegator :@objects, :size
def_delegator :@objects, :<<
def_delegator :@objects, :concat

# FIXME: use Nanoc::Int::Configuration
Contract C::Any => C::Any
contract C::Any => C::Any
def initialize(config)
@config = config

@objects = []
end

Contract C::None => self
contract C::None => self
def freeze
@objects.freeze
@objects.each(&:freeze)
build_mapping
super
end

Contract C::Any => C::Maybe[C::RespondTo[:identifier]]
contract C::Any => C::Maybe[C::RespondTo[:identifier]]
def [](arg)
case arg
when Nanoc::Identifier
Expand All @@ -43,17 +41,17 @@ def [](arg)
end
end

Contract C::None => C::ArrayOf[C::RespondTo[:identifier]]
contract C::None => C::ArrayOf[C::RespondTo[:identifier]]
def to_a
@objects
end

Contract C::None => C::Bool
contract C::None => C::Bool
def empty?
@objects.empty?
end

Contract C::Func[C::RespondTo[:identifier] => C::Bool] => self
contract C::Func[C::RespondTo[:identifier] => C::Bool] => self
def delete_if(&block)
@objects.delete_if(&block)
self
Expand Down

0 comments on commit 2d134ba

Please sign in to comment.