knish 0.2.6

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.
@@ -0,0 +1,188 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Knish::Model do
4
+ let(:model) { model_class.new(attrs) }
5
+
6
+ let(:model_class) do
7
+ Project # defined in support
8
+ end
9
+
10
+ let(:attrs) { {} }
11
+ let(:id) { nil }
12
+
13
+ let(:data_path) { "#{model.config.model_root}/data.json" }
14
+
15
+ before { clear_db(db_fixture_path) }
16
+ after { clear_db(db_fixture_path) }
17
+
18
+ context 'when no id is provided' do
19
+ let(:id) { nil }
20
+
21
+ it 'uses the next id' do
22
+ expect(model.id).to eq(1)
23
+ end
24
+ end
25
+
26
+ context 'when an id is included in the initialization hash' do
27
+ let(:attrs) { {id: 42} }
28
+
29
+ it 'uses it' do
30
+ expect(model.id).to eq(42)
31
+ end
32
+ end
33
+
34
+ describe 'configed attributes' do
35
+ it 'should have getters and setters for the data attributes' do
36
+ expect(model).to respond_to('name')
37
+ expect(model).to respond_to('name=')
38
+ expect(model).to respond_to('url')
39
+ expect(model).to respond_to('url=')
40
+ end
41
+
42
+ it 'should have getters and setters for the markdown attributes' do
43
+ expect(model).to respond_to('description')
44
+ expect(model).to respond_to('description=')
45
+ end
46
+
47
+ it 'should have getters the collections' do
48
+ expect(model).to respond_to('stories')
49
+ end
50
+ end
51
+
52
+ context 'when initilaized with attributes' do
53
+ let(:attrs) {
54
+ {
55
+ name: 'My New Project',
56
+ url: 'github.com/baccigalupi/my-new-project',
57
+ description: '#Headline!'
58
+ }
59
+ }
60
+
61
+ it 'sets each of these into an attribute' do
62
+ expect(model.name).to eq(attrs[:name])
63
+ expect(model.url).to eq(attrs[:url])
64
+ expect(model.description).to eq(attrs[:description])
65
+ end
66
+ end
67
+
68
+ describe '#save' do
69
+ let(:attrs) {
70
+ {
71
+ name: 'My New Project',
72
+ url: 'github.com/baccigalupi/my-new-project',
73
+ description: '#Headline!'
74
+ }
75
+ }
76
+
77
+ let(:saved_data) { JSON.parse(File.read(data_path)) }
78
+
79
+ let(:model) { Nested::Deeply::Is::Project.new(attrs) }
80
+
81
+ it 'saves to file the data attributes' do
82
+ model.save
83
+ expect(saved_data['name']).to eq(attrs[:name])
84
+ expect(saved_data['url']).to eq(attrs[:url])
85
+ end
86
+
87
+ it 'also save the class name in a specal attribute' do
88
+ model.save
89
+ expect(saved_data['___type']).to eq('Nested::Deeply::Is::Project')
90
+ end
91
+
92
+ it 'saves markdown files' do
93
+ model.save
94
+ expect(File.read("#{model.config.model_root}/_description.md")).to eq(attrs[:description])
95
+ end
96
+ end
97
+
98
+ describe '#load' do
99
+ let(:model_directory) { File.dirname(data_path) }
100
+
101
+ before do
102
+ FileUtils.mkdir_p(model_directory)
103
+ File.open(data_path, 'w') { |f| f.write({name: 'Name'}.to_json) }
104
+ File.open("#{model_directory}/_description.md", 'w') { |f| f.write("#Hello") }
105
+ end
106
+
107
+ it 'loads the data into attributes' do
108
+ model.load
109
+ expect(model.name).to eq('Name')
110
+ end
111
+
112
+ it 'loads the markdown files into attributes' do
113
+ model.load
114
+ expect(model.description).to eq('#Hello')
115
+ end
116
+ end
117
+
118
+ describe '#template' do
119
+ let(:reader) { double('reader') }
120
+
121
+ it 'delegates it down to the reader' do
122
+ allow(Knish::Reader).to receive(:new).and_return(reader)
123
+ expect(reader).to receive(:template).with('key').and_return("some_path")
124
+ expect(model.template('key')).to eq('some_path')
125
+ end
126
+ end
127
+
128
+ describe 'adding to collections, and saving on that collection directly' do
129
+ it 'stores and retrieves any kind of Knish object to the collection' do
130
+ model.stories << Feature.new(name: 'Do something great, and quickly')
131
+ model.stories << Bug.new(name: 'Fix all the badness, go!')
132
+
133
+ expect(model.stories.first.name).to eq('Do something great, and quickly')
134
+ expect(model.stories.last.name).to eq('Fix all the badness, go!')
135
+ end
136
+
137
+ it 'saves the models to the right location' do
138
+ model.stories << Feature.new(name: 'Do something great, and quickly')
139
+ model.stories << Bug.new(name: 'Fix all the badness, go!')
140
+
141
+ model.stories.save
142
+
143
+ expect(File.exist?("#{model.config.model_root}/stories/1")).to be(true)
144
+ end
145
+ end
146
+
147
+ describe 'loading collections, is done via direct call to collection through the model' do
148
+ let(:attrs) {
149
+ {
150
+ name: 'My New Project',
151
+ url: 'github.com/baccigalupi/my-new-project',
152
+ description: '#Headline!'
153
+ }
154
+ }
155
+
156
+ before do
157
+ model.stories << Feature.new(name: 'Make it go', description: 'Do I have to specify this?')
158
+ model.stories << Bug.new(name: 'It just doesn\'t work', description: 'Do I have to specify this?')
159
+ model.stories.save
160
+ end
161
+
162
+ let(:loaded_model) {
163
+ project = Project.new(id: model.id)
164
+ project.stories.load
165
+ project
166
+ }
167
+
168
+ it 'builds the right classes for collection models' do
169
+ expect(loaded_model.stories.size).to eq(2)
170
+ expect(loaded_model.stories.first).to be_a(Feature)
171
+ expect(loaded_model.stories.last).to be_a(Bug)
172
+ end
173
+
174
+ it 'models have the right ids' do
175
+ expect(loaded_model.stories.first.id).to eq(1)
176
+ expect(loaded_model.stories.last.id).to eq(2)
177
+ end
178
+ end
179
+
180
+ context 'in order to have the models work well in forms for ActiveModel' do
181
+ let(:naming) { double('naming class') }
182
+
183
+ it 'shortens the name' do
184
+ expect(ActiveModel::Name).to receive(:new).with(Nested::Deeply::Is::Project, Nested::Deeply::Is).and_return(naming)
185
+ Nested::Deeply::Is::Project.model_name
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Knish::Reader do
4
+ let(:reader) { Knish::Reader.new(config) }
5
+ let(:config) {
6
+ c = Knish::ModelConfig.new(fixture_db_config, 'posts', id)
7
+ c.markdown_attributes = ['key']
8
+ c
9
+ }
10
+ let(:id) { 32 }
11
+
12
+ before { clear_db(db_fixture_path) }
13
+ after { clear_db(db_fixture_path) }
14
+
15
+ context 'when the collection directory does not exist' do
16
+ it '#get_json returns an empty hash' do
17
+ expect(reader.get_json).to eq({})
18
+ end
19
+
20
+ it '#get_markdown returns an empty string' do
21
+ expect(reader.get_markdown).to eq({'key' => ''})
22
+ end
23
+
24
+ it '#template returns the path as though it were there' do
25
+ expect(reader.template('key')).to eq("/../../knish/posts/32/key")
26
+ end
27
+
28
+ it 'should not be persisted' do
29
+ expect(reader.persisted?).to eq(false)
30
+ end
31
+ end
32
+
33
+ context 'when the data exists' do
34
+ before do
35
+ FileUtils.mkdir_p(config.model_root)
36
+ File.open("#{config.model_root}/data.json", 'w') {|f| f.write({hello: 'happy json'}.to_json)}
37
+ File.open("#{config.model_root}/_key.md", 'w') {|f| f.write("#hello!")}
38
+ end
39
+
40
+ it '#get_json returns the found data' do
41
+ expect(reader.get_json).to eq({'hello' => 'happy json'})
42
+ end
43
+
44
+ it '#get_markdown returns the contents of the file' do
45
+ expect(reader.get_markdown).to eq({'key' =>"#hello!"})
46
+ end
47
+
48
+ it '#template returns the path to the markdown file, rails style' do
49
+ expect(reader.template('key')).to eq("/../../knish/posts/32/key")
50
+ end
51
+
52
+ it 'should be persisted' do
53
+ expect(reader.persisted?).to eq(true)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,34 @@
1
+ $: << File.dirname(__FILE__) + "/../lib"
2
+
3
+ require_relative "fixtures/active_model_mock"
4
+
5
+ require 'knish'
6
+ require 'bundler'
7
+
8
+ Dir.glob(File.dirname(__FILE__) + "/support/**/*").each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+ config.expect_with :rspec do |expectations|
12
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
13
+ end
14
+
15
+ config.mock_with :rspec do |mocks|
16
+ mocks.verify_partial_doubles = true
17
+ end
18
+
19
+ config.disable_monkey_patching!
20
+
21
+ if config.files_to_run.one?
22
+ config.default_formatter = 'doc'
23
+ end
24
+
25
+ config.order = :random
26
+ Kernel.srand config.seed
27
+
28
+ config.before {
29
+ Knish.clear_config
30
+ Knish.configure do |c|
31
+ c.db_directory = db_fixture_path
32
+ end
33
+ }
34
+ end
@@ -0,0 +1,19 @@
1
+ def clear_db(path)
2
+ Dir.glob(path).each { |p| FileUtils.rm_rf(p) }
3
+ end
4
+
5
+ def db_fixture_path
6
+ File.expand_path(File.dirname(__FILE__) + "/../fixtures/db")
7
+ end
8
+
9
+ def full_db_path
10
+ db_fixture_path + "/knish"
11
+ end
12
+
13
+ def fixture_db_config
14
+ c = Knish::DbConfig.new
15
+ c.db_directory = db_fixture_path
16
+ c
17
+ end
18
+
19
+
@@ -0,0 +1,32 @@
1
+ Project = Knish.build('projects') do |config|
2
+ config.db_directory = db_fixture_path
3
+ config.data_attributes = ['name', 'url']
4
+ config.markdown_attributes = ['description']
5
+ config.collections = ['stories']
6
+ end
7
+
8
+ Feature = Knish.build('features') do |config|
9
+ config.db_directory = db_fixture_path
10
+ config.data_attributes = ['name']
11
+ config.markdown_attributes = ['overview', 'description', 'scenarios']
12
+ end
13
+
14
+ Bug = Knish.build('bugs') do |config|
15
+ config.db_directory = db_fixture_path
16
+ config.data_attributes = ['name']
17
+ config.markdown_attributes = ['description', 'reproduction_steps', 'expected', 'actual', 'additional_information']
18
+ end
19
+
20
+ module Nested
21
+ module Deeply
22
+ module Is
23
+ Project = Knish.build('projects') do |config|
24
+ config.db_directory = db_fixture_path
25
+ config.data_attributes = ['name', 'url']
26
+ config.markdown_attributes = ['description']
27
+ config.collections = ['stories']
28
+ config.omitted_namespace = Nested::Deeply::Is
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Knish::Writer do
4
+ let(:writer) { Knish::Writer.new(config) }
5
+ let(:config) { Knish::ModelConfig.new(fixture_db_config, 'posts', id) }
6
+ let(:id) { 32 }
7
+
8
+ before { clear_db(db_fixture_path) }
9
+ after { clear_db(db_fixture_path) }
10
+
11
+ describe '#build_directories' do
12
+ it 'will create the collection root directory' do
13
+ writer.build_directories([])
14
+ expect(File.exist?(config.model_root)).to eq(true)
15
+ end
16
+
17
+ it 'will create directories specified' do
18
+ writer.build_directories(['foo', 'bar'])
19
+ expect(File.exist?("#{config.model_root}/foo")).to eq(true)
20
+ expect(File.exist?("#{config.model_root}/bar")).to eq(true)
21
+ end
22
+ end
23
+
24
+ describe '#save_json' do
25
+ it 'will build the root if it does not exist' do
26
+ writer.save_json({})
27
+ expect(File.exist?(config.model_root)).to eq(true)
28
+ end
29
+
30
+ it 'creates a data.json file in the root directory' do
31
+ writer.save_json({})
32
+ expect(File.exist?("#{config.model_root}/data.json")).to eq(true)
33
+ end
34
+
35
+ it 'has the right data' do
36
+ writer.save_json({hello: 'knish'})
37
+ data = JSON.load(File.read("#{config.model_root}/data.json"))
38
+ expect(data).to eq({'hello' => 'knish'})
39
+ end
40
+ end
41
+
42
+ describe '#save_markdown' do
43
+ it 'will build the root if it does not exist' do
44
+ writer.save_markdown({description: '#Description'})
45
+ expect(File.exist?(config.model_root)).to eq(true)
46
+ end
47
+
48
+ it 'creates file with named for the key' do
49
+ writer.save_markdown({description: '#Description'})
50
+ expect(File.exist?("#{config.model_root}/_description.md")).to eq(true)
51
+ end
52
+
53
+ it 'has the markdown' do
54
+ writer.save_markdown({description: '#Description'})
55
+ data = File.read("#{config.model_root}/_description.md")
56
+ expect(data).to eq('#Description')
57
+ end
58
+ end
59
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knish
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.6
5
+ platform: ruby
6
+ authors:
7
+ - Kane Baccigalupi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |-
56
+ The problem with CMSs is that you really want your application content in source control,
57
+ not a database. Knish provides a structured data model for saving data to json, and formatted html to markdown
58
+ email:
59
+ - baccigalupi@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - ".rspec"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - knish.gemspec
71
+ - lib/knish.rb
72
+ - lib/knish/builder.rb
73
+ - lib/knish/collection.rb
74
+ - lib/knish/collection_config.rb
75
+ - lib/knish/db_config.rb
76
+ - lib/knish/delegate_inspector.rb
77
+ - lib/knish/existing_models.rb
78
+ - lib/knish/member.rb
79
+ - lib/knish/model.rb
80
+ - lib/knish/model_config.rb
81
+ - lib/knish/reader.rb
82
+ - lib/knish/version.rb
83
+ - lib/knish/writer.rb
84
+ - spec/builder_spec.rb
85
+ - spec/collection_config_spec.rb
86
+ - spec/collection_spec.rb
87
+ - spec/fixtures/active_model_mock.rb
88
+ - spec/knish_spec.rb
89
+ - spec/model_config_spec.rb
90
+ - spec/model_spec.rb
91
+ - spec/reader_spec.rb
92
+ - spec/spec_helper.rb
93
+ - spec/support/file_helpers.rb
94
+ - spec/support/model_classes.rb
95
+ - spec/writer_spec.rb
96
+ homepage: http://github.com/baccigalupi/knish
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.2.2
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: File backed data models, excellent for CMS apps!
120
+ test_files:
121
+ - spec/builder_spec.rb
122
+ - spec/collection_config_spec.rb
123
+ - spec/collection_spec.rb
124
+ - spec/fixtures/active_model_mock.rb
125
+ - spec/knish_spec.rb
126
+ - spec/model_config_spec.rb
127
+ - spec/model_spec.rb
128
+ - spec/reader_spec.rb
129
+ - spec/spec_helper.rb
130
+ - spec/support/file_helpers.rb
131
+ - spec/support/model_classes.rb
132
+ - spec/writer_spec.rb