copy_no_dependency 0.2.0

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 (51) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +5 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +20 -0
  5. data/README.md +66 -0
  6. data/Rakefile +10 -0
  7. data/bin/copy +27 -0
  8. data/copy.gemspec +28 -0
  9. data/lib/copy/admin/copy.css +66 -0
  10. data/lib/copy/admin/edit.html.erb +12 -0
  11. data/lib/copy/admin/index.html.erb +44 -0
  12. data/lib/copy/admin/index.js.erb +105 -0
  13. data/lib/copy/admin/jquery-ui.js +100 -0
  14. data/lib/copy/admin/jquery.js +18 -0
  15. data/lib/copy/generators/site/Gemfile +20 -0
  16. data/lib/copy/generators/site/config.ru +27 -0
  17. data/lib/copy/generators/site/public/favicon.ico +0 -0
  18. data/lib/copy/generators/site/public/images/.gitkeep +0 -0
  19. data/lib/copy/generators/site/public/javascripts/.gitkeep +0 -0
  20. data/lib/copy/generators/site/public/javascripts/main.js +0 -0
  21. data/lib/copy/generators/site/public/robots.txt +5 -0
  22. data/lib/copy/generators/site/public/stylesheets/.gitkeep +0 -0
  23. data/lib/copy/generators/site/public/stylesheets/main.css +0 -0
  24. data/lib/copy/generators/site/views/index.html.erb +1 -0
  25. data/lib/copy/generators/site/views/layout.html.erb +14 -0
  26. data/lib/copy/router.rb +62 -0
  27. data/lib/copy/server.rb +132 -0
  28. data/lib/copy/storage.rb +30 -0
  29. data/lib/copy/storage/mongodb.rb +38 -0
  30. data/lib/copy/storage/redis.rb +17 -0
  31. data/lib/copy/storage/relational.rb +35 -0
  32. data/lib/copy/version.rb +3 -0
  33. data/lib/copy_no_dependency.rb +6 -0
  34. data/test/router_test.rb +108 -0
  35. data/test/server_test.rb +183 -0
  36. data/test/storage_test.rb +50 -0
  37. data/test/test_app/views/_one.html.erb +1 -0
  38. data/test/test_app/views/_three.html.erb +1 -0
  39. data/test/test_app/views/about/_two.html.erb +2 -0
  40. data/test/test_app/views/about/index.html.erb +1 -0
  41. data/test/test_app/views/about/us.html.erb +1 -0
  42. data/test/test_app/views/data/people.csv.erb +1 -0
  43. data/test/test_app/views/data/people.xml.erb +1 -0
  44. data/test/test_app/views/indented.html.erb +9 -0
  45. data/test/test_app/views/index.html.erb +1 -0
  46. data/test/test_app/views/layout.html.erb +8 -0
  47. data/test/test_app/views/renders_partials.html.erb +4 -0
  48. data/test/test_app/views/with_copy_helper.html.erb +3 -0
  49. data/test/test_app/views/with_copy_helper_one_line.html.erb +1 -0
  50. data/test/test_helper.rb +49 -0
  51. metadata +181 -0
@@ -0,0 +1,183 @@
1
+ require 'test_helper'
2
+ require 'rack/test'
3
+
4
+ class ServerTest < Test::Unit::TestCase
5
+ include CopyAppSetup
6
+ include Rack::Test::Methods
7
+
8
+ test "GET index" do
9
+ get '/'
10
+
11
+ assert last_response.ok?
12
+ assert_equal 'text/html;charset=utf-8', last_response.headers['Content-Type']
13
+ assert_match "<title>I'm the layout!</title>", last_response.body
14
+ assert_match "<p>I'm the index!</p>", last_response.body
15
+ end
16
+
17
+ test "GET path with index in folder" do
18
+ %w(/about /about/).each do |path|
19
+ get path
20
+
21
+ assert last_response.ok?
22
+ assert_match "<p>About!</p>", last_response.body
23
+ end
24
+ end
25
+
26
+ test "GET path to template in folder" do
27
+ %w(/about/us /about/us/).each do |path|
28
+ get path
29
+
30
+ assert last_response.ok?
31
+ assert_match "<p>About us!</p>", last_response.body
32
+ end
33
+ end
34
+
35
+ test "GET non-existent path" do
36
+ get '/nope'
37
+ assert last_response.status == 404
38
+ end
39
+
40
+ test "cache_time setting sets a Cache-Control header" do
41
+ app.config { set :cache_time, 456 }
42
+ get '/'
43
+ assert_equal 'public, max-age=456', last_response.headers['Cache-Control']
44
+
45
+ [0, nil, false].each do |time|
46
+ app.config { set :cache_time, time }
47
+ get '/'
48
+ assert_equal 'no-cache', last_response.headers['Cache-Control']
49
+ end
50
+ end
51
+
52
+ test "GET csv" do
53
+ get 'data/people.csv'
54
+
55
+ assert last_response.ok?
56
+ assert_equal 'text/csv;charset=utf-8', last_response.headers['Content-Type']
57
+ assert_equal File.read(app.settings.views + '/data/people.csv.erb'), last_response.body
58
+ end
59
+
60
+ test "GET xml" do
61
+ get 'data/people.xml'
62
+
63
+ assert last_response.ok?
64
+ assert_equal 'application/xml;charset=utf-8', last_response.headers['Content-Type']
65
+ assert_equal File.read(app.settings.views + '/data/people.xml.erb'), last_response.body
66
+ end
67
+
68
+ test "connects to storage when setting present" do
69
+ connection_url = 'redis://localhost:1234'
70
+ app.config { set :storage, connection_url }
71
+ Copy::Storage.expects(:connect!).with(connection_url).once.returns(true)
72
+ get '/'
73
+ assert last_response.ok?
74
+ end
75
+ end
76
+
77
+ class ServerCopyHelperTest < Test::Unit::TestCase
78
+ include CopyAppSetup
79
+ include Rack::Test::Methods
80
+
81
+ test "copy helper displays content from storage" do
82
+ Copy::Storage.stubs(:connected?).returns(true)
83
+ Copy::Storage.expects(:get).with(:facts).returns("truth")
84
+
85
+ get 'with_copy_helper'
86
+ assert last_response.ok?
87
+ assert_match "truth", last_response.body
88
+ end
89
+
90
+ test "copy helper saves defaults text when content is not in storage and renders it" do
91
+ Copy::Storage.stubs(:connected?).returns(true)
92
+ Copy::Storage.expects(:get).with(:facts).returns(nil)
93
+ Copy::Storage.expects(:set).with(:facts, "_Default Text_\n").returns(true)
94
+
95
+ get 'with_copy_helper'
96
+ assert last_response.ok?, last_response.errors
97
+ assert_match %Q(<div class="_copy_editable" data-name="facts"><p><em>Default Text</em></p></div>), last_response.body
98
+ end
99
+
100
+ test "copy helper shows default text when not connected" do
101
+ Copy::Storage.expects(:connected?).twice.returns(false)
102
+
103
+ get 'with_copy_helper'
104
+ assert last_response.ok?
105
+ assert_match %Q(<div class="_copy_editable" data-name="facts"><p><em>Default Text</em></p></div>), last_response.body
106
+ end
107
+
108
+ test "copy helper renders single line content correctly" do
109
+ Copy::Storage.expects(:connected?).twice.returns(false)
110
+
111
+ get 'with_copy_helper_one_line'
112
+ assert last_response.ok?
113
+ assert_match %Q(<span class="_copy_editable" data-name="headline">Important!</span>), last_response.body
114
+ end
115
+
116
+ test "copy helper indented in view" do
117
+ Copy::Storage.stubs(:connected?).returns(true)
118
+ Copy::Storage.expects(:get).with(:three).returns(nil)
119
+ Copy::Storage.expects(:set).with(:three, "three\n").returns(true)
120
+
121
+ get 'indented'
122
+ assert last_response.ok?, last_response.errors
123
+ assert_match %Q(<div class="_copy_editable" data-name="three"><p>three</p></div>), last_response.body
124
+ end
125
+
126
+ test "partial rendering" do
127
+ get 'renders_partials'
128
+ assert last_response.ok?, last_response.errors
129
+ assert_match "before\none\ntwo\nthree\nafter", last_response.body
130
+ end
131
+ end
132
+
133
+ class ServerAdminTest < Test::Unit::TestCase
134
+ include CopyAppSetup
135
+ include Rack::Test::Methods
136
+
137
+ test "GET /_copy is protected when no user/pass are set" do
138
+ get '/_copy'
139
+ assert_equal 401, last_response.status
140
+ end
141
+
142
+ test "GET /_copy protected when user/pass are set, but supplied incorrectly" do
143
+ setup_auth 'good', 'girl'
144
+ authorize 'bad', 'boy'
145
+ get '/_copy'
146
+ assert_equal 401, last_response.status
147
+ end
148
+
149
+ test "GET /_copy with valid credentials" do
150
+ authorize!
151
+ get '/_copy'
152
+ assert last_response.ok?
153
+ assert_match 'Edit Copy', last_response.body
154
+ end
155
+
156
+ test "GET /_copy.js" do
157
+ authorize!
158
+ get '/_copy.js'
159
+ assert last_response.ok?, last_response.errors
160
+ assert_match 'jQuery JavaScript Library', last_response.body
161
+ end
162
+
163
+ test "GET /_copy/:name" do
164
+ Copy::Storage.stubs(:connected?).returns(true)
165
+ Copy::Storage.expects(:get).with('fun').returns("<b>party\n")
166
+
167
+ authorize!
168
+ get '/_copy/fun'
169
+ assert last_response.ok?, last_response.errors
170
+ assert_match "&lt;b&gt;party\n</textarea>", last_response.body
171
+ end
172
+
173
+ test "PUT /_copy/:name" do
174
+ Copy::Storage.stubs(:connected?).returns(true)
175
+ Copy::Storage.expects(:set).with('fun', '_party_').returns(true)
176
+ Copy::Storage.expects(:get).with('fun').returns('_party_')
177
+
178
+ authorize!
179
+ put '/_copy/fun', :content => '_party_', :wrap_tag => 'article'
180
+ assert last_response.ok?, last_response.errors
181
+ assert_match %Q(<article class="_copy_editable" data-name="fun"><em>party</em></article>), last_response.body
182
+ end
183
+ end
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ # Maybe TODO: Should the tests require a running redis, mongo, mysql
4
+ # instance and actually test getting, setting data?
5
+
6
+ class StorageTest < Test::Unit::TestCase
7
+ test "mongodb connect!" do
8
+ connection_url ='mongodb://copy:secret@localhost/copy-content'
9
+ Copy::Storage::Mongodb.expects(:new).with(connection_url).returns(true)
10
+
11
+ assert Copy::Storage.connect!(connection_url)
12
+ end
13
+
14
+ test "redis connect!" do
15
+ connection_url ='redis://localhost:6379'
16
+ Copy::Storage::Redis.expects(:new).with(connection_url).returns(true)
17
+
18
+ assert Copy::Storage.connect!(connection_url)
19
+ end
20
+
21
+ test "mysql connect!" do
22
+ connection_url = 'mysql://localhost/copy_content'
23
+ Copy::Storage::Relational.expects(:new).with(connection_url).returns(true)
24
+
25
+ assert Copy::Storage.connect!(connection_url)
26
+ end
27
+
28
+ test "postgres connect!" do
29
+ connection_url = 'postgres://localhost/copy_content'
30
+ Copy::Storage::Relational.expects(:new).with(connection_url).returns(true)
31
+
32
+ assert Copy::Storage.connect!(connection_url)
33
+ end
34
+
35
+ test "sqlite connect!" do
36
+ connection_url = 'sqlite:///path/to/copy_content.db'
37
+ Copy::Storage::Relational.expects(:new).with(connection_url).returns(true)
38
+
39
+ assert Copy::Storage.connect!(connection_url)
40
+ end
41
+
42
+ test "get and set" do
43
+ connection_url ='redis://localhost:6379'
44
+ Copy::Storage::Redis.expects(:new).with(connection_url).returns(stub(:get => :result1, :set => :result2))
45
+
46
+ Copy::Storage.connect!(connection_url)
47
+ assert_equal :result1, Copy::Storage.get('name')
48
+ assert_equal :result2, Copy::Storage.set('name', 'content')
49
+ end
50
+ end
@@ -0,0 +1 @@
1
+ three
@@ -0,0 +1,2 @@
1
+ two
2
+ <%= partial :three %>
@@ -0,0 +1 @@
1
+ <p>About!</p>
@@ -0,0 +1 @@
1
+ <p>About us!</p>
@@ -0,0 +1 @@
1
+ Javan,Zooey,Nali
@@ -0,0 +1 @@
1
+ <person>Javan</person>
@@ -0,0 +1,9 @@
1
+ <div>
2
+ <div class="one">
3
+ <div class="two">
4
+ <% copy :three do %>
5
+ three
6
+ <% end %>
7
+ </div>
8
+ </div>
9
+ </div>
@@ -0,0 +1 @@
1
+ <p>I'm the index!</p>
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title>I'm the layout!</title>
4
+ </head>
5
+ <body>
6
+ <%= yield %>
7
+ </body>
8
+ </html>
@@ -0,0 +1,4 @@
1
+ before
2
+ <%= partial 'one' %>
3
+ <%= partial 'about/two' %>
4
+ after
@@ -0,0 +1,3 @@
1
+ <% copy :facts do %>
2
+ _Default Text_
3
+ <% end %>
@@ -0,0 +1 @@
1
+ <h1><% copy :headline do %>Important!<% end %></h1>
@@ -0,0 +1,49 @@
1
+ dir = File.dirname(File.expand_path(__FILE__))
2
+ $LOAD_PATH.unshift dir + '/../lib'
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ begin
7
+ require 'turn'
8
+ rescue LoadError
9
+ end
10
+ require 'mocha/setup'
11
+ require 'copy'
12
+
13
+ class Test::Unit::TestCase
14
+ def self.test(name, &block)
15
+ define_method("test_#{name.gsub(/\W/,'_')}", &block) if block
16
+ end
17
+
18
+ def self.setup(&block)
19
+ define_method(:setup, &block)
20
+ end
21
+
22
+ def self.teardown(&block)
23
+ define_method(:teardown, &block)
24
+ end
25
+ end
26
+
27
+ module CopyAppSetup
28
+ def app
29
+ Copy::Server
30
+ end
31
+
32
+ def setup
33
+ app.config do
34
+ set :views, File.dirname(File.expand_path(__FILE__)) + '/test_app/views'
35
+ end
36
+ end
37
+
38
+ def setup_auth(user, pass)
39
+ app.config do
40
+ set :copy_username, user
41
+ set :copy_password, pass
42
+ end
43
+ end
44
+
45
+ def authorize!
46
+ setup_auth 'super', 'secret'
47
+ authorize 'super', 'secret'
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: copy_no_dependency
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Javan Makhmali
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sinatra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redcarpet
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 2.2.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 2.2.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: mocha
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
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Serves mostly static pages with blocks of editable copy.
84
+ email:
85
+ - javan@javan.us
86
+ executables:
87
+ - copy
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - .gitignore
92
+ - Gemfile
93
+ - LICENSE
94
+ - README.md
95
+ - Rakefile
96
+ - bin/copy
97
+ - copy.gemspec
98
+ - lib/copy/admin/copy.css
99
+ - lib/copy/admin/edit.html.erb
100
+ - lib/copy/admin/index.html.erb
101
+ - lib/copy/admin/index.js.erb
102
+ - lib/copy/admin/jquery-ui.js
103
+ - lib/copy/admin/jquery.js
104
+ - lib/copy/generators/site/Gemfile
105
+ - lib/copy/generators/site/config.ru
106
+ - lib/copy/generators/site/public/favicon.ico
107
+ - lib/copy/generators/site/public/images/.gitkeep
108
+ - lib/copy/generators/site/public/javascripts/.gitkeep
109
+ - lib/copy/generators/site/public/javascripts/main.js
110
+ - lib/copy/generators/site/public/robots.txt
111
+ - lib/copy/generators/site/public/stylesheets/.gitkeep
112
+ - lib/copy/generators/site/public/stylesheets/main.css
113
+ - lib/copy/generators/site/views/index.html.erb
114
+ - lib/copy/generators/site/views/layout.html.erb
115
+ - lib/copy/router.rb
116
+ - lib/copy/server.rb
117
+ - lib/copy/storage.rb
118
+ - lib/copy/storage/mongodb.rb
119
+ - lib/copy/storage/redis.rb
120
+ - lib/copy/storage/relational.rb
121
+ - lib/copy/version.rb
122
+ - lib/copy_no_dependency.rb
123
+ - test/router_test.rb
124
+ - test/server_test.rb
125
+ - test/storage_test.rb
126
+ - test/test_app/views/_one.html.erb
127
+ - test/test_app/views/_three.html.erb
128
+ - test/test_app/views/about/_two.html.erb
129
+ - test/test_app/views/about/index.html.erb
130
+ - test/test_app/views/about/us.html.erb
131
+ - test/test_app/views/data/people.csv.erb
132
+ - test/test_app/views/data/people.xml.erb
133
+ - test/test_app/views/indented.html.erb
134
+ - test/test_app/views/index.html.erb
135
+ - test/test_app/views/layout.html.erb
136
+ - test/test_app/views/renders_partials.html.erb
137
+ - test/test_app/views/with_copy_helper.html.erb
138
+ - test/test_app/views/with_copy_helper_one_line.html.erb
139
+ - test/test_helper.rb
140
+ homepage: https://github.com/javan/copy
141
+ licenses: []
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ! '>='
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project: copy
159
+ rubygems_version: 2.1.10
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Simple, Sinatra-based CMS.
163
+ test_files:
164
+ - test/router_test.rb
165
+ - test/server_test.rb
166
+ - test/storage_test.rb
167
+ - test/test_app/views/_one.html.erb
168
+ - test/test_app/views/_three.html.erb
169
+ - test/test_app/views/about/_two.html.erb
170
+ - test/test_app/views/about/index.html.erb
171
+ - test/test_app/views/about/us.html.erb
172
+ - test/test_app/views/data/people.csv.erb
173
+ - test/test_app/views/data/people.xml.erb
174
+ - test/test_app/views/indented.html.erb
175
+ - test/test_app/views/index.html.erb
176
+ - test/test_app/views/layout.html.erb
177
+ - test/test_app/views/renders_partials.html.erb
178
+ - test/test_app/views/with_copy_helper.html.erb
179
+ - test/test_app/views/with_copy_helper_one_line.html.erb
180
+ - test/test_helper.rb
181
+ has_rdoc: