mingle-macro-development-toolkit 1.3.2 → 1.3.3
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.
- data/History.txt +8 -0
- data/{README.rdoc → README.txt} +8 -6
- data/Rakefile +19 -27
- data/bin/new_mingle_macro +10 -4
- data/example/integration_test_helper.rb +5 -5
- data/example/unit_test_helper.rb +4 -13
- data/lib/macro_development_toolkit.rb +1 -1
- data/lib/macro_development_toolkit/mingle/project.rb +4 -4
- data/lib/macro_development_toolkit/mingle_model_loader.rb +100 -136
- data/test/fixtures/sample/card_types.yml +9 -1
- data/test/fixtures/sample/project_variables.yml +3 -1
- data/test/fixtures/sample/property_definitions.yml +13 -3
- data/test/integration/integration_test_helper.rb +20 -8
- data/test/integration/rest_loader.rb +172 -250
- data/test/unit/fixture_loader.rb +73 -145
- data/test/unit/fixture_loader_test.rb +11 -11
- data/test/unit/unit_test_helper.rb +6 -5
- metadata +29 -15
@@ -3,27 +3,35 @@
|
|
3
3
|
position: 3
|
4
4
|
color: 'ff3300'
|
5
5
|
id: 339
|
6
|
+
project_id: 78
|
6
7
|
- name: Defect
|
7
8
|
position: 5
|
8
9
|
color: '000599'
|
9
10
|
id: 340
|
11
|
+
project_id: 78
|
10
12
|
- name: Task
|
11
13
|
position: 4
|
12
14
|
color: 'ffe066'
|
13
15
|
id: 341
|
16
|
+
project_id: 78
|
14
17
|
- name: Sprint
|
15
18
|
position: 2
|
16
19
|
color: 'ff0db6'
|
17
20
|
id: 342
|
21
|
+
project_id: 78
|
18
22
|
- name: Release
|
19
23
|
position: 1
|
20
24
|
color: '990024'
|
21
25
|
id: 343
|
26
|
+
project_id: 78
|
22
27
|
- name: Feature
|
23
28
|
position: 6
|
24
29
|
color: '296600'
|
25
30
|
id: 344
|
31
|
+
project_id: 78
|
26
32
|
- name: Epic Story
|
27
33
|
position: 7
|
28
34
|
color: '00d91d'
|
29
|
-
id: 345
|
35
|
+
id: 345
|
36
|
+
project_id: 78
|
37
|
+
|
@@ -3,39 +3,49 @@
|
|
3
3
|
name: Status
|
4
4
|
description: ""
|
5
5
|
type_description: Managed text list
|
6
|
+
project_id: 78
|
6
7
|
- id: 1141
|
7
8
|
name: Priority
|
8
9
|
description: ""
|
9
10
|
type_description: Managed text list
|
11
|
+
project_id: 78
|
10
12
|
- id: 1142
|
11
13
|
name: Development Started On
|
12
14
|
description: ""
|
13
15
|
type_description: Managed text list
|
16
|
+
project_id: 78
|
14
17
|
- id: 1143
|
15
18
|
description: ""
|
16
19
|
name: Development Completed On
|
17
20
|
type_description: Date
|
21
|
+
project_id: 78
|
18
22
|
- id: 1144
|
19
23
|
description: ""
|
20
24
|
name: Added On
|
21
25
|
type_description: Date
|
26
|
+
project_id: 78
|
22
27
|
- id: 1145
|
23
28
|
description: ""
|
24
29
|
name: Estimate - Planning
|
25
|
-
type_description: Formula
|
30
|
+
type_description: Formula
|
31
|
+
project_id: 78
|
26
32
|
- id: 1146
|
27
33
|
description: ""
|
28
34
|
name: Risk
|
29
|
-
type_description: Managed text list
|
35
|
+
type_description: Managed text list
|
36
|
+
project_id: 78
|
30
37
|
- id: 1147
|
31
38
|
description: ""
|
32
39
|
name: Task Estimate
|
33
40
|
type_description: Managed text list
|
41
|
+
project_id: 78
|
34
42
|
- id: 1148
|
35
43
|
description:
|
36
44
|
name: Estimate - Task
|
37
45
|
type_description: Managed text list
|
46
|
+
project_id: 78
|
38
47
|
- id: 1149
|
39
48
|
description: Individual assigned to a work item
|
40
49
|
name: Owner
|
41
|
-
type_description: User
|
50
|
+
type_description: User
|
51
|
+
project_id: 78
|
@@ -2,20 +2,32 @@
|
|
2
2
|
|
3
3
|
require 'delegate'
|
4
4
|
require 'test/unit'
|
5
|
+
require 'net/http'
|
5
6
|
require 'macro_development_toolkit'
|
6
7
|
require File.dirname(__FILE__) + '/rest_loader'
|
7
8
|
|
8
9
|
class Test::Unit::TestCase
|
9
|
-
|
10
|
-
def project(
|
11
|
-
@
|
12
|
-
|
13
|
-
|
10
|
+
|
11
|
+
def project(resource)
|
12
|
+
@projects ||= {}
|
13
|
+
@projects[resource] ||= load_project_resource(resource)
|
14
|
+
end
|
15
|
+
|
16
|
+
def projects(*resources)
|
17
|
+
resources.collect {|resource| project(resource)}
|
18
|
+
end
|
19
|
+
|
14
20
|
def errors
|
15
21
|
@errors ||= []
|
16
|
-
end
|
22
|
+
end
|
17
23
|
|
18
24
|
def alert(message)
|
19
25
|
errors << message
|
20
|
-
end
|
21
|
-
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def load_project_resource(resource)
|
31
|
+
RESTfulLoaders::ProjectLoader.new(resource, self).project
|
32
|
+
end
|
33
|
+
end
|
@@ -1,311 +1,233 @@
|
|
1
1
|
#Copyright 2010 ThoughtWorks, Inc. All rights reserved.
|
2
2
|
|
3
3
|
module RESTfulLoaders
|
4
|
+
|
4
5
|
class RemoteError < StandardError
|
5
6
|
def self.parse(response_body)
|
6
7
|
Hash.from_xml(response_body)['errors'].delete("error")
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class Base
|
11
|
-
def initialize(project_name)
|
12
|
-
@xml_model = if (String === project_name)
|
13
|
-
@project_name = project_name
|
14
|
-
OpenStruct.new(Hash.from_xml(get(project_name)))
|
15
|
-
else
|
16
|
-
project_name
|
17
|
-
end
|
18
|
-
raise "No such project resource available! #{@project_name}" unless (@xml_model && @xml_model.to_s != '')
|
19
8
|
end
|
9
|
+
end
|
20
10
|
|
21
|
-
|
22
|
-
|
11
|
+
module LoaderHelper
|
12
|
+
|
13
|
+
def extract(key, container)
|
14
|
+
container[key] ? container[key][key.singularize] : []
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(resource)
|
18
|
+
url = URI.parse(resource)
|
23
19
|
get_request = Net::HTTP::Get.new(url.request_uri)
|
24
20
|
get_request.basic_auth(url.user, url.password)
|
25
21
|
response = Net::HTTP.start(url.host, url.port) { |http| http.request(get_request) }
|
26
|
-
if response.code.to_s != "200"
|
22
|
+
if response.code.to_s != "200"
|
27
23
|
raise RemoteError, RemoteError.parse(response.body)
|
28
24
|
end
|
29
|
-
response.body
|
30
|
-
end
|
31
|
-
|
32
|
-
def load_all_card_types_from_xml
|
33
|
-
extract_array_of 'card_types', :from => @xml_model.project
|
34
|
-
end
|
35
|
-
|
36
|
-
def load_all_property_definitions_from_xml
|
37
|
-
extract_array_of 'property_definitions', :from => @xml_model.project
|
38
|
-
end
|
39
|
-
|
40
|
-
def load_all_card_types_property_definitions_from_xml
|
41
|
-
load_all_card_types_from_xml.collect do |card_type_xml|
|
42
|
-
card_types_property_definitions = OpenStruct.new(card_type_xml).card_types_property_definitions
|
43
|
-
[card_types_property_definitions['card_type_property_definition']].flatten if card_types_property_definitions
|
44
|
-
end.compact.flatten.compact
|
45
|
-
end
|
46
|
-
|
47
|
-
def card_types_property_definitions_by_card_type_id_loader(card_type_id)
|
48
|
-
LoadCardTypesPropertyDefinitionsByCardTypeId.new(card_type_id, @xml_model)
|
49
|
-
end
|
50
|
-
|
51
|
-
def card_types_property_definitions_by_property_definition_id_loader(property_definition_id)
|
52
|
-
LoadCardTypesPropertyDefinitionsByPropertyDefinitionId.new(property_definition_id, @xml_model)
|
25
|
+
Hash.from_xml(response.body)
|
53
26
|
end
|
27
|
+
end
|
54
28
|
|
55
|
-
|
56
|
-
|
57
|
-
end
|
29
|
+
class MqlExecutor < SimpleDelegator
|
30
|
+
include LoaderHelper
|
58
31
|
|
59
|
-
def
|
60
|
-
|
32
|
+
def initialize(resource, error_handler, delegator)
|
33
|
+
super(delegator)
|
34
|
+
@uri = URI.parse(resource)
|
35
|
+
@error_handler = error_handler
|
36
|
+
@version = /(\/api\/([^\/]*))\//.match(@uri.request_uri)[2]
|
61
37
|
end
|
62
|
-
|
63
|
-
def property_definition_by_id_loader(property_definition_id)
|
64
|
-
LoadPropertyDefinitionById.new(property_definition_id, @xml_model)
|
65
|
-
end
|
66
|
-
|
67
|
-
def card_types_by_project_id_loader
|
68
|
-
LoadCardTypesByProjectId.new(@xml_model)
|
69
|
-
end
|
70
38
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
39
|
+
def execute_mql(mql)
|
40
|
+
from_xml_data(get(url_for(:action => "execute_mql", :query => "mql=#{mql}")))
|
41
|
+
rescue => e
|
42
|
+
@error_handler.alert(e.message)
|
43
|
+
[]
|
44
|
+
end
|
74
45
|
|
75
|
-
def
|
76
|
-
|
46
|
+
def can_be_cached?(mql)
|
47
|
+
from_xml_data(get(url_for(:action => "can_be_cached", :query => "mql=#{mql}")))
|
48
|
+
rescue => e
|
49
|
+
@error_handler.alert(e.message)
|
50
|
+
[]
|
77
51
|
end
|
78
52
|
|
79
|
-
def
|
80
|
-
|
53
|
+
def format_number_with_project_precision(number)
|
54
|
+
from_xml_data(get(url_for(:action => "format_number_to_project_precision", :query => "number=#{number}")))
|
55
|
+
rescue => e
|
56
|
+
@error_handler.alert(e.message)
|
57
|
+
[]
|
81
58
|
end
|
82
59
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
60
|
+
def format_date_with_project_date_format(date)
|
61
|
+
from_xml_data(get(url_for(:action => "format_string_to_date_format", :query => "date=#{date}")))
|
62
|
+
rescue => e
|
63
|
+
@error_handler.alert(e.message)
|
64
|
+
[]
|
65
|
+
end
|
89
66
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
__getobj__.send(:add_alert, e.message)
|
101
|
-
[]
|
102
|
-
end
|
103
|
-
|
104
|
-
def can_be_cached?(mql)
|
105
|
-
@mql_executor.can_be_cached?(mql, self)
|
106
|
-
rescue => e
|
107
|
-
__getobj__.send(:add_alert, e.message)
|
108
|
-
[]
|
109
|
-
end
|
110
|
-
|
111
|
-
def format_number_with_project_precision(number)
|
112
|
-
@mql_executor.format_number_with_project_precision(number, self)
|
113
|
-
rescue => e
|
114
|
-
__getobj__.send(:add_alert, e.message)
|
115
|
-
end
|
116
|
-
|
117
|
-
def format_date_with_project_date_format(date)
|
118
|
-
@mql_executor.format_date_with_project_date_format(date, self)
|
119
|
-
rescue => e
|
120
|
-
__getobj__.send(:add_alert, e.message)
|
67
|
+
def url_for(params)
|
68
|
+
relative_path = URI.escape("/api/#{@version}/projects/#{identifier}/cards/#{params[:action]}.xml?#{params[:query]}")
|
69
|
+
@uri.merge(relative_path).to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
def from_xml_data(data)
|
73
|
+
if data.is_a?(Hash) && data.keys.size == 1
|
74
|
+
from_xml_data(data.values.first)
|
75
|
+
else
|
76
|
+
data
|
121
77
|
end
|
122
|
-
end
|
78
|
+
end
|
79
|
+
end
|
123
80
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
@
|
129
|
-
@
|
81
|
+
class ProjectLoader
|
82
|
+
include LoaderHelper
|
83
|
+
|
84
|
+
def initialize(resource, error_handler)
|
85
|
+
@resource = resource
|
86
|
+
@error_handler = error_handler
|
130
87
|
end
|
131
|
-
|
132
|
-
def load_project_from_xml
|
133
|
-
@xml_model.project
|
134
|
-
end
|
135
88
|
|
136
89
|
def project
|
137
|
-
project
|
138
|
-
project.card_types_loader = card_types_by_project_id_loader
|
139
|
-
project.property_definitions_loader = property_definitions_by_project_id_loader
|
140
|
-
project.team_loader = team_by_project_id_loader
|
141
|
-
project.project_variables_loader = project_variables_by_project_id_loader
|
142
|
-
project
|
90
|
+
@project ||= load
|
143
91
|
end
|
144
92
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
93
|
+
private
|
94
|
+
|
95
|
+
def load
|
96
|
+
proj = OpenStruct.new(get(@resource)).project
|
97
|
+
project = MqlExecutor.new(@resource, @error_handler, Mingle::Project.new(OpenStruct.new(proj), nil))
|
98
|
+
project.card_types_loader = CardTypesLoader.new(proj)
|
99
|
+
project.property_definitions_loader = PropertyDefinitionsLoader.new(proj)
|
100
|
+
project.team_loader = TeamLoader.new(proj)
|
101
|
+
project.project_variables_loader = ProjectVariablesLoader.new(proj)
|
102
|
+
project
|
150
103
|
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
class CardTypesLoader
|
108
|
+
include LoaderHelper
|
151
109
|
|
152
|
-
def
|
153
|
-
|
154
|
-
Hash.from_xml(
|
155
|
-
get(
|
156
|
-
build_request_url(:path => url_for("can_be_cached"), :query => "mql=#{mql}"))))
|
110
|
+
def initialize(project)
|
111
|
+
@project = project
|
157
112
|
end
|
158
113
|
|
159
|
-
def
|
160
|
-
|
161
|
-
Hash.from_xml(
|
162
|
-
get(
|
163
|
-
build_request_url(:path => url_for("format_number_to_project_precision"), :query => "number=#{number}"))))
|
114
|
+
def load
|
115
|
+
extract('card_types', @project).collect { |ct| CardTypeLoader.new(@project, ct) }.sort_by { |loader| loader.card_type.position }
|
164
116
|
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class CardTypeLoader
|
165
120
|
|
166
|
-
def
|
167
|
-
|
168
|
-
|
169
|
-
get(
|
170
|
-
build_request_url(:path => url_for("format_string_to_date_format"), :query => "date=#{date}"))))
|
121
|
+
def initialize(project, ct)
|
122
|
+
@project = project
|
123
|
+
@ct = ct
|
171
124
|
end
|
172
125
|
|
173
|
-
def
|
174
|
-
|
126
|
+
def card_type
|
127
|
+
@card_type ||= load
|
175
128
|
end
|
176
129
|
|
177
|
-
def build_request_url(params)
|
178
|
-
url = URI.parse(@project_name)
|
179
|
-
request_class = if url.scheme == 'http'
|
180
|
-
URI::HTTP
|
181
|
-
elsif
|
182
|
-
URI::HTTPS
|
183
|
-
else
|
184
|
-
raise "Unknown protocol used to access project resource #{@project_name}. Supported protocols are HTTP & HTTPS"
|
185
|
-
end
|
186
|
-
default_params = {:userinfo => "#{url.user}:#{url.password}", :host => url.host, :port => url.port.to_s}
|
187
|
-
request_class.build2(default_params.merge(params))
|
188
|
-
end
|
189
|
-
|
190
|
-
def from_xml_data(data)
|
191
|
-
if data.is_a?(Hash) && data.keys.size == 1
|
192
|
-
from_xml_data(data.values.first)
|
193
|
-
else
|
194
|
-
data
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
class LoadCardTypesByProjectId < Base
|
200
130
|
def load
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
end.sort_by(&:position)
|
206
|
-
end
|
131
|
+
card_type = Mingle::CardType.new(OpenStruct.new(@ct))
|
132
|
+
card_type.card_types_property_definitions_loader = CardTypesPropertyDefinitionsLoader.new(@project, 'card_type_id' => @ct['id'])
|
133
|
+
card_type
|
134
|
+
end
|
207
135
|
end
|
208
136
|
|
209
|
-
class
|
137
|
+
class PropertyDefinitionsLoader
|
138
|
+
include LoaderHelper
|
139
|
+
|
140
|
+
def initialize(project)
|
141
|
+
@project = project
|
142
|
+
end
|
143
|
+
|
210
144
|
def load
|
211
|
-
|
212
|
-
|
213
|
-
property_definition.card_types_property_definitions_loader = card_types_property_definitions_by_property_definition_id_loader(pd['id'])
|
214
|
-
property_definition.values_loader = values_by_property_definition_id_loader(pd['id'])
|
215
|
-
property_definition
|
216
|
-
end
|
217
|
-
end
|
145
|
+
extract('property_definitions', @project).collect { |pd| PropertyDefinitionLoader.new(@project, pd) }
|
146
|
+
end
|
218
147
|
end
|
219
|
-
|
220
|
-
class LoadCardTypesPropertyDefinitionsByCardTypeId < Base
|
221
|
-
def initialize(card_type_id, fixture_file_name)
|
222
|
-
super(fixture_file_name)
|
223
|
-
@card_type_id = card_type_id
|
224
|
-
end
|
225
148
|
|
149
|
+
class PropertyDefinitionLoader
|
150
|
+
def initialize(project, pd)
|
151
|
+
@project = project
|
152
|
+
@pd = pd
|
153
|
+
end
|
154
|
+
|
155
|
+
def property_definition
|
156
|
+
@property_definition ||= load
|
157
|
+
end
|
158
|
+
|
226
159
|
def load
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
card_type_property_definition
|
233
|
-
end.compact.sort_by(&:position).compact
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
class LoadCardTypesPropertyDefinitionsByPropertyDefinitionId < Base
|
238
|
-
def initialize(property_definition_id, fixture_file_name)
|
239
|
-
super(fixture_file_name)
|
240
|
-
@property_definition_id = property_definition_id
|
241
|
-
end
|
242
|
-
|
243
|
-
def load
|
244
|
-
load_all_card_types_property_definitions_from_xml.collect do |ctpd|
|
245
|
-
next unless ctpd['property_definition_id'] == @property_definition_id
|
246
|
-
card_type_property_definition = Mingle::CardTypePropertyDefinition.new(OpenStruct.new(ctpd))
|
247
|
-
card_type_property_definition.card_type_loader = card_type_by_id_loader(ctpd['card_type_id'])
|
248
|
-
card_type_property_definition.property_definition_loader = property_definition_by_id_loader(ctpd['property_definition_id'])
|
249
|
-
card_type_property_definition
|
250
|
-
end.compact.sort_by(&:position).compact
|
251
|
-
end
|
160
|
+
@property_definition = Mingle::PropertyDefinition.new(OpenStruct.new(@pd))
|
161
|
+
@property_definition.card_types_property_definitions_loader = CardTypesPropertyDefinitionsLoader.new(@project, 'property_definition_id' => @pd['id'])
|
162
|
+
@property_definition.values_loader = PropertyValuesLoader.new(@pd)
|
163
|
+
@property_definition
|
164
|
+
end
|
252
165
|
end
|
253
|
-
|
254
|
-
class
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
def load
|
261
|
-
yaml = load_all_card_types_from_xml.detect { |ct| ct['id'] == @card_type_id }
|
262
|
-
ct = Mingle::CardType.new(OpenStruct.new(yaml))
|
263
|
-
ct.card_types_property_definitions_loader = card_types_property_definitions_by_card_type_id_loader(yaml['id'])
|
264
|
-
ct
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
class LoadPropertyDefinitionById < Base
|
269
|
-
def initialize(property_definition_id, fixture_file_name)
|
270
|
-
super(fixture_file_name)
|
271
|
-
@property_definition_id = property_definition_id
|
166
|
+
|
167
|
+
class PropertyValuesLoader
|
168
|
+
include LoaderHelper
|
169
|
+
|
170
|
+
def initialize(property_definition)
|
171
|
+
@property_definition = property_definition
|
272
172
|
end
|
273
|
-
|
173
|
+
|
274
174
|
def load
|
275
|
-
|
276
|
-
pd = Mingle::PropertyDefinition.new(OpenStruct.new(yaml))
|
277
|
-
pd.card_types_property_definitions_loader = card_types_property_definitions_by_property_definition_id_loader(yaml['id'])
|
278
|
-
pd.values_loader = values_by_property_definition_id_loader(yaml['id'])
|
279
|
-
pd
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
class LoadValuesByPropertyDefinitionId < Base
|
284
|
-
def initialize(property_definition_id, fixture_file_name)
|
285
|
-
super(fixture_file_name)
|
286
|
-
@property_definition_id = property_definition_id
|
175
|
+
extract('values', @property_definition).collect {|value| Mingle::PropertyValue.new(OpenStruct.new(value))}
|
287
176
|
end
|
177
|
+
|
178
|
+
end
|
288
179
|
|
180
|
+
class CardTypesPropertyDefinitionsLoader
|
181
|
+
include LoaderHelper
|
182
|
+
|
183
|
+
def initialize(project, params)
|
184
|
+
@project = project
|
185
|
+
@params = params
|
186
|
+
end
|
187
|
+
|
289
188
|
def load
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
189
|
+
mappings = extract('card_types', @project).collect do |card_type|
|
190
|
+
mapping = card_type['card_types_property_definitions'].values
|
191
|
+
end.flatten
|
192
|
+
|
193
|
+
pds = extract('property_definitions', @project)
|
194
|
+
cts = extract('card_types', @project)
|
195
|
+
mappings.collect do |mapping|
|
196
|
+
if (match?(mapping))
|
197
|
+
pd = pds.find { |pd| pd['id'] && pd['id'] == mapping['property_definition_id'] }
|
198
|
+
ct = cts.find { |ct| ct['id'] == mapping['card_type_id'] }
|
199
|
+
OpenStruct.new(:card_type => CardTypeLoader.new(@project, ct).load, :property_definition => PropertyDefinitionLoader.new(@project, pd).load)
|
200
|
+
end
|
296
201
|
end.compact
|
297
|
-
end
|
202
|
+
end
|
203
|
+
|
204
|
+
private
|
205
|
+
def match?(mapping)
|
206
|
+
@params.all? { |key, value| value == mapping[key] }
|
207
|
+
end
|
298
208
|
end
|
299
209
|
|
300
|
-
class
|
210
|
+
class TeamLoader
|
211
|
+
include LoaderHelper
|
212
|
+
|
213
|
+
def initialize(project)
|
214
|
+
@project = project
|
215
|
+
end
|
216
|
+
|
301
217
|
def load
|
302
|
-
|
303
|
-
end
|
218
|
+
(extract('users', @project) || []).collect{ |user| Mingle::User(OpenStruct.new(user))}
|
219
|
+
end
|
304
220
|
end
|
305
|
-
|
306
|
-
class
|
221
|
+
|
222
|
+
class ProjectVariablesLoader
|
223
|
+
include LoaderHelper
|
224
|
+
|
225
|
+
def initialize(project)
|
226
|
+
@project = project
|
227
|
+
end
|
228
|
+
|
307
229
|
def load
|
308
|
-
|
309
|
-
end
|
230
|
+
extract('project_variables', @project).collect {|pv| Mingle::ProjectVariable.new(OpenStruct.new(pv))}
|
231
|
+
end
|
310
232
|
end
|
311
|
-
end
|
233
|
+
end
|