nanoc-oo 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +31 -0
  6. data/Rakefile +1 -0
  7. data/bin/nanoc-oo +17 -0
  8. data/cucumber.yml +8 -0
  9. data/data/nanoc-oo/wrapper/Rules +115 -0
  10. data/data/nanoc-oo/wrapper/lib/classes/1_page.rb +198 -0
  11. data/data/nanoc-oo/wrapper/lib/fake_dir.rb +27 -0
  12. data/data/nanoc-oo/wrapper/lib/fake_item.rb +39 -0
  13. data/data/nanoc-oo/wrapper/lib/fake_items.rb +22 -0
  14. data/data/nanoc-oo/wrapper/lib/filter_for.rb +14 -0
  15. data/data/nanoc-oo/wrapper/lib/item_class.rb +22 -0
  16. data/features/_related_tests.feature +32 -0
  17. data/features/composite_file.example +82 -0
  18. data/features/move_children.example +43 -0
  19. data/features/paginate_article.example +86 -0
  20. data/features/step_definitions/complex_steps.rb +23 -0
  21. data/features/step_definitions/nanoc-oo_steps.rb +9 -0
  22. data/features/step_definitions/nanoc_steps.rb +22 -0
  23. data/features/step_definitions/steps.rb +1 -0
  24. data/features/support/env.rb +25 -0
  25. data/features/support/my_extension.rb +16 -0
  26. data/features/support/nice_steps.rb +14 -0
  27. data/lib/nanoc-oo/version.rb +3 -0
  28. data/lib/nanoc-oo.rb +25 -0
  29. data/nanoc-oo.gemspec +32 -0
  30. data/old-README.md +72 -0
  31. data/spec/add_item_spec.rb +97 -0
  32. data/spec/cli/all_spec.rb +57 -0
  33. data/spec/item_children_and_comiling_spec.rb +97 -0
  34. data/spec/items_configuration_spec.rb +239 -0
  35. data/spec/layouts_spec.rb +50 -0
  36. data/spec/rspec/compiler_spec.rb +8 -0
  37. data/spec/rspec/nanoc_spec.rb +13 -0
  38. data/spec/rspec/wrapper_spec.rb +15 -0
  39. data/spec/support/0_coverage.rb +18 -0
  40. data/spec/support/1_config.rb +27 -0
  41. data/spec/support/2_nanoc.rb +27 -0
  42. data/spec/support/3_wrapper.rb +17 -0
  43. data/spec/support/4_compiler.rb +16 -0
  44. data/spec/support/5_temp_files.rb +51 -0
  45. data/spec/support/6_temp_helpers.rb +98 -0
  46. data/spec/support/all.rb +22 -0
  47. data/spec/unit/fake_dir_spec.rb +45 -0
  48. data/spec/unit/fake_item_spec.rb +62 -0
  49. data/spec/unit/fake_items_spec.rb +38 -0
  50. data/spec/unit/filter_for_spec.rb +12 -0
  51. data/spec/unit/item_class_spec.rb +42 -0
  52. data/spec/unit/page_spec.rb +96 -0
  53. data/spec/unit/temp_files_spec.rb +107 -0
  54. metadata +278 -0
@@ -0,0 +1,43 @@
1
+ @wip
2
+ Feature: move children items
3
+
4
+ Background:
5
+ Given I have a blank wrapped nanoc site
6
+ And the folowing are input files:
7
+ """
8
+ content/one/index.html
9
+ content/one/item1.html
10
+ content/one/item2.html
11
+ content/two/index.html
12
+ """
13
+ And the folowing are expected output files:
14
+ """
15
+ output/one/index.html
16
+ output/two/index.html
17
+ output/two/item1/index.html
18
+ output/two/item2/index.html
19
+ """
20
+
21
+ Scenario:
22
+ Given the following empty files exist:
23
+ | content/one/index.html |
24
+ | content/one/item1.html |
25
+ | content/one/item2.html |
26
+ | content/two/index.html |
27
+ And a file named "lib/classes/classes.rb" with:
28
+ """
29
+ class One < Page
30
+ GOOD_ID = 'one'
31
+ end
32
+
33
+ class Two < Page
34
+ GOOD_ID = 'two'
35
+ end
36
+
37
+ class ThatItem < Page
38
+ GOOD_ID = 'one/*'
39
+ end
40
+ """
41
+ When I successfully compile it
42
+ Then input are the only files in "content" directory
43
+ And expected output are the only files in "output" directory
@@ -0,0 +1,86 @@
1
+ Feature: paginate article example
2
+
3
+ Scenario:
4
+ Given I have a blank wrapped nanoc site
5
+ And a file named "content/article.html.md" with:
6
+ """
7
+ # First Header
8
+
9
+ ...
10
+
11
+ # Second Header
12
+
13
+ ...
14
+
15
+ # Third Header
16
+
17
+ ...
18
+
19
+ """
20
+ And a file named "lib/classes/articles.rb" with:
21
+ """
22
+ class Article < Page
23
+ GOOD_ID = // # any item found
24
+
25
+ LAYOUT = '/article_contents/' # replace original content using layout
26
+
27
+ # create sub pages
28
+ def preprocess context
29
+ pages(item.raw_content).each_with_index do |page,index|
30
+ ArticlePage.create context, page, {}, %"#{identifier}#{index+1}/"
31
+ end
32
+ end
33
+
34
+ private
35
+ def pages content, one_page=/# .+?(?:(?=# )|\z)/m
36
+ content.scan(one_page).map &:strip
37
+ end
38
+ end
39
+
40
+ class ArticlePage < Page
41
+ GOOD_ID = nil # only manual assignment by Page.create
42
+ EXT = 'html' # for proper routing to index.html
43
+ end
44
+ """
45
+ And a file named "layouts/article_contents.slim" with:
46
+ """
47
+ - @title = /# (.*)$/
48
+ - for page in (+item).children
49
+ a href=page.path = page.raw_content[@title,1]
50
+ """
51
+ When I successfully compile it
52
+ Then the following files should exist:
53
+ | output/article/index.html |
54
+ | output/article/1/index.html |
55
+ | output/article/2/index.html |
56
+ | output/article/3/index.html |
57
+ And the file "output/article/index.html" should contain:
58
+ """
59
+ <a href="1/">First Header
60
+ """
61
+ And the file "output/article/index.html" should contain:
62
+ """
63
+ <a href="2/">Second Header
64
+ """
65
+ And the file "output/article/index.html" should contain:
66
+ """
67
+ <a href="3/">Third Header
68
+ """
69
+ And the file "output/article/1/index.html" should contain exactly:
70
+ """
71
+ # First Header
72
+
73
+ ...
74
+ """
75
+ And the file "output/article/2/index.html" should contain exactly:
76
+ """
77
+ # Second Header
78
+
79
+ ...
80
+ """
81
+ And the file "output/article/3/index.html" should contain exactly:
82
+ """
83
+ # Third Header
84
+
85
+ ...
86
+ """
@@ -0,0 +1,23 @@
1
+ def make_table array
2
+ table array.map { |str| [str] }
3
+ end
4
+
5
+ Step 'the folowing are * files:...' do |group, files|
6
+ (@groups ||= {})[group] = files.lines.map(&:strip).reject &:empty?
7
+ end
8
+
9
+ Step 'the * files should *exist' do |group, nt| # nt~not
10
+ step "the following files should #{nt}exist:", make_table(@groups[group])
11
+ end
12
+
13
+ Step '(the )?*( files)? are the only (ones|files) in( the)? "*" directory' do |group, dir|
14
+ really = nil
15
+ in_current_dir do
16
+ really = Dir[File.join(dir,'**/**')].to_a
17
+ end
18
+ ideal = @groups[group]
19
+ extra = really - ideal
20
+ missing = ideal - really
21
+ step 'the following files should exist:', make_table(missing)
22
+ step 'the following files should not exist:', make_table(extra)
23
+ end
@@ -0,0 +1,9 @@
1
+ Given 'I have a wrapped default nanoc site' do
2
+ step '$ nanoc-oo site'
3
+ step 'I cd to "site"'
4
+ end
5
+
6
+ Given 'I have a blank wrapped nanoc site' do
7
+ step '$ nanoc-oo site --blank'
8
+ step 'I cd to "site"'
9
+ end
@@ -0,0 +1,22 @@
1
+ Step '[>$] ?nanoc *' do |command|
2
+ step "I successfully run `ruby -S nanoc #{command}`"
3
+ end
4
+
5
+ Step '[>$] ?nanoc-oo *' do |command|
6
+ step "I successfully run `ruby -S nanoc-oo #{command}`"
7
+ end
8
+
9
+ Given 'I have a default nanoc site' do
10
+ step '$ nanoc create-site site'
11
+ step 'I cd to "site"'
12
+ end
13
+
14
+ When 'I successfully compile it' do
15
+ step '$ nanoc compile'
16
+ step 'it is successfully compiled'
17
+ end
18
+
19
+ Then 'it is successfully compiled' do
20
+ step 'a directory named "output" should exist'
21
+ step 'the file "crash.log" should not exist'
22
+ end
@@ -0,0 +1 @@
1
+ #Step 'the following files'
@@ -0,0 +1,25 @@
1
+ require 'aruba/cucumber'
2
+ include FileUtils
3
+
4
+
5
+ def clean_temp
6
+ rm_rf 'tmp'
7
+ end
8
+ AfterConfiguration do |config|
9
+ clean_temp
10
+ end
11
+ at_exit do
12
+ clean_temp
13
+ end
14
+
15
+
16
+ def copy_all params
17
+ from, to = params[:from], params[:to]
18
+ cp_r from, to
19
+ end
20
+
21
+
22
+ __END__
23
+ || undefined method 'feature' for ...ScenarioOutline...reporting.rb:101
24
+ \/
25
+ ENV['ARUBA_REPORT_DIR'] = 'doc_features'
@@ -0,0 +1,16 @@
1
+ # tricky way to register .example files as cucumber features
2
+
3
+ DEFAULT = /\*\.feature$/
4
+ MODIFIED = '*.example'
5
+
6
+ class Dir
7
+ class << self
8
+ alias _super []
9
+ end
10
+
11
+ def self.[] mask
12
+ return _super(mask) if mask !~ DEFAULT
13
+
14
+ _super(mask).to_a + _super(mask.sub(DEFAULT, MODIFIED)).to_a
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ def full_line line
2
+ /^#{line}$/
3
+ end
4
+
5
+ def regex str
6
+ str.gsub!(/\(/, '(?:')
7
+ str.gsub!(/\*/, '(.*?)')
8
+ str.sub!(/\.\.\.$/, '.*')
9
+ full_line str
10
+ end
11
+
12
+ def Step step, &block
13
+ When regex(step), &block
14
+ end
@@ -0,0 +1,3 @@
1
+ module NanocOO
2
+ VERSION = "0.0.1"
3
+ end
data/lib/nanoc-oo.rb ADDED
@@ -0,0 +1,25 @@
1
+ require "nanoc-oo/version"
2
+
3
+ module NanocOO
4
+ include FileUtils
5
+
6
+ def create_site name, blank=false
7
+ `nanoc create-site #{name}`
8
+ wrap name
9
+ delete_content name if blank
10
+ end
11
+
12
+ def wrap dir
13
+ cp_r wrapper+'/.', dir
14
+ end
15
+
16
+ def wrapper
17
+ File.join Gem.datadir('nanoc-oo'), 'wrapper'
18
+ end
19
+
20
+ def delete_content dir
21
+ rm_r File.join(dir,'content')
22
+ end
23
+
24
+ extend self
25
+ end
data/nanoc-oo.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'nanoc-oo/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "nanoc-oo"
8
+ gem.version = NanocOO::VERSION
9
+ gem.authors = ['Alexander K']
10
+ gem.email = ['xpyro@ya.ru']
11
+ gem.description = %q{ with this you can map classes to directories and use inheritance in your nanoc site }
12
+ gem.summary = %q{ nanoc wrapper with OO taste }
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency 'rspec'
21
+ gem.add_development_dependency 'cucumber'
22
+ gem.add_development_dependency 'aruba'
23
+ gem.add_development_dependency 'slim'
24
+ gem.add_development_dependency 'nokogiri'
25
+ gem.add_development_dependency 'kramdown'
26
+ gem.add_development_dependency 'sass'
27
+
28
+ gem.add_dependency 'nanoc'
29
+ gem.add_dependency 'thor'
30
+
31
+ gem.executables << 'nanoc-oo'
32
+ end
data/old-README.md ADDED
@@ -0,0 +1,72 @@
1
+ # nanoc-OO [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/sowcow/nanoc-oo)
2
+
3
+ * even more powerful nanoc (\*with object oriented taste\*)
4
+
5
+ * the main idea is to decouple Rules file to classes \<link to feature>
6
+
7
+ * by default files extensions are used to apply filters to layouts and items \<link to feature>
8
+
9
+ * **pending** (+item).children is filled with children by default; some dsl to reuse items by assigning them as children to other items; compiling is guided by children tree
10
+
11
+ ## under the hood:
12
+
13
+ * does not affect nanoc internals (and doesn't use them by now)
14
+ * generates individual compile/route rules for each item
15
+ * actually generates only one compile/route rule for root item, and it in turn generates rules for its children and so on
16
+ * so there is kind of items for directories (`FakeDir`) to compile deeply seated items
17
+ * `FakeItem` is kind of Nanoc::Item, that extracts `identifier` and `extension` from file name and has its own `#html?` and `#binary?` methods
18
+ * `FakeItems` class is used to build array of items before even preprocessing stage
19
+ * one instance of `Page`s subclasses is assigned for each item and it is accessible by `(+item)`; `(+item).item` is item itself
20
+ * `Page`s are mostly configured by `CONSTANTS` or by methods that by default use that constants, both ways are inheritable by subclasses
21
+ * any naming improvements or other thoughts are welcome
22
+
23
+ ## todo:
24
+
25
+ 1. children/parent
26
+ 1. Rules file:
27
+ * get rid of trash
28
+ * is it running twice (rspec)?
29
+ 1. cucumber features / examples
30
+ 1. extract methods from step definitions?
31
+ 1. layout in a class << !
32
+ 1. decouple specs
33
+ 1. comments -> specs
34
+ 1. improve rspec tables?
35
+ 1. ...
36
+
37
+ ## notes:
38
+
39
+ ### useful:
40
+
41
+ * relative paths filter is applying by default
42
+ * configureable
43
+
44
+ ### cryptic:
45
+
46
+ * specs for UndefinedPage?
47
+ * unused Hidable
48
+ * refactor:
49
+ * specs:
50
+ * refactor temp spec helpers
51
+ * refactor specs with true/false variant arrays
52
+ * use `context` properly (in specs)
53
+ * specs want to be cleaned
54
+ * refactor specs...
55
+ * fix specs: `it 'should work'`, `it 'routes properly'`, ...
56
+ * extract `"#{ SITE }/output/#{ name }..."`
57
+ * `'some.erb'.html?`
58
+ * silent `no compilation rules found` by introducing empty compilation rule in `UndefinedPage`?
59
+ * use factories?
60
+ * require inside code
61
+ * Rules file functions are passing params too much
62
+ * Rules:`unless item.is_a? FakeDir` is not tested decision
63
+ * unclear testing dependencies
64
+ * require FileUtils?
65
+ * fakeitem ~ nanocitem
66
+ * specs (lack of specification of code that is covered by features)
67
+ * binary?
68
+ * extension or ''
69
+ * raw_content
70
+ * EXT = , ID=nil, Page.create, ...
71
+ * (+item).parent?
72
+ * GOOD_ID= '*/some/**'
@@ -0,0 +1,97 @@
1
+ require 'support/all'
2
+ require_lib
3
+
4
+
5
+ describe 'Page#preprocess' do
6
+ let(:name){ 'test-page-preprocess' }
7
+
8
+ it 'should take context with items as parameter' do
9
+ Page.new('').method(:preprocess).arity.should == 1
10
+ end
11
+
12
+ describe '<context> argument' do
13
+
14
+ before do
15
+ TempFiles.create "#{ SITE }/lib/classes/#{ name }.rb" do
16
+ "
17
+ class TestingPage < Page
18
+ GOOD_ID = Regexp.new Regexp.escape '/#{ name }/'
19
+ #{ configuration }
20
+ end
21
+
22
+ class NewItems < Page
23
+ GOOD_ID = %r|item_|
24
+ end
25
+ "
26
+ end
27
+ end
28
+ before do
29
+ create_item("#{ name }.html.erb"){ '<strong><%= item[:value] %></strong>' }
30
+ end
31
+
32
+ describe 'value' do
33
+ let(:configuration) do
34
+ "
35
+ def preprocess context
36
+ item[:value] = context.items.count
37
+ end
38
+ "
39
+ end
40
+
41
+ it 'reflects items' do
42
+ compile!
43
+ output_file(name)[/<strong>(.+)<\/strong>/, 1].should == '1'
44
+ end
45
+ end
46
+
47
+ describe '<<' do
48
+ let(:configuration) do
49
+ '
50
+ def preprocess context
51
+ 3.times do |counter|
52
+ context.items << Nanoc::Item.new("", {extension: \'html\'}, "/item_#{ counter }/")
53
+ end
54
+ end
55
+ '
56
+ end
57
+
58
+ it 'adds item' do
59
+ compile!
60
+ Dir["#{ SITE }/output/**/*.html"].count.should == 3 + 1 # "/#{ name }.html"
61
+ end
62
+ end
63
+
64
+ describe 'reject!' do
65
+
66
+ context 'configuration 1' do
67
+ let(:configuration) do
68
+ '
69
+ def preprocess context
70
+ context.items.reject! { true }
71
+ end
72
+ '
73
+ end
74
+
75
+ it 'removes items' do
76
+ compile!
77
+ Dir["#{ SITE }/output/**/*.html"].count.should == 0
78
+ end
79
+ end
80
+
81
+ context 'configuration 2' do
82
+ let(:configuration) do
83
+ '
84
+ def preprocess context
85
+ context.items.reject! { |those| those.identifier != identifier }
86
+ end
87
+ '
88
+ end
89
+
90
+ it 'removes items' do
91
+ compile!
92
+ Dir["#{ SITE }/output/**/*.html"].count.should == 1
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,57 @@
1
+ require 'nanoc-oo'
2
+
3
+ describe NanocOO do
4
+ include FileUtils
5
+
6
+ let(:temp){ 'temp' }
7
+ let(:site){ "#{temp}/site" }
8
+ before :each do
9
+ rm_rf temp
10
+ end
11
+ after :each do
12
+ rm_rf temp
13
+ end
14
+
15
+ it 'creates site with nanoc' do
16
+ `nanoc-oo #{site}`
17
+ File.should exist join(site,'Rules')
18
+ Dir[join(site,'content')].count.should > 0
19
+ end
20
+
21
+ it 'creates site with nanoc (w/o cli)' do
22
+ NanocOO.create_site site
23
+ File.should exist join(site,'Rules')
24
+ Dir[join(site,'content')].count.should > 0
25
+ end
26
+
27
+ it 'creates site without content if --blank specified' do
28
+ `nanoc-oo #{site} --blank`
29
+ File.should exist join(site,'Rules')
30
+ Dir[join(site,'content')].count.should == 0
31
+ end
32
+
33
+ describe 'created site' do
34
+ before do
35
+ `nanoc-oo #{site}`
36
+ end
37
+
38
+ it 'is wrapped' do
39
+ read(join(site,'Rules')).should == read(join(NanocOO.wrapper,'Rules'))
40
+ end
41
+
42
+ context 'terminal outputs' do
43
+ specify 'nanoc output'
44
+ specify 'wrapping info'
45
+ specify '--help?'
46
+ end if false
47
+ end
48
+ end
49
+
50
+ BEGIN{
51
+ def join *a
52
+ File.join *a
53
+ end
54
+ def read *a
55
+ File.read *a
56
+ end
57
+ }
@@ -0,0 +1,97 @@
1
+ require 'support/all'
2
+ require_lib
3
+
4
+ def chdir name
5
+ Dir.mkdir name
6
+ Dir.chdir name do
7
+ yield
8
+ end
9
+ end
10
+
11
+ def write file, text=lorem
12
+ File.write file, text
13
+ end
14
+
15
+
16
+
17
+ describe 'items compiling guided by children' do
18
+ before do
19
+ create_class do
20
+ "
21
+ class Test < Page
22
+ GOOD_ID = //
23
+ end
24
+ "
25
+ end
26
+ end
27
+
28
+ context 'just root item' do
29
+ before do
30
+ create_item('index.html'){ lorem }
31
+ end
32
+
33
+ it 'works' do
34
+ compile!
35
+ File.should exist "#{SITE}/output/index.html"
36
+ end
37
+ end
38
+
39
+ context 'just non-root item' do
40
+ let(:name){ 'non-root-item' }
41
+ before do
42
+ create_item("#{name}.html"){ lorem }
43
+ end
44
+
45
+ it 'works' do
46
+ compile!
47
+ File.should exist output name
48
+ end
49
+ end
50
+
51
+ context 'one deep seated item' do
52
+
53
+ let(:name){ 'deep/seated/item' }
54
+ before do
55
+ create_item("#{name}.html"){ lorem }
56
+ end
57
+
58
+ it 'works' do
59
+ compile!
60
+ File.should exist output name
61
+ end
62
+ end
63
+
64
+ context 'small tree of items with index.html files' do
65
+
66
+ let(:name){'some-temp-test-dir'}
67
+ let(:dir){"#{SITE}/content/#{name}"}
68
+ let(:text){ lorem }
69
+ after :all do
70
+ rm_rf dir
71
+ end
72
+ before :all do
73
+ chdir dir do
74
+ write 'index.html'
75
+ write 'file1.html'
76
+ chdir 'dir' do
77
+ write 'index.html'
78
+ write 'file2.html'
79
+ write 'file3.html'
80
+ end
81
+ end
82
+ end
83
+
84
+ it 'compiles nested files' do
85
+ compile!
86
+ File.should exist output "#{name}/file1"
87
+ File.should exist output "#{name}/dir/file2"
88
+ File.should exist output "#{name}/dir/file3"
89
+ end
90
+
91
+ it 'compiles index items' do
92
+ compile!
93
+ File.should exist output name
94
+ File.should exist output "#{name}/dir"
95
+ end
96
+ end
97
+ end