minglr 1.3.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.document +5 -0
  2. data/.gitignore +3 -0
  3. data/LICENSE +20 -0
  4. data/PostInstall.txt +1 -0
  5. data/README.rdoc +87 -0
  6. data/Rakefile +90 -0
  7. data/VERSION.yml +4 -0
  8. data/bin/minglr +29 -0
  9. data/bin/mtx +14 -0
  10. data/cucumber.yml +2 -0
  11. data/features/cards.feature +27 -0
  12. data/features/step_definitions/minglr_steps.rb +34 -0
  13. data/features/step_definitions/shared_steps.rb +69 -0
  14. data/features/users.feature +6 -0
  15. data/lib/minglr.rb +34 -0
  16. data/lib/minglr/action.rb +85 -0
  17. data/lib/minglr/config_parser.rb +51 -0
  18. data/lib/minglr/extensions/array.rb +23 -0
  19. data/lib/minglr/mtx/input_cache.rb +24 -0
  20. data/lib/minglr/mtx/options_parser.rb +58 -0
  21. data/lib/minglr/options_parser.rb +82 -0
  22. data/lib/minglr/resources/attachment.rb +51 -0
  23. data/lib/minglr/resources/base.rb +42 -0
  24. data/lib/minglr/resources/card.rb +117 -0
  25. data/lib/minglr/resources/project.rb +25 -0
  26. data/lib/minglr/resources/property_definition.rb +12 -0
  27. data/lib/minglr/resources/transition_execution.rb +6 -0
  28. data/lib/minglr/resources/user.rb +19 -0
  29. data/minglr.gemspec +120 -0
  30. data/minglrconfig.sample +37 -0
  31. data/tasks/commit.sample.rake +86 -0
  32. data/tasks/svn.sample.rake +27 -0
  33. data/test/action_test.rb +75 -0
  34. data/test/commands_test.rb +111 -0
  35. data/test/config_parser_test.rb +116 -0
  36. data/test/extensions/array_test.rb +41 -0
  37. data/test/options_parser_test.rb +74 -0
  38. data/test/resources/attachment_test.rb +90 -0
  39. data/test/resources/base_test.rb +58 -0
  40. data/test/resources/card_test.rb +199 -0
  41. data/test/resources/project_test.rb +44 -0
  42. data/test/resources/property_definition_test.rb +25 -0
  43. data/test/resources/user_test.rb +32 -0
  44. data/test/test_helper.rb +31 -0
  45. metadata +219 -0
@@ -0,0 +1,116 @@
1
+ require 'test_helper'
2
+
3
+ module Minglr
4
+
5
+ class ConfigParserTest < Test::Unit::TestCase
6
+
7
+ context "parse" do
8
+
9
+ should "look for a config file in the user home directory or the current working directory" do
10
+ File.expects(:exist?).with(File.join(ENV["HOME"], ".minglrconfig")).returns(true)
11
+ #File.expects(:exist?).with(File.expand_path(File.join(ENV["PWD"], ".minglrconfig"))).returns(false)
12
+ config_file_contents = ""
13
+ File.expects(:read).with(File.join(ENV["HOME"], ".minglrconfig")).returns(config_file_contents)
14
+
15
+ ConfigParser.parse
16
+ end
17
+
18
+ should "return the parsed configuration as a hash" do
19
+ configuration_content = <<-EOS
20
+ [foo]
21
+ myfoo = myvalue
22
+ [bar]
23
+ mybar = yourvalue
24
+ EOS
25
+
26
+ File.stubs(:exist?).returns(true)
27
+ File.expects(:read).returns(configuration_content)
28
+ parsed_configuration = ConfigParser.parse
29
+
30
+ assert_equal Hash, parsed_configuration.class
31
+ end
32
+
33
+ should "print a message if the config file cannot be found" do
34
+ File.expects(:exist?).times(2).returns(false)
35
+ ConfigParser.expects(:class_eval).with("send :exit, 1")
36
+ ConfigParser.expects(:puts)
37
+ ConfigParser.parse
38
+ end
39
+
40
+ end
41
+
42
+ context "initialize" do
43
+
44
+ should "parse the configuration file into sections and variables" do
45
+ configuration_content = <<-EOS
46
+ [foo]
47
+ myfoo = myvalue
48
+ [bar]
49
+ mybar = yourvalue
50
+ EOS
51
+
52
+ parsed_configuration = ConfigParser.new(configuration_content)
53
+ assert_equal true, parsed_configuration.config.has_key?(:foo)
54
+ assert_equal true, parsed_configuration.config.has_key?(:bar)
55
+ assert_equal true, parsed_configuration.config[:foo].has_key?(:myfoo)
56
+ assert_equal true, parsed_configuration.config[:bar].has_key?(:mybar)
57
+ assert_equal "myvalue", parsed_configuration.config[:foo][:myfoo]
58
+ assert_equal "yourvalue", parsed_configuration.config[:bar][:mybar]
59
+ end
60
+
61
+ should "skip comment lines" do
62
+ configuration_content = <<-EOS
63
+ # [foo]
64
+ # bar = bad
65
+ [foo]
66
+ bar = baz
67
+ EOS
68
+
69
+ parsed_configuration = ConfigParser.new(configuration_content)
70
+ assert_equal "baz", parsed_configuration.config[:foo][:bar]
71
+ end
72
+
73
+ should "skip blank lines" do
74
+ configuration_content = <<-EOS
75
+
76
+ [foo]
77
+
78
+ [babble]
79
+ bar = baz
80
+ EOS
81
+
82
+ parsed_configuration = ConfigParser.new(configuration_content)
83
+ assert_equal "baz", parsed_configuration.config[:babble][:bar]
84
+ end
85
+
86
+ should "not redefine a section if it has already been defined" do
87
+ configuration_content = <<-EOS
88
+ [foo]
89
+ bar = baz
90
+ should = bekept
91
+
92
+ [foo]
93
+ bar = somethingelse
94
+ EOS
95
+
96
+ parsed_configuration = ConfigParser.new(configuration_content)
97
+ assert_equal "somethingelse", parsed_configuration.config[:foo][:bar]
98
+ assert_equal "bekept", parsed_configuration.config[:foo][:should]
99
+ end
100
+
101
+ should "set a section variable to the latest value allowing it to be redefined" do
102
+ configuration_content = <<-EOS
103
+ [foo]
104
+ bar = baz
105
+ bar = somethingelse
106
+ EOS
107
+
108
+ parsed_configuration = ConfigParser.new(configuration_content)
109
+ assert_equal "somethingelse", parsed_configuration.config[:foo][:bar]
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+
116
+ end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ module Minglr
4
+ module Extensions
5
+
6
+ class ArrayTest < Test::Unit::TestCase
7
+
8
+ context Array do
9
+
10
+ context "filter" do
11
+
12
+ setup do
13
+ class TestObject
14
+ attr_accessor :name
15
+ end
16
+ @test1 = TestObject.new
17
+ @test2 = TestObject.new
18
+ @test1.name = "test1"
19
+ @test2.name = "test2"
20
+ @collection = [@test1, @test2]
21
+ @collection.send(:extend, Minglr::Extensions::Array)
22
+ end
23
+
24
+ should "include elements matching words in attributes" do
25
+ assert_equal [@test1], @collection.filter([:name], ["1"])
26
+ assert_equal [@test1, @test2], @collection.filter([:name], ["test"])
27
+ end
28
+
29
+ should "deal with empty words and attributes" do
30
+ assert_equal [@test1, @test2], @collection.filter([], [])
31
+ assert_equal [@test1, @test2], @collection.filter([:name], [])
32
+ assert_equal [], @collection.filter([], ["1"])
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,74 @@
1
+ require 'test_helper'
2
+
3
+ module Minglr
4
+
5
+ class OptionsParserTest < Test::Unit::TestCase
6
+
7
+ context "parse" do
8
+
9
+ should "gather all property definitions for a given project" do
10
+ Resources::Base.site = "http://foo.bar"
11
+ Resources::PropertyDefinition.expects(:project_options).returns([[:column_name, "Some Column Name"]])
12
+ OptionsParser.expects(:puts)
13
+ OptionsParser.parse(["--version"])
14
+ end
15
+
16
+ should "warn about authentication if property definition gathering fails" do
17
+ Resources::Base.site = "http://foo.bar"
18
+ Resources::PropertyDefinition.expects(:project_options).raises(ActiveResource::UnauthorizedAccess, stub(:code => "BadAccess"))
19
+ OptionsParser.expects(:puts).at_least(1)
20
+ OptionsParser.expects(:puts).with("Connection Failed with BadAccess to http://foo.bar")
21
+ OptionsParser.expects(:puts).with("Did you set 'basic_authentication_enabled: true' in your auth_config.yml file?")
22
+ OptionsParser.parse(["--version"])
23
+ end
24
+
25
+ should "parse name option" do
26
+ Resources::Base.site = "http://foo.bar"
27
+ Resources::PropertyDefinition.stubs(:project_options).returns([])
28
+ options = OptionsParser.parse(["-n", "MyName"])
29
+
30
+ assert_equal true, options.has_key?(:name)
31
+ assert_equal "MyName", options[:name]
32
+ end
33
+
34
+ should "parse description option" do
35
+ Resources::Base.site = "http://foo.bar"
36
+ Resources::PropertyDefinition.stubs(:project_options).returns([])
37
+ options = OptionsParser.parse(["-d", "MyDescription"])
38
+
39
+ assert_equal true, options.has_key?(:description)
40
+ assert_equal "MyDescription", options[:description]
41
+ end
42
+
43
+ should "parse type option" do
44
+ Resources::Base.site = "http://foo.bar"
45
+ Resources::PropertyDefinition.stubs(:project_options).returns([])
46
+ options = OptionsParser.parse(["-t MyType"])
47
+
48
+ assert_equal true, options.has_key?(:card_type_name)
49
+ assert_equal "MyType", options[:card_type_name]
50
+ end
51
+
52
+ should "parse comment option" do
53
+ Resources::Base.site = "http://foo.bar"
54
+ Resources::PropertyDefinition.stubs(:project_options).returns([])
55
+ options = OptionsParser.parse(["-c MyComment"])
56
+
57
+ assert_equal true, options.has_key?(:comment)
58
+ assert_equal "MyComment", options[:comment]
59
+ end
60
+
61
+ should "parse file option" do
62
+ Resources::Base.site = "http://foo.bar"
63
+ Resources::PropertyDefinition.stubs(:project_options).returns([])
64
+ options = OptionsParser.parse(["-f MyFile"])
65
+
66
+ assert_equal true, options.has_key?(:file_attachment)
67
+ assert_equal "MyFile", options[:file_attachment]
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+ end
@@ -0,0 +1,90 @@
1
+ require 'test_helper'
2
+
3
+ module Resources
4
+
5
+ class AttachmentTest < Test::Unit::TestCase
6
+
7
+ context Attachment do
8
+
9
+ context "configure" do
10
+
11
+ should "append to the site url" do
12
+ options = { :username => "user",
13
+ :password => "pass",
14
+ :url => "proto://somehost.com:1234/projects/my_project" }
15
+ Base.configure(options)
16
+ Attachment.configure
17
+ assert_equal "/projects/my_project/cards/1/", Attachment.prefix(:card_number => 1)
18
+ end
19
+
20
+ end
21
+
22
+ context "fetch" do
23
+
24
+ should "download all found attachments for a given card number" do
25
+ card = Card.new
26
+ card.stubs(:number).returns(1)
27
+
28
+ attachment1 = Attachment.new
29
+ attachment1.stubs(:url).returns("http://attachment1.url")
30
+ attachment1.stubs(:file_name).returns("attachment1.txt")
31
+ attachment2 = Attachment.new
32
+ attachment2.stubs(:url).returns("http://attachment2.url")
33
+ attachment2.stubs(:file_name).returns("attachment2.txt")
34
+
35
+ Attachment.stubs(:puts)
36
+ Card.expects(:find).with(1).returns(card)
37
+ Attachment.expects(:find).with(:all, :params => { :card_number => 1 }).returns([attachment1, attachment2])
38
+ Attachment.expects(:curl).with("curl --insecure --progress-bar --output attachment1.txt --user username:password http://attachment1.url")
39
+ Attachment.expects(:curl).with("curl --insecure --progress-bar --output attachment2.txt --user username:password http://attachment2.url")
40
+
41
+ Attachment.fetch(1, "username", "password")
42
+ end
43
+
44
+ end
45
+
46
+ context "attach" do
47
+
48
+ setup do
49
+ options = { :username => "user",
50
+ :password => "pass",
51
+ :url => "proto://somehost.com:1234/projects/my_project" }
52
+ Base.configure(options)
53
+ end
54
+
55
+ should "upload file for a given card number" do
56
+ file_name = File.join(File.dirname(__FILE__), "..", "..", "Rakefile")
57
+
58
+ card = Card.new
59
+ card.stubs(:number).returns(1)
60
+
61
+ fake_response = stub("Response", :status_code => 201)
62
+ fake_client = mock("HTTPClient")
63
+ fake_client.expects(:post).returns(fake_response)
64
+ fake_client.expects(:set_auth).with(nil, "username", "password")
65
+
66
+ Card.expects(:find).with(1).returns(card)
67
+ HTTPClient.expects(:new).returns(fake_client)
68
+ Attachment.expects(:puts).with("File '#{file_name}' attached to card 1")
69
+
70
+ Attachment.attach(1, file_name, "username", "password")
71
+ end
72
+
73
+ should "warn for invalid file" do
74
+ card = Card.new
75
+ card.stubs(:number).returns(1)
76
+
77
+ Card.expects(:find).with(1).returns(card)
78
+ File.expects(:exist?).with("myfile.txt").returns(false)
79
+ Attachment.expects(:warn).with("Unable to open file 'myfile.txt'")
80
+
81
+ Attachment.attach(1, "myfile.txt", "username", "password")
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+
3
+ module Resources
4
+
5
+ class BaseTest < Test::Unit::TestCase
6
+
7
+ context Base do
8
+
9
+ context "configure" do
10
+
11
+ should "combine options to build url" do
12
+ options = { :username => "user",
13
+ :password => "pass",
14
+ :url => "proto://somehost.com:1234/projects/my_project" }
15
+ Base.configure(options)
16
+ assert_equal "proto://user:pass@somehost.com:1234/projects/my_project",
17
+ Base.site.to_s
18
+ end
19
+
20
+ end
21
+
22
+ context "warn" do
23
+
24
+ should "prepend message with warning" do
25
+ Base.expects(:puts).with("Warning: test")
26
+ Base.warn("test")
27
+ end
28
+
29
+ end
30
+
31
+ context "print_collection" do
32
+
33
+ setup do
34
+ @object1 = stub("Object", :name => "Foo", :description => "Bar")
35
+ @object2 = stub("Object", :name => "Bar", :description => "Frobble")
36
+ @collection = [@object1, @object2]
37
+ @attributes = [:name, :description]
38
+ end
39
+
40
+ should "print values of attributes of objects separated by dashes and aligning columns of values" do
41
+ Base.expects(:puts).with("Foo - Bar ")
42
+ Base.expects(:puts).with("Bar - Frobble")
43
+ Base.print_collection(@collection, @attributes)
44
+ end
45
+
46
+ should "allow for right adjusted values" do
47
+ Base.expects(:puts).with("Foo - Bar")
48
+ Base.expects(:puts).with("Bar - Frobble")
49
+ Base.print_collection(@collection, @attributes, :right)
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,199 @@
1
+ require 'test_helper'
2
+
3
+ module Resources
4
+
5
+ class CardTest < Test::Unit::TestCase
6
+
7
+ context Card do
8
+
9
+ context "create" do
10
+
11
+ should "create a card with options passed in" do
12
+ card = Card.new
13
+ card.stubs(:number).returns(1)
14
+ Card.expects(:new).with(:name => "Name").returns(card)
15
+ Card.any_instance.expects(:save).returns(true)
16
+ Card.any_instance.expects(:reload)
17
+ Card.expects(:puts).with("Card #1 created")
18
+ Card.create({:name => "Name"})
19
+ end
20
+
21
+ should "create a card with the status of new if status property is available" do
22
+ card = Card.new
23
+ card.stubs(:number).returns(1)
24
+ Card.expects(:new).with(:some_option => "value", :cp_status => "New").returns(card)
25
+ Card.any_instance.expects(:save).returns(true)
26
+ Card.any_instance.expects(:reload)
27
+ Card.expects(:puts).with("Card #1 created")
28
+ Card.create({:some_option => "value"}, "cp_status")
29
+ end
30
+
31
+ should "warn if it is unable to create the card" do
32
+ Card.any_instance.expects(:save).returns(false)
33
+ Card.expects(:warn).with("Unable to create card")
34
+ Card.create
35
+ end
36
+
37
+ end
38
+
39
+ context "move" do
40
+
41
+ should "move card from one state to the next as defined" do
42
+ card = Card.new
43
+ card.stubs(:card_type_name).returns("story")
44
+ card.stubs(:status).returns("New")
45
+ config = { :story_state_1 => "New > Dev", :status_property => "status"}
46
+ response = stub("Response", :attributes => { "status" => "completed" })
47
+
48
+ Card.expects(:find).with(1).returns(card)
49
+ TransitionExecution.expects(:create).with(:transition => 'Dev', :card => 1).returns(response)
50
+ Card.expects(:puts).with("Moved card from New to Dev")
51
+ Card.move(1, {}, config)
52
+ end
53
+
54
+ should "warn if no matching card type is found" do
55
+ card = Card.new
56
+ card.stubs(:card_type_name).returns("someothertype")
57
+ card.stubs(:status).returns("New")
58
+ config = { :story_state_1 => "New > Dev", :status_property => "status"}
59
+
60
+ Card.expects(:find).with(1).returns(card)
61
+ Card.expects(:warn).with("No transitions defined for card of type someothertype")
62
+ Card.move(1, {}, config)
63
+ end
64
+
65
+ should "warn if card has no status property" do
66
+ card = Card.new
67
+ card.stubs(:card_type_name).returns("story")
68
+ card.stubs(:current_status).returns("New")
69
+ config = { :story_state_1 => "New > Dev"}
70
+
71
+ Card.expects(:find).with(1).returns(card)
72
+ Card.expects(:warn).with("No known status of card #1, cannot move!")
73
+ Card.move(1, {}, config)
74
+ end
75
+
76
+ should "warn if card cannot be found" do
77
+ Card.expects(:find).with(0).returns(nil)
78
+ Card.expects(:warn).with("No card #0 found to move")
79
+ Card.move(0)
80
+ end
81
+
82
+ end
83
+
84
+ context "print_all" do
85
+
86
+ should "warn if there are no cards" do
87
+ Card.expects(:find).with(:all).returns([])
88
+ Card.expects(:warn).with("No cards found")
89
+ Card.print_all
90
+ end
91
+
92
+ should "print the cards found with format" do
93
+ card1 = stub("Card", :number => 1, :card_type_name => "Story", :name => "Some Story")
94
+ card2 = stub("Card", :number => 2, :card_type_name => "Task", :name => "Some Task")
95
+ Card.expects(:find).with(:all).returns([card1, card2])
96
+ Card.expects(:puts).with("1 - Story - Some Story")
97
+ Card.expects(:puts).with("2 - Task - Some Task ")
98
+ Card.print_all
99
+ end
100
+
101
+ should "print cards with status property if available" do
102
+ card1 = stub("Card", :number => 1, :card_type_name => "Story", :name => "Some Story", :cp_status => "Ready")
103
+ Card.expects(:find).with(:all).returns([card1])
104
+ Card.expects(:puts).with("1 - Story - Ready - Some Story")
105
+ Card.print_all([], "cp_status")
106
+ end
107
+
108
+ end
109
+
110
+ context "print_card" do
111
+
112
+ should "print the details for a given card" do
113
+ status_property = "cp_status"
114
+ card = Card.new
115
+ card.expects(:to_s).with(status_property)
116
+ Card.expects(:find).with(1).returns(card)
117
+ Card.stubs(:puts)
118
+ Card.print_card(1, status_property)
119
+ end
120
+
121
+ should "warn if it is not able to find the card" do
122
+ Card.expects(:find).with(0).returns(nil)
123
+ Card.expects(:warn).with("No card #0 found")
124
+ Card.print_card(0)
125
+ end
126
+
127
+ end
128
+
129
+ context "update" do
130
+
131
+ should "update a card with the options passed in" do
132
+ card = mock("Card")
133
+ card.stubs(:number).returns(1)
134
+ card.expects(:foo=).with("bar")
135
+ card.expects(:baz=).with("frobble")
136
+ card.expects(:save)
137
+ Card.stubs(:puts)
138
+ Card.expects(:find).with(1).returns(card)
139
+
140
+ Card.update(1, {:foo => "bar", :baz => "frobble"})
141
+ end
142
+
143
+ should "print out the details of the card after updating" do
144
+ card = mock("Card")
145
+ card.stubs(:number).returns(1)
146
+ card.stubs(:foo=)
147
+ card.stubs(:baz=)
148
+ card.stubs(:save)
149
+ Card.stubs(:find).with(1).returns(card)
150
+
151
+ Card.expects(:puts).with("Card #1 updated\n\n")
152
+ Card.expects(:puts).with(card.to_s)
153
+ Card.update(1, {:foo => "bar", :baz => "frobble"})
154
+ end
155
+
156
+ should "warn if it is not able to find the card" do
157
+ Card.expects(:find).with(0).returns(nil)
158
+ Card.expects(:warn).with("Unable to update card #0")
159
+ Card.update(0)
160
+ end
161
+
162
+ end
163
+
164
+ context "to_s" do
165
+
166
+ should "format the details of a given card including attachments" do
167
+ Resources::Base.site = "http://foo.bar"
168
+
169
+ attachment = Attachment.new
170
+ attachment.stubs(:file_name).returns("My File Name")
171
+ attachment.stubs(:url).returns("http://some.url")
172
+ Attachment.expects(:find).with(:all, :params => { :card_number => 1 }).returns([attachment])
173
+
174
+ card = Card.new
175
+ card.stubs(:number).returns(1)
176
+ card.stubs(:name).returns("My Name")
177
+ card.stubs(:card_type_name).returns("My Type")
178
+ card.stubs(:description).returns("My Description")
179
+
180
+ expected_output = <<-EOS
181
+ Number: 1
182
+ Name: My Name
183
+ Type: My Type
184
+ Status:
185
+ Description: My Description
186
+
187
+ Attachments:
188
+ * My File Name: http://some.url
189
+ EOS
190
+ assert_equal expected_output, card.to_s
191
+ end
192
+
193
+ end
194
+
195
+ end
196
+
197
+ end
198
+
199
+ end