working on the content entry filesystem repository (WIP), broken specs (tha's bad I know)

did committed Feb 13, 2015
commit a5c798c67ad54c6ffe2f0f168e81a1ede975569f
Showing 22 changed files with 583 additions and 40 deletions
Gemfile.lock +2 -0
@@ @@ -4,6 +4,7 @@ PATH
locomotivecms_steam (0.2.0.pre.beta)
RedCloth (~> 4.2.9)
activesupport (~> 4.2.0)
+ chronic (~> 0.10.2)
coffee-script (~> 2.3.0)
compass (~> 1.0.3)
dragonfly (~> 1.0.7)
@@ @@ -52,6 +53,7 @@ GEM
columnize (~> 0.8)
debugger-linecache (~> 1.2)
slop (~> 3.6)
+ chronic (0.10.2)
chunky_png (1.3.3)
codeclimate-test-reporter (0.4.6)
simplecov (>= 0.7.1, < 1.0.0)
locomotive/steam.rb b/lib/locomotive/steam.rb +2 -0
@@ @@ -16,6 +16,8 @@ require_relative 'steam/repositories'
require_relative 'steam/services'
# TODO: move into a file named dependencies
+
+ # TODO: move them to a different place
require 'haml'
require 'compass'
require 'mimetype_fu'
locomotive/steam/liquid/drops/content_entry.rb b/lib/locomotive/steam/liquid/drops/content_entry.rb +12 -10
@@ @@ -50,14 +50,16 @@ module Locomotive
return '' if @_source.nil?
if not @@forbidden_attributes.include?(meth.to_s)
- value = @_source.send(meth)
+ repository.value_for(meth, @_source, @context['with_scope'])
- # check for an association (lazy loading)
- if value.respond_to?(:all)
- filter_association(value)
- else
- value
- end
+ # value = @_source.send(meth)
+
+ # # check for an association (lazy loading)
+ # if value.respond_to?(:all)
+ # filter_association(value)
+ # else
+ # value
+ # end
else
nil
end
@@ @@ -69,9 +71,9 @@ module Locomotive
@context.registers[:services].repositories.content_entry
end
- def filter_association(association)
- repository.filter(association, @context['with_scope'] || {})
- end
+ # def fetch_association(name)
+ # repository.association(name, @_source, @context['with_scope'] || {})
+ # end
end
end
locomotive/steam/repositories/filesystem.rb b/lib/locomotive/steam/repositories/filesystem.rb +3 -1
@@ @@ -39,7 +39,9 @@ module Locomotive
end
register :content_entry do
- Filesystem::ContentEntry.new(current_site)
+ Filesystem::ContentEntry.new(
+ YAMLLoaders::ContentEntry.new(options[:path], cache),
+ current_site, current_locale)
end
register :theme_asset do
locomotive/steam/repositories/filesystem/concerns/queryable.rb b/lib/locomotive/steam/repositories/filesystem/concerns/queryable.rb +18 -9
@@ @@ -8,25 +8,34 @@ module Locomotive
extend ActiveSupport::Concern
- def query(&block)
+ def query(*args, &block)
_locale = respond_to?(:current_locale) ? current_locale : nil
- MemoryAdapter::Query.new(collection, _locale, &block)
+ MemoryAdapter::Query.new(memoized_collection(*args), _locale, &block)
end
private
- def collection
+ def memoized_collection(*args)
return @collection if @collection
- @collection = loader.list_of_attributes.map do |attributes|
+ @collection = collection(*args)
+ end
+
+ def collection(*args)
+ _collection = loader.list_of_attributes(*args).map do |attributes|
collection_options[:model].new(attributes)
end
- if sanitizer = collection_options[:sanitizer]
- sanitizer.new(site.default_locale, site.locales).apply_to(@collection)
- else
- @collection
- end
+ sanitize!(_collection)
+ end
+
+ def sanitize!(collection)
+ sanitizer.try(:apply_to, collection) || collection
+ end
+
+ def sanitizer
+ return unless (klass = collection_options[:sanitizer])
+ klass.new(site.default_locale, site.locales)
end
module ClassMethods
locomotive/steam/repositories/filesystem/content_entry.rb b/lib/locomotive/steam/repositories/filesystem/content_entry.rb +41 -13
@@ @@ -3,48 +3,76 @@ module Locomotive
module Repositories
module Filesystem
- class ContentEntry < Struct.new(:site)
+ class ContentEntry < Struct.new(:loader, :site, :current_locale)
+ include Concerns::Queryable
+
+ set_collection model: Filesystem::Models::ContentEntry, sanitizer: Filesystem::Sanitizers::ContentEntry
+
+ # Engine: ???
def all(type, conditions = {})
- # TODO
- raise 'TODO all'
+ conditions ||= {}
+
+ # TODO: order_by goes here (get settings from the type)
+
+ query(type) do
+ where(conditions.merge(_visible: true)).order_by(conditions.delete(:order_by))
+ end.all
+ end
+
+ # Engine: entry.name :-)
+ def value_for(name, entry, conditions = {})
+ value = entry.send(name)
+
+ if value.respond_to?(:association)
+ association(value, conditions || {})
+ else
+ value
+ end
end
- def filter(association, conditions = {})
+ # Note:
+ def association(metadata, conditions = {})
# only visible entries
# conditions[:_visible] = true
# order_by = conditions.delete(:order_by).try(:split)
# association.filtered(conditions, order_by)
-
raise 'TODO filter'
end
+ # Engine: entry.next
def next(entry)
- # entry.next
raise 'TODO next'
end
+ # Engine: entry.previous
def previous(entry)
- # entry.previous
raise 'TODO previous'
end
+ # Engine: content_type.entries.klass.send(:group_by_select_option, name, content_type.order_by_definition)
def group_by_select_option(type, name)
- # klass = content_type.entries.klass
- # order = content_type.order_by_definition
-
- # klass.send(:group_by_select_option, name, order)
raise 'TODO group_by_select_option'
end
+ # Engine: content_type.entries.klass.send(:"#{name}_options").map { |option| option['name'] }
def select_options(type, name)
- # klass = content_type.entries.klass
- # klass.send(:"#{name}_options").map { |option| option['name'] }
raise 'TODO select_options'
end
+ private
+
+ def memoized_collection(content_type)
+ slug = content_type.slug
+ @collections ||= {}
+
+ return @collections[slug] if @collections[slug]
+
+ @collections[slug] = collection(content_type)
+ end
+
end
end
locomotive/steam/repositories/filesystem/memory_adapter/query.rb b/lib/locomotive/steam/repositories/filesystem/memory_adapter/query.rb +1 -1
@@ @@ -39,7 +39,7 @@ module Locomotive
end
def order_by(order_string)
- @sorting = order_string.downcase.split.map(&:to_sym) unless order_string.empty?
+ @sorting = order_string.downcase.split.map(&:to_sym) unless order_string.blank?
self
end
locomotive/steam/repositories/filesystem/models/base.rb b/lib/locomotive/steam/repositories/filesystem/models/base.rb +1 -1
@@ @@ -14,7 +14,7 @@ module Locomotive
def method_missing(name, *args, &block)
if attributes.include?(name)
- attributes[name.to_sym]
+ self[name]
else
super
end
locomotive/steam/repositories/filesystem/models/content_entry.rb b/lib/locomotive/steam/repositories/filesystem/models/content_entry.rb +79 -0
@@ @@ -0,0 +1,79 @@
+ require 'chronic'
+
+ module Locomotive
+ module Steam
+ module Repositories
+ module Filesystem
+ module Models
+
+ class ContentEntry < Base
+
+ set_localized_attributes [:_id, :_slug, :seo_title, :meta_description, :meta_keywords]
+
+ attr_accessor :content_type
+
+ def initialize(attributes = {})
+ super({
+ _visible: true,
+ _position: 0
+ }.merge(attributes))
+ end
+
+ def _slug; self[:_slug]; end
+ alias :_id :_slug
+ alias :_permalink :_slug
+
+ def _label
+ self[content_type.label_field_name]
+ end
+
+ def [](name)
+ is_dynamic_attribute?(name) ? cast_value(name) : super
+ end
+
+ def localized_attributes
+ self.class.localized_attributes + content_type.localized_fields_names
+ end
+
+ private
+
+ def is_dynamic_attribute?(name)
+ content_type.fields_by_name.has_key?(name)
+ end
+
+ def cast_value(name)
+ case (field = content_type.fields_by_name[name]).type
+ when :integer then _cast_value(name, &:to_i)
+ when :float then _cast_value(name, &:to_f)
+ when :date then _cast_value(name) { |v| v.is_a?(String) ? Chronic.parse(v).to_date : v }
+ when :date_time then _cast_value(name) { |v| v.is_a?(String) ? Chronic.parse(v).to_datetime : v }
+ when :file then _cast_value(name) { |v| v.present? ? { 'url' => v } : nil }
+ when :belongs_to, :has_many, :many_to_many
+ AssociationMetadata.new(field.type, self, field, [*attributes[name]])
+ else
+ attributes[name]
+ end
+ rescue Exception => e
+ Locomotive::Common::Logger.info "[#{content_type.slug}][#{_label}] Unable to cast the \"#{name}\" field, reason: #{e.message}".yellow
+ nil
+ end
+
+ def _cast_value(name, &block)
+ if (value = attributes[name]).is_a?(Hash)
+ value.each { |l, _value| value[l] = yield(_value) }
+ else
+ yield(value)
+ end
+ end
+
+ class AssociationMetadata < Struct.new(:type, :source, :field, :target_slugs)
+ def association; true; end
+ end
+
+ end
+
+ end
+ end
+ end
+ end
+ end
locomotive/steam/repositories/filesystem/models/content_type.rb b/lib/locomotive/steam/repositories/filesystem/models/content_type.rb +14 -0
@@ @@ -6,6 +6,20 @@ module Locomotive
class ContentType < Base
+ attr_accessor :fields, :fields_by_name
+
+ def label_field_name
+ (self[:label_field_name] || fields.first.name).to_sym
+ end
+
+ def localized_fields_names
+ query_fields { where(localized: true) }.all.map(&:name)
+ end
+
+ def query_fields(&block)
+ Filesystem::MemoryAdapter::Query.new(fields, &block)
+ end
+
end
end
locomotive/steam/repositories/filesystem/models/content_type_field.rb b/lib/locomotive/steam/repositories/filesystem/models/content_type_field.rb +2 -1
@@ @@ -8,7 +8,8 @@ module Locomotive
def initialize(attributes)
super({
- type: :string
+ type: :string,
+ localized: false
}.merge(attributes))
end
locomotive/steam/repositories/filesystem/models/page.rb b/lib/locomotive/steam/repositories/filesystem/models/page.rb +1 -1
@@ @@ -6,7 +6,7 @@ module Locomotive
class Page < Base
- set_localized_attributes [:title, :slug, :permalink, :editable_elements, :template, :template_path, :fullpath, :seo, :meta_description, :meta_keywords]
+ set_localized_attributes [:title, :slug, :permalink, :editable_elements, :template, :template_path, :fullpath, :seo_title, :meta_description, :meta_keywords]
attr_accessor :depth, :_fullpath
locomotive/steam/repositories/filesystem/models/site.rb b/lib/locomotive/steam/repositories/filesystem/models/site.rb +1 -1
@@ @@ -6,7 +6,7 @@ module Locomotive
class Site < Base
- set_localized_attributes [:seo, :meta_description, :meta_keywords]
+ set_localized_attributes [:seo_title, :meta_description, :meta_keywords]
attr_accessor :root_path
locomotive/steam/repositories/filesystem/sanitizers/content_entry.rb b/lib/locomotive/steam/repositories/filesystem/sanitizers/content_entry.rb +66 -0
@@ @@ -0,0 +1,66 @@
+ module Locomotive
+ module Steam
+ module Repositories
+ module Filesystem
+ module Sanitizers
+
+ class ContentEntry < Struct.new(:default_locale, :locales)
+
+ def apply_to(collection)
+ collection.each do |entry|
+ set_content_type(entry)
+ add_label(entry)
+ set_slug(entry, collection)
+ end
+ end
+
+ def set_slug(entry, collection)
+ if entry._label.is_a?(Hash)
+ entry[:_slug] ||= {}
+ entry._label.each do |locale, label|
+ entry[:_slug][locale] ||= slugify(label, collection, locale)
+ end
+ else
+ entry[:_slug] ||= slugify(entry._label, collection)
+ end
+ end
+
+ def slugify(label, collection, locale = nil)
+ base, index = label.singularize.parameterize('-'), nil
+ _slugify = -> (i) { [base, i].compact.join('-') }
+
+ while !is_slug_unique?(_slugify.call(index), collection, locale)
+ index += 1
+ end
+
+ _slugify.call(index)
+ end
+
+ def is_slug_unique?(slug, collection, locale)
+ Filesystem::MemoryAdapter::Query.new(collection, locale) do
+ where(_slug: slug)
+ end.first.nil?
+ end
+
+ def set_content_type(entry)
+ entry.content_type = entry.attributes.delete(:content_type)
+ end
+
+ def add_label(entry)
+ value = entry.attributes.delete(:_label)
+ name = entry.content_type.label_field_name
+
+ if entry.attributes[name].is_a?(Hash) # localized?
+ entry.attributes[name][default_locale] = value
+ else
+ entry.attributes[name] = value
+ end
+ end
+
+ end
+
+ end
+ end
+ end
+ end
+ end
locomotive/steam/repositories/filesystem/sanitizers/content_type.rb b/lib/locomotive/steam/repositories/filesystem/sanitizers/content_type.rb +14 -2
@@ @@ -8,9 +8,11 @@ module Locomotive
def apply_to(collection)
collection.each do |content_type|
- if list = content_type.fields
- content_type[:fields] = build_fields(list)
+ if list = content_type.attributes[:fields]
+ content_type[:slug] = content_type[:slug].to_s
+ content_type.fields = build_fields(list)
end
+ build_fields_by_name_shortcut(content_type)
end
end
@@ @@ -24,10 +26,20 @@ module Locomotive
_attributes[:label] = name.to_s.humanize
end
+ _attributes[:type] = _attributes[:type].to_sym
+
Filesystem::Models::ContentTypeField.new(_attributes)
end
end
+ def build_fields_by_name_shortcut(content_type)
+ content_type.fields_by_name = {}
+
+ (content_type.fields || []).each do |field|
+ content_type.fields_by_name[field.name] = field
+ end
+ end
+
end
end
locomotive/steam/repositories/filesystem/yaml_loaders/content_entry.rb b/lib/locomotive/steam/repositories/filesystem/yaml_loaders/content_entry.rb +45 -0
@@ @@ -0,0 +1,45 @@
+ module Locomotive
+ module Steam
+ module Repositories
+ module Filesystem
+ module YAMLLoaders
+
+ class ContentEntry < Struct.new(:root_path, :cache)
+
+ include YAMLLoaders::Concerns::Common
+
+ def list_of_attributes(content_type)
+ cache.fetch("data/#{content_type.slug}") { load_list(content_type) }
+ end
+
+ private
+
+ def load_list(content_type)
+ [].tap do |list|
+ each(content_type.slug) do |label, attributes, position|
+ default = { content_type: content_type, _position: position, _label: label.to_s }
+ list << default.merge(attributes)
+ end
+ end
+ end
+
+ def each(slug, &block)
+ position = 0
+ load(File.join(path, "#{slug}.yml")).each do |element|
+ label, attributes = element.keys.first, element.values.first
+ yield(label, attributes, position)
+ position += 1
+ end
+ end
+
+ def path
+ File.join(root_path, 'data')
+ end
+
+ end
+
+ end
+ end
+ end
+ end
+ end
locomotivecms_steam.gemspec +1 -0
@@ @@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'stringex', '~> 2.5.2'
spec.add_dependency 'morphine', '~> 0.1.1'
spec.add_dependency 'httparty', '~> 0.13.3'
+ spec.add_dependency 'chronic', '~> 0.10.2'
spec.add_dependency 'rack-cache', '~> 1.2'
spec.add_dependency 'dragonfly', '~> 1.0.7'
spec/unit/repositories/filesystem/content_entry_spec.rb +81 -0
@@ @@ -0,0 +1,81 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Repositories::Filesystem::ContentEntry do
+
+ # let(:fields) { [{ title: { hint: 'Title of the article' } }, { author: { type: 'string', label: 'Fullname of the author' } }] }
+ let(:type) { instance_double('Articles', slug: 'articles', label_field_name: :title, localized_fields_names: [:title], fields_by_name: { title: instance_double('Field', type: :string) }) }
+ let(:loader) { instance_double('Loader', list_of_attributes: [{ content_type: type, _position: 0, _label: 'Update #1', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General' }]) }
+ let(:site) { instance_double('Site', default_locale: :en, locales: [:en, :fr]) }
+ let(:locale) { :en }
+
+ let(:repository) { Locomotive::Steam::Repositories::Filesystem::ContentEntry.new(loader, site, locale) }
+
+ describe '#collection' do
+
+ subject { repository.send(:collection, type) }
+
+ it { expect(subject.size).to eq 1 }
+
+ describe 'once after the sanitizer has been applied' do
+
+ subject { repository.send(:collection, type).first }
+
+ it { expect(subject.class).to eq Locomotive::Steam::Repositories::Filesystem::Models::ContentEntry }
+ it { expect(subject.title).to eq({ en: 'Update #1', fr: 'Mise a jour #1' }) }
+ it { expect(subject._slug).to eq({ en: 'update-1', fr: 'mise-a-jour-1' }) }
+ it { expect(subject.content_type).to eq type }
+
+ end
+
+ end
+
+ describe '#value_for' do
+
+ let(:name) { :title }
+ let(:entry) { instance_double('Article', title: 'Hello world') }
+
+ subject { repository.value_for(name, entry) }
+
+ it { is_expected.to eq 'Hello world' }
+
+ context 'association' do
+
+ # TODO
+
+ end
+
+ end
+
+ describe '#all' do
+
+ let(:conditions) { nil }
+ subject { repository.all(type, conditions) }
+
+ it { expect(subject.size).to eq 1 }
+
+ end
+
+ # describe '#by_slug' do
+
+ # let(:slug) { nil }
+ # subject { repository.by_slug(slug) }
+
+ # it { is_expected.to eq nil }
+
+ # context 'existing content type' do
+
+ # let(:slug) { 'articles' }
+ # it { expect(subject.name).to eq 'Articles' }
+
+ # end
+
+ # context 'slug is already a content type' do
+
+ # let(:slug) { instance_double('ContentType') }
+ # it { is_expected.to eq slug }
+
+ # end
+
+ # end
+
+ end
spec/unit/repositories/filesystem/content_type_spec.rb +2 -0
@@ @@ -17,7 +17,9 @@ describe Locomotive::Steam::Repositories::Filesystem::ContentType do
it 'applies the sanitizer' do
expect(subject.name).to eq('Articles')
+ expect(subject.slug).to eq('articles')
expect(subject.fields.size).to eq 2
+ expect(subject.fields_by_name.size).to eq 2
end
describe 'a field of the first element' do
spec/unit/repositories/filesystem/models/content_entry_spec.rb +133 -0
@@ @@ -0,0 +1,133 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Repositories::Filesystem::Models::ContentEntry do
+
+ let(:type) { instance_double('ContentType', slug: 'articles', label_field_name: :title, localized_fields_names: [:title], fields_by_name: {}) }
+ let(:attributes) { { title: 'Hello world', _slug: 'hello-world' } }
+ let(:content_entry) do
+ Locomotive::Steam::Repositories::Filesystem::Models::ContentEntry.new(attributes).tap do |entry|
+ entry.content_type = type
+ end
+ end
+
+ describe '#_label' do
+
+ subject { content_entry._label }
+ it { is_expected.to eq 'Hello world' }
+
+ end
+
+ describe '#_id' do
+
+ subject { content_entry._id }
+ it { is_expected.to eq 'hello-world' }
+
+ end
+
+ describe '#localized_attributes' do
+
+ subject { content_entry.localized_attributes }
+ it { is_expected.to include :seo_title }
+ it { is_expected.to include :title }
+ it { is_expected.to include :_slug }
+
+ end
+
+ describe 'dynamic attributes' do
+
+ let(:field_type) { :string }
+ let(:attributes) { { my_field: value } }
+ let(:field) { instance_double('Field', type: field_type) }
+ before { allow(type).to receive(:fields_by_name).and_return(my_field: field) }
+
+ subject { content_entry.my_field }
+
+ describe 'unable to cast it' do
+
+ let(:field_type) { :float }
+ let(:value) { [] }
+ it { is_expected.to eq nil }
+
+ end
+
+ context 'a string' do
+ let(:value) { 'Hello world' }
+ it { is_expected.to eq 'Hello world' }
+ context 'localized' do
+ let(:value) { { en: 'Hello world', fr: 'Bonjour monde' } }
+ it { is_expected.to eq({ en: 'Hello world', fr: 'Bonjour monde' }) }
+ end
+ end
+
+ context 'an integer' do
+ let(:field_type) { :integer }
+ let(:value) { '42' }
+ it { is_expected.to eq 42 }
+ context 'localized' do
+ let(:value) { { en: 42, fr: '42' } }
+ it { is_expected.to eq({ en: 42, fr: 42 }) }
+ end
+ end
+
+ context 'a float' do
+ let(:field_type) { :float }
+ let(:value) { '42.0' }
+ it { is_expected.to eq 42.0 }
+ context 'localized' do
+ let(:value) { { en: 42.0, fr: '42.0' } }
+ it { is_expected.to eq({ en: 42.0, fr: 42.0 }) }
+ end
+ end
+
+ context 'a date' do
+ let(:field_type) { :date }
+ let(:value) { '2007/06/29' }
+ let(:date) { Date.parse('2007/06/29') }
+ it { is_expected.to eq date }
+ context 'localized' do
+ let(:value) { { en: '2007/06/29', fr: date } }
+ it { is_expected.to eq({ en: date, fr: date }) }
+ end
+ end
+
+ context 'a date time' do
+ let(:field_type) { :date }
+ let(:value) { '2007/06/29 00:00:00' }
+ let(:datetime) { DateTime.parse('2007/06/29 00:00:00') }
+ it { is_expected.to eq datetime }
+ context 'localized' do
+ let(:value) { { en: '2007/06/29 00:00:00', fr: datetime } }
+ it { is_expected.to eq({ en: datetime, fr: datetime }) }
+ end
+ end
+
+ context 'a belongs_to relationship' do
+ let(:field_type) { :belongs_to }
+ let(:value) { 'john-doe' }
+ it { expect(subject.type).to eq :belongs_to }
+ it { expect(subject.target_slugs).to eq ['john-doe'] }
+ it { expect(subject.source).to eq content_entry }
+ it { expect(subject.field).to eq field }
+ end
+
+ context 'a has_many relationship' do
+ let(:field_type) { :has_many }
+ let(:value) { nil }
+ it { expect(subject.type).to eq :has_many }
+ it { expect(subject.target_slugs).to eq [] }
+ it { expect(subject.source).to eq content_entry }
+ it { expect(subject.field).to eq field }
+ end
+
+ context 'a many_to_many relationship' do
+ let(:field_type) { :many_to_many }
+ let(:value) { ['john-doe', 'jane-doe'] }
+ it { expect(subject.type).to eq :many_to_many }
+ it { expect(subject.target_slugs).to eq ['john-doe', 'jane-doe'] }
+ it { expect(subject.source).to eq content_entry }
+ it { expect(subject.field).to eq field }
+ end
+
+ end
+
+ end
spec/unit/repositories/filesystem/models/content_type_spec.rb +42 -0
@@ @@ -0,0 +1,42 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Repositories::Filesystem::Models::ContentType do
+
+ let(:fields) { [instance_double('Field1', label: 'Title', name: 'title'), instance_double('Field2', label: 'Author', name: 'author')] }
+ let(:content_type) do
+ Locomotive::Steam::Repositories::Filesystem::Models::ContentType.new(name: 'Articles').tap do |type|
+ type.fields = fields
+ end
+ end
+
+ describe '#field_by_name' do
+
+ let(:name) { nil }
+ subject { content_type.field_by_name(name) }
+
+ it { is_expected.to eq nil }
+
+ context 'not nil name' do
+
+ let(:name) { 'author' }
+ it { expect(subject.label).to eq 'Author' }
+
+ end
+
+ end
+
+ describe '#label_field' do
+
+ subject { content_type.label_field.try(:label) }
+ it { is_expected.to eq 'Title' }
+
+ context 'defined within the content type itself' do
+
+ before { allow(content_type.attributes).to receive(:[]).with(:label_field_name).and_return('author') }
+ it { is_expected.to eq 'Author' }
+
+ end
+
+ end
+
+ end
spec/unit/repositories/filesystem/yaml_loaders/content_entry_spec.rb +22 -0
@@ @@ -0,0 +1,22 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Repositories::Filesystem::YAMLLoaders::ContentEntry do
+
+ let(:root_path) { default_fixture_site_path }
+ let(:cache) { NoCacheStore.new }
+ let(:content_type) { instance_double('Articles', slug: 'bands') }
+ let(:loader) { Locomotive::Steam::Repositories::Filesystem::YAMLLoaders::ContentEntry.new(root_path, cache) }
+
+ describe '#list_of_attributes' do
+
+ subject { loader.list_of_attributes(content_type).sort { |a, b| a[:_label] <=> b[:_label] } }
+
+ it 'tests various stuff' do
+ expect(subject.size).to eq 3
+ expect(subject.first[:_label]).to eq 'Alice in Chains'
+ expect(subject.first.content_type).to eq content_type
+ end
+
+ end
+
+ end