kaboom 0.3.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.
@@ -0,0 +1,96 @@
1
+ # coding: utf-8
2
+
3
+ # Storage adapter that saves data from boom to MongoDB instead of JSON file.
4
+ begin
5
+ require 'mongo'
6
+ rescue LoadError
7
+ end
8
+
9
+ module Boom
10
+ module Storage
11
+ class Mongodb < Base
12
+
13
+ def self.sample_config
14
+ %(
15
+ {"backend": "mongodb",
16
+ "mongodb": {
17
+ "port": "",
18
+ "host": ""
19
+ "database": ""
20
+ "username": ""
21
+ "password": ""
22
+ }
23
+ })
24
+ end
25
+
26
+ # Public: Initialize MongoDB connection and check dep.
27
+ #
28
+ # Returns Mongo connection
29
+ def mongo
30
+ @mongo ||= ::Mongo::Connection.new(
31
+ Boom.config.attributes["mongodb"]["host"],
32
+ Boom.config.attributes["mongodb"]["port"]
33
+ ).db(Boom.config.attributes["mongodb"]["database"])
34
+
35
+ @mongo.authenticate(
36
+ Boom.config.attributes['mongodb']['username'],
37
+ Boom.config.attributes['mongodb']['password']
38
+ )
39
+
40
+ # Return connection
41
+ @mongo
42
+ rescue Exception => exception
43
+ handle exception, "You don't have the Mongo gem installed yet:\n gem install mongo"
44
+ end
45
+
46
+ # Public: The MongoDB collection
47
+ #
48
+ # Returns the MongoDB collection
49
+ def collection
50
+ @collection ||= mongo.collection(Boom.config.attributes["mongodb"]["collection"])
51
+ end
52
+
53
+ # Public: Bootstrap
54
+ #
55
+ # Returns
56
+ def bootstrap
57
+ collection.insert("boom" => '{"lists": [{}]}') if collection.find_one.nil?
58
+ end
59
+
60
+ # Public: Populates the memory list from MongoDB
61
+ #
62
+ # Returns nothing
63
+ def populate
64
+ storage = MultiJson.decode(collection.find_one['boom']) || []
65
+
66
+ storage['lists'].each do |lists|
67
+ lists.each do |list_name, items|
68
+ @lists << list = List.new(list_name)
69
+
70
+ items.each do |item|
71
+ item.each do |name,value|
72
+ list.add_item(Item.new(name,value))
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ # Public: Save to MongoDB
80
+ #
81
+ # Returns Mongo ID
82
+ def save
83
+ doc = collection.find_one()
84
+ collection.update({"_id" => doc["_id"]}, {'boom' => to_json})
85
+ end
86
+
87
+ # Public: Convert to JSON
88
+ #
89
+ # Returns
90
+ def to_json
91
+ MultiJson.encode(to_hash)
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,79 @@
1
+ # coding: utf-8
2
+ #
3
+ # Sup, Redis.
4
+ #
5
+ begin
6
+ require 'digest'
7
+ require 'redis'
8
+ rescue LoadError
9
+ end
10
+
11
+ module Boom
12
+ module Storage
13
+ class Redis < Base
14
+ include Boom::Color
15
+ include Boom::Output
16
+
17
+ def self.sample_config
18
+ %(
19
+ {"backend": "redis",
20
+ "redis": {
21
+ "port": "6379",
22
+ "host": "<host>"
23
+ }
24
+ }
25
+ )
26
+ end
27
+
28
+ def redis
29
+ @redis ||= ::Redis.new :host => Boom.config.attributes["redis"]["host"],
30
+ :port => Boom.config.attributes["redis"]["port"]
31
+ rescue Exception => exception
32
+ handle exception, "You don't have Redis installed yet:\n gem install redis"
33
+ end
34
+
35
+ def bootstrap
36
+ end
37
+
38
+ def populate
39
+ lists = redis.smembers("boom:lists") || []
40
+
41
+ lists.each do |sha|
42
+ list_name = redis.get("boom:lists:#{sha}:name")
43
+ @lists << list = List.new(list_name)
44
+
45
+ shas = redis.lrange("boom:lists:#{sha}:items",0,-1) || []
46
+
47
+ shas.each do |item_sha|
48
+ name = redis.get "boom:items:#{item_sha}:name"
49
+ value = redis.get "boom:items:#{item_sha}:value"
50
+ list.add_item(Item.new(name, value))
51
+ end
52
+ end
53
+ end
54
+
55
+ def clear
56
+ redis.del "boom:lists"
57
+ redis.del "boom:items"
58
+ end
59
+
60
+ def save
61
+ clear
62
+
63
+ lists.each do |list|
64
+ list_sha = Digest::SHA1.hexdigest(list.name)
65
+ redis.set "boom:lists:#{list_sha}:name", list.name
66
+ redis.sadd "boom:lists", list_sha
67
+
68
+ list.items.each do |item|
69
+ item_sha = Digest::SHA1.hexdigest(item.name)
70
+ redis.rpush "boom:lists:#{list_sha}:items", item_sha
71
+ redis.set "boom:items:#{item_sha}:name", item.name
72
+ redis.set "boom:items:#{item_sha}:value", item.value
73
+ end
74
+ end
75
+
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,3 @@
1
+ {
2
+ backend: 'Json'
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "backend": "Json"
3
+ }
@@ -0,0 +1 @@
1
+ {"lists":[{"urls":[{"github":"https://github.com"},{"blog":"http://zachholman.com"}]}]}
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+
3
+ require 'test/unit'
4
+
5
+ begin
6
+ require 'rubygems'
7
+ require 'redgreen'
8
+ rescue LoadError
9
+ end
10
+
11
+ require 'mocha'
12
+
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
+
16
+ require 'kaboom'
17
+
18
+ def boom_json(name)
19
+ root = File.expand_path(File.dirname(__FILE__))
20
+ Boom::Storage::Json.any_instance.stubs(:save).returns(true)
21
+ Boom::Storage::Json.any_instance.stubs(:json_file).
22
+ returns("#{root}/examples/#{name}.json")
23
+ Boom.use_remote false
24
+ Boom.stubs(:storage).returns(Boom::Storage::Json.new)
25
+ end
@@ -0,0 +1,28 @@
1
+ module Boom
2
+ module Output
3
+
4
+ def capture_output
5
+ @output = ''
6
+ end
7
+
8
+ def captured_output
9
+ @output
10
+ end
11
+
12
+ def output(s)
13
+ @output << s
14
+ end
15
+
16
+ extend self
17
+ end
18
+ end
19
+
20
+ # Intercept STDOUT and collect it
21
+ class Boom::Command
22
+
23
+
24
+ def self.save!
25
+ # no-op
26
+ end
27
+
28
+ end
@@ -0,0 +1,30 @@
1
+ require 'helper'
2
+
3
+ class TestColor < Test::Unit::TestCase
4
+
5
+ def test_colorize
6
+ assert_equal "\e[35mBoom!\e[0m",
7
+ Boom::Color.colorize("Boom!", :magenta)
8
+ end
9
+
10
+ def test_magenta
11
+ assert_equal "\e[35mMagenta!\e[0m",
12
+ Boom::Color.magenta("Magenta!")
13
+ end
14
+
15
+ def test_red
16
+ assert_equal "\e[31mRed!\e[0m",
17
+ Boom::Color.red("Red!")
18
+ end
19
+
20
+ def test_yellow
21
+ assert_equal "\e[33mYellow!\e[0m",
22
+ Boom::Color.yellow("Yellow!")
23
+ end
24
+
25
+ def test_cyan
26
+ assert_equal "\e[36mCyan!\e[0m",
27
+ Boom::Color.cyan("Cyan!")
28
+ end
29
+
30
+ end
@@ -0,0 +1,227 @@
1
+ # coding: utf-8
2
+
3
+ require 'helper'
4
+ require 'output_interceptor'
5
+
6
+ class TestCommand < Test::Unit::TestCase
7
+
8
+ def setup
9
+ boom_json :urls
10
+ end
11
+
12
+ def command(cmd)
13
+ cmd = cmd.split(' ') if cmd
14
+ Boom::Command.capture_output
15
+ Boom::Command.execute(*cmd)
16
+ output = Boom::Command.captured_output
17
+ output.gsub(/\e\[\d\d?m/, '')
18
+ end
19
+
20
+ def test_use_remote
21
+ response = command('remote the_office fun awesome')
22
+
23
+ assert_match /a new list called the_office/, response
24
+ assert_match /fun in the_office is awesome/, response
25
+ end
26
+
27
+ def test_remote_checks_for_acceptable_config
28
+ response = command('remote the_office fun awesome')
29
+
30
+ assert_match /a new list called the_office/, response
31
+ assert_match /fun in the_office is awesome/, response
32
+ end
33
+
34
+ def test_overview_for_empty
35
+ storage = Boom::Storage
36
+ storage.stubs(:lists).returns([])
37
+ Boom::Command.stubs(:storage).returns(storage)
38
+ assert_match /have anything yet!/, command(nil)
39
+ end
40
+
41
+ def test_overview
42
+ assert_equal ' urls (2)', command(nil)
43
+ end
44
+
45
+ def test_list_detail
46
+ assert_match /github/, command('urls')
47
+ end
48
+
49
+ def test_list_all
50
+ cmd = command('all')
51
+ assert_match /urls/, cmd
52
+ assert_match /github/, cmd
53
+ end
54
+
55
+ def test_list_creation
56
+ assert_match /a new list called newlist/, command('newlist')
57
+ end
58
+
59
+ def test_list_creation_with_item
60
+ assert_match /a new list called newlist.* item in newlist/, command('newlist item blah')
61
+ end
62
+
63
+ def test_list_creation_with_item_stdin
64
+ STDIN.stubs(:read).returns('blah')
65
+ STDIN.stubs(:stat)
66
+ STDIN.stat.stubs(:size).returns(4)
67
+
68
+ assert_match /a new list called newlist.* item in newlist is blah/, command('newlist item')
69
+ end
70
+
71
+ def test_item_access
72
+ IO.stubs(:popen)
73
+ assert_match /copied https:\/\/github\.com to your clipboard/,
74
+ command('github')
75
+ end
76
+
77
+ def test_item_access_scoped_by_list
78
+ IO.stubs(:popen)
79
+ assert_match /copied https:\/\/github\.com to your clipboard/,
80
+ command('urls github')
81
+ end
82
+
83
+ def test_item_open_item
84
+ Boom::Platform.stubs(:system).returns('')
85
+ assert_match /opened https:\/\/github\.com for you/, command('open github')
86
+ end
87
+
88
+ def test_item_open_specific_item
89
+ Boom::Platform.stubs(:system).returns('')
90
+ assert_match /opened https:\/\/github\.com for you/, command('open urls github')
91
+ end
92
+
93
+ def test_item_open_lists
94
+ Boom::Platform.stubs(:system).returns('')
95
+ assert_match /opened all of urls for you/, command('open urls')
96
+ end
97
+
98
+ def test_item_creation
99
+ assert_match /twitter in urls/,
100
+ command('urls twitter http://twitter.com/holman')
101
+ end
102
+
103
+ def test_item_creation_long_value
104
+ assert_match /is tanqueray hendricks bombay/,
105
+ command('urls gins tanqueray hendricks bombay')
106
+ end
107
+
108
+ def test_list_deletion_no
109
+ STDIN.stubs(:gets).returns('n')
110
+ assert_match /Just kidding then/, command('urls delete')
111
+ end
112
+
113
+ def test_list_deletion_yes
114
+ STDIN.stubs(:gets).returns('y')
115
+ assert_match /Deleted all your urls/, command('urls delete')
116
+ end
117
+
118
+ def test_item_deletion
119
+ assert_match /github is gone forever/, command('urls github delete')
120
+ end
121
+
122
+ def test_edit
123
+ Boom::Platform.stubs(:system).returns('')
124
+ assert_match 'Make your edits', command('edit')
125
+ end
126
+
127
+ def test_help
128
+ assert_match 'boom help', command('help')
129
+ assert_match 'boom help', command('-h')
130
+ assert_match 'boom help', command('--help')
131
+ end
132
+
133
+ def test_noop_options
134
+ assert_match 'boom help', command('--anything')
135
+ assert_match 'boom help', command('-d')
136
+ end
137
+
138
+ def test_nonexistent_item_access_scoped_by_list
139
+ assert_match /twitter not found in urls/, command('urls twitter')
140
+ end
141
+
142
+ def test_echo_item
143
+ assert_match /https:\/\/github\.com/, command('echo github')
144
+ end
145
+
146
+ def test_echo_item_shorthand
147
+ assert_match /https:\/\/github\.com/, command('e github')
148
+ end
149
+
150
+ def test_echo_item_does_not_exist
151
+ assert_match /wrong not found/, command('echo wrong')
152
+ end
153
+
154
+ def test_echo_list_item
155
+ assert_match /https:\/\/github\.com/, command('echo urls github')
156
+ end
157
+
158
+ def test_echo_list_item_does_not_exist
159
+ assert_match /wrong not found in urls/, command('echo urls wrong')
160
+ end
161
+
162
+ def test_show_storage
163
+ Boom::Config.any_instance.stubs(:attributes).returns('backend' => 'json')
164
+ assert_match /You're currently using json/, command('storage')
165
+ end
166
+
167
+ def test_nonexistant_storage_switch
168
+ Boom::Config.any_instance.stubs(:save).returns(true)
169
+ assert_match /couldn't find that storage engine/, command('switch dkdkdk')
170
+ end
171
+
172
+ def test_storage_switch
173
+ Boom::Config.any_instance.stubs(:save).returns(true)
174
+ assert_match /We've switched you over to redis/, command('switch redis')
175
+ end
176
+
177
+ def test_version_switch
178
+ assert_match /#{Boom::VERSION}/, command('-v')
179
+ end
180
+
181
+ def test_version_long
182
+ assert_match /#{Boom::VERSION}/, command('--version')
183
+ end
184
+
185
+ def test_stdin_pipes
186
+ stub = Object.new
187
+ stub.stubs(:stat).returns([1,2])
188
+ stub.stubs(:read).returns("http://twitter.com")
189
+ Boom::Command.stubs(:stdin).returns(stub)
190
+ assert_match /twitter in urls/, command('urls twitter')
191
+ end
192
+
193
+ def test_random
194
+ Boom::Platform.stubs(:system).returns('')
195
+ assert_match /opened .+ for you/, command('random')
196
+ end
197
+
198
+ def test_random_from_list
199
+ Boom::Platform.stubs(:system).returns('')
200
+ assert_match /(github|zachholman)/, command('random urls')
201
+ end
202
+
203
+ def test_random_list_not_exist
204
+ Boom::Platform.stubs(:system).returns('')
205
+ assert_match /couldn't find that list\./, command('random 39jc02jlskjbbac9')
206
+ end
207
+
208
+ def test_delete_item_list_not_exist
209
+ assert_match /couldn't find that list\./, command('urlz github delete')
210
+ end
211
+
212
+ def test_delete_item_wrong_list
213
+ command('urlz twitter https://twitter.com/')
214
+ assert_match /github not found in urlz/, command('urlz github delete')
215
+ end
216
+
217
+ def test_delete_item_different_name
218
+ command('foo bar baz')
219
+ assert_match /bar is gone forever/, command('foo bar delete')
220
+ end
221
+
222
+ def test_delete_item_same_name
223
+ command('duck duck goose')
224
+ assert_match /duck is gone forever/, command('duck duck delete')
225
+ end
226
+
227
+ end