knish 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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