mingle-macro-development-toolkit 1.3.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/{History.txt → History} +11 -0
  2. data/{LICENSE.txt → LICENSE} +0 -0
  3. data/{README.txt → README} +4 -2
  4. data/Rakefile +15 -40
  5. data/bin/new_mingle_macro +25 -137
  6. data/lib/mingle_macro_development_toolkit.rb +4 -0
  7. data/lib/mingle_macro_development_toolkit/loaders.rb +5 -0
  8. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/base.rb +19 -0
  9. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/card_type_loader.rb +15 -0
  10. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/card_types_loader.rb +10 -0
  11. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/card_types_property_definitions_loader.rb +12 -0
  12. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/project_loader.rb +16 -0
  13. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/project_variables_loader.rb +10 -0
  14. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/property_definition_loader.rb +16 -0
  15. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/property_definitions_loader.rb +10 -0
  16. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/property_values_loader.rb +10 -0
  17. data/lib/mingle_macro_development_toolkit/loaders/fixture_loaders/team_loader.rb +10 -0
  18. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/base.rb +85 -0
  19. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/card_type_loader.rb +19 -0
  20. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/card_types_loader.rb +14 -0
  21. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/card_types_property_definitions_loader.rb +32 -0
  22. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/project_loader.rb +26 -0
  23. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/project_variables_loader.rb +14 -0
  24. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/property_definition_loader.rb +20 -0
  25. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/property_definitions_loader.rb +14 -0
  26. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/property_values_loader.rb +14 -0
  27. data/lib/mingle_macro_development_toolkit/loaders/restful_loaders/team_loader.rb +14 -0
  28. data/templates/Rakefile +23 -0
  29. data/{getting_started.txt → templates/getting_started.txt} +93 -93
  30. data/templates/init.rb +1 -0
  31. data/{example → templates/lib}/macro.rb +0 -0
  32. data/{test/project_data → templates/test/data/exports}/macro_toolkit_test_template.mingle +0 -0
  33. data/{test/fixtures/sample → templates/test/data/fixtures}/card_types.yml +0 -0
  34. data/{test/fixtures/sample → templates/test/data/fixtures}/project_variables.yml +0 -0
  35. data/{test/fixtures/sample → templates/test/data/fixtures}/projects.yml +0 -0
  36. data/{test/fixtures/sample → templates/test/data/fixtures}/property_definitions.yml +0 -0
  37. data/{test/fixtures/sample → templates/test/data/fixtures}/property_type_mappings.yml +0 -0
  38. data/{test/fixtures/sample → templates/test/data/fixtures}/property_values.yml +0 -0
  39. data/{test/fixtures/sample → templates/test/data/fixtures}/users.yml +0 -0
  40. data/{example → templates/test/integration}/integration_test.rb +4 -5
  41. data/templates/test/integration/integration_test_helper.rb +23 -0
  42. data/templates/test/test_helper.rb +4 -0
  43. data/{example → templates/test/unit}/unit_test.rb +7 -7
  44. data/templates/test/unit/unit_test_helper.rb +13 -0
  45. data/test/data/exports/macro_toolkit_test_template.mingle +0 -0
  46. data/test/data/fixtures/card_types.yml +37 -0
  47. data/test/data/fixtures/project_variables.yml +7 -0
  48. data/test/data/fixtures/projects.yml +4 -0
  49. data/test/data/fixtures/property_definitions.yml +51 -0
  50. data/test/data/fixtures/property_type_mappings.yml +81 -0
  51. data/test/data/fixtures/property_values.yml +19 -0
  52. data/test/data/fixtures/users.yml +16 -0
  53. data/test/integration/integration_test_helper.rb +3 -13
  54. data/test/integration/{rest_loader_test.rb → restful_loaders_test.rb} +4 -4
  55. data/test/test_helper.rb +2 -0
  56. data/test/unit/{fixture_loader_test.rb → fixture_loaders_test.rb} +2 -2
  57. data/test/unit/unit_test_helper.rb +7 -6
  58. metadata +101 -100
  59. data/example/Rakefile +0 -6
  60. data/example/deploy.rake +0 -10
  61. data/example/init.rb +0 -10
  62. data/example/integration_test_helper.rb +0 -31
  63. data/example/unit_test_helper.rb +0 -13
  64. data/lib/macro_development_toolkit.rb +0 -29
  65. data/lib/macro_development_toolkit/mingle/card_type.rb +0 -41
  66. data/lib/macro_development_toolkit/mingle/card_type_property_definition.rb +0 -26
  67. data/lib/macro_development_toolkit/mingle/project.rb +0 -168
  68. data/lib/macro_development_toolkit/mingle/project_variable.rb +0 -24
  69. data/lib/macro_development_toolkit/mingle/property_definition.rb +0 -105
  70. data/lib/macro_development_toolkit/mingle/property_value.rb +0 -67
  71. data/lib/macro_development_toolkit/mingle/user.rb +0 -33
  72. data/lib/macro_development_toolkit/mingle_model_loader.rb +0 -151
  73. data/tasks/test.rake +0 -16
  74. data/test/integration/rest_loader.rb +0 -233
  75. data/test/unit/fixture_loader.rb +0 -109
@@ -1,3 +1,14 @@
1
+ == 2.0.0 April 2012
2
+
3
+ * 1.3.4 was meant to be a major version update, sorry for the inconvenience caused.
4
+ * This version will generate macros that work with the upcoming Mingle 12.1 release.
5
+ * To work with older Mingle versions, you can use 1.3.3 version.
6
+
7
+ == 1.3.4 April 2012
8
+
9
+ * Minor bug fix
10
+ * Code refactoring
11
+
1
12
  == 1.3.3 January 2011
2
13
 
3
14
  * Minor bug fix
File without changes
@@ -1,11 +1,13 @@
1
1
  = Macro Development Toolkit - supporting development of custom macros for Mingle
2
2
 
3
- http://mingle-macros.rubyforge.org/
3
+ https://github.com/ThoughtWorksStudios/mingle_macro_development_toolkit
4
+
5
+ NOTE: This new version will only work with upcoming Mingle 12.1 release and later. For older versions of Mingle, please use version 1.3.3
4
6
 
5
7
  This toolkit provides support for developing, testing and deploying custom Mingle macros.
6
8
 
7
9
  Use the built in generator to create a skeleton of a plugin which you can then deploy to an instance of Mingle running
8
- version 2.2 or later of the software.
10
+ version 12.1 or later of the software.
9
11
 
10
12
  This allows you to take advantage of free charting utilities such as the Google Charts API, to create
11
13
  new visualizations, specific to your project or organization.
data/Rakefile CHANGED
@@ -1,40 +1,15 @@
1
- #Copyright 2009 ThoughtWorks, Inc. All rights reserved.
2
-
3
- begin
4
- require 'rubygems'
5
-
6
- unless Gem::RubyGemsVersion >= '1.2.0'
7
- $stderr.puts %(Rails requires RubyGems >= 1.2.0 (you have #{rubygems_version}). Please `gem update --system` and try again.)
8
- exit 1
9
- end
10
-
11
- rescue LoadError
12
- $stderr.puts %(Rails requires RubyGems >= 1.2.0. Please install RubyGems and try again: http://rubygems.rubyforge.org)
13
- exit 1
14
- end
15
-
16
- %w[rake rake/clean rake/testtask fileutils].each { |f| require f }
17
- require File.dirname(__FILE__) + '/lib/macro_development_toolkit'
18
-
19
-
20
- %w[newgem rubigen hoe].each { |f| require f }
21
-
22
- # Generate all the Rake tasks
23
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
24
- $hoe = Hoe.spec('mingle-macro-development-toolkit') do |p|
25
- p.version = MacroDevelopmentToolkit::VERSION
26
- p.developer('ThoughtWorks Inc', 'support@thoughtworks.com')
27
- p.post_install_message = 'getting_started.txt'
28
- p.rubyforge_name = 'mingle-macros'
29
- p.extra_deps = [
30
- ['activesupport','2.3.5'],
31
- ]
32
- p.summary = "This toolkit provides support for developing, testing and deploying custom Mingle macros."
33
- p.clean_globs |= %w[**/.DS_Store tmp *.log]
34
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
35
- p.remote_rdoc_dir = ''
36
- p.rsync_args = '-av --delete --ignore-errors'
37
- end
38
- require 'newgem/tasks'
39
-
40
- Dir['tasks/**/*.rake'].each { |t| load t }
1
+ require "rake/testtask"
2
+
3
+ namespace :test do
4
+ Rake::TestTask.new(:unit) do |t|
5
+ t.libs << "test/unit"
6
+ t.pattern = 'test/unit/*_test.rb'
7
+ t.verbose = true
8
+ end
9
+
10
+ Rake::TestTask.new(:integration) do |t|
11
+ t.libs << "test/integration"
12
+ t.pattern = 'test/integration/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+ end
data/bin/new_mingle_macro CHANGED
@@ -1,151 +1,39 @@
1
- #!/usr/bin/env ruby
2
- #Copyright 2011 ThoughtWorks, Inc. All rights reserved.
3
-
4
- module NewMingleMacro
5
- module Messages
6
- USAGE = <<-USAGE
7
- Macro name cannot be blank.
1
+ #!/usr/bin/env ruby -rubygems -w
8
2
 
9
- Usage: new_mingle_macro <macro_name> [macro_class_name]
3
+ require "fileutils"
4
+ require 'thread'
5
+ require 'active_support'
6
+ require "erb"
7
+
8
+ USAGE = <<-USAGE
9
+ Usage: new_mingle_macro <macro_name>
10
10
 
11
11
  macro_name : The name of your new macro. Should be alphabetic, possibly
12
12
  including underscores(_).
13
- macro_class_name: (optional) The name of the class that implements the macro.
14
- Should be a CamelCased alphabetic string. Defaults to
15
- CamelCased version of macro_name. We highly recommend setting
16
- your own class name with an appropriate namespace to avoid
17
- collisions with standard libraries or Mingle classes.
18
13
  USAGE
19
-
20
- SPECIAL_CHARACTER_REPLACEMENT_MESSAGE = <<-SPECIAL_CHARACTER_REPLACEMENT_MESSAGE
21
- Your macro name contains special characters that will be replaced with
22
- underscores (_). Is this OK? [Yes/No]"
23
- SPECIAL_CHARACTER_REPLACEMENT_MESSAGE
24
14
 
25
- AUTO_GENERATED_CLASS_NAME_MESSAGE = <<-AUTO_GENERATED_CLASS_NAME_MESSAGE
26
- Succeeded with warnings: You did not provide a class name for your macro. A class name has been generated
27
- for you. This name should be considered a guide and we highly recommend naming your own
28
- classes name with appropriate namespaces to avoid collisions with standard libraries
29
- or Mingle classes. Please run this tool with no command-line arguments to learn
30
- how to provide a class name.
31
- AUTO_GENERATED_CLASS_NAME_MESSAGE
32
- end
33
- end
15
+ macro_name = ARGV[0]
16
+ raise "Macro name is required!\n" + USAGE if macro_name.blank?
17
+ raise "Invalid macro name!\n" + USAGE if macro_name !~ /^[a-z]([a-z0-9_]+)?/i
34
18
 
35
- require 'erb'
36
- require 'fileutils'
37
- begin
38
- require 'active_support/all'
39
- rescue LoadError
40
- require 'rubygems'
41
- require 'active_support/all'
42
- end
19
+ macro_class_name = macro_name.downcase.camelcase
43
20
 
44
- require 'active_support/version'
45
- REQUIRED_ACTIVE_SUPPORT_VERSION = '2.3.5'
46
- unless ActiveSupport::VERSION::STRING == REQUIRED_ACTIVE_SUPPORT_VERSION
47
- raise "For guaranteed compatibility with Mingle, you must develop macros using ActiveSupport #{REQUIRED_ACTIVE_SUPPORT_VERSION}. You are using version #{ActiveSupport::VERSION::STRING}"
48
- end
49
-
50
- def print_usage
51
- puts NewMingleMacro::Messages::USAGE
52
- end
21
+ destination = File.expand_path(macro_name)
22
+ raise "#{destination} already exists!" if File.exists? destination
53
23
 
54
- if ARGV[0].blank?
55
- print_usage
56
- exit!
57
- end
58
-
59
- def read_macro_name
60
- result = ARGV[0].downcase.gsub(/\s/, '_')
61
- if result !~ /^[_A-Za-z]+$/
62
- print NewMingleMacro::Messages::SPECIAL_CHARACTER_REPLACEMENT_MESSAGE
63
- exit if STDIN.gets.downcase =~ /^n/
64
- result = result.gsub(/[^_A-Za-z]/, '_').squeeze('_')
65
- end
66
- result
67
- end
68
-
69
- def read_or_generate_macro_class_name(macro_name)
70
- if ARGV[1]
71
- ARGV[1]
72
- else
73
- puts NewMingleMacro::Messages::AUTO_GENERATED_CLASS_NAME_MESSAGE
74
- macro_name.gsub(/\W/, '_').camelize
75
- end
76
- end
24
+ FileUtils.mkdir destination
77
25
 
78
- def validate_class_name(macro_class_name)
79
- if macro_class_name.camelize != macro_class_name
80
- print "Your macro class name is not a valid class name. Continue with the default class name of #{macro_name.camelize}? [Yes/No]"
81
- exit if STDIN.gets.downcase =~ /^n/
82
- macro_class_name = macro_name.camelize
26
+ Dir.chdir(File.join(File.dirname(__FILE__), "..", "templates")) do
27
+ Dir.glob("**/*").each do |f|
28
+ next if File.directory? f
29
+ output = File.join(destination, f)
30
+ FileUtils.mkdir_p(File.dirname(output))
31
+ File.open(output, 'w').write(ERB.new(File.read(f), nil, '-').result(binding))
83
32
  end
84
- macro_class_name
85
- end
86
-
87
- macro_name = read_macro_name
88
- macro_class_name = validate_class_name(read_or_generate_macro_class_name(macro_name))
89
-
90
- if File.exists?(macro_name)
91
- print "Folder #{macro_name} already exists in your current directory. Either rename the macro or delete the folder and then execute this command to continue."
92
- exit
93
33
  end
94
34
 
95
- class Path
96
- def initialize(location=:gem)
97
- @base_location = if location.to_s == 'gem'
98
- File.expand_path(File.join(File.dirname(__FILE__), '..'))
99
- else
100
- File.expand_path(location)
101
- end
102
-
103
- end
104
-
105
- def /(another_fragment)
106
- self.class.new(File.join(@base_location, another_fragment))
107
- end
108
-
109
- def cp(options = {:to => nil, :r => true})
110
- if options[:r]
111
- FileUtils.cp(@base_location, options[:to].to_s, :verbose => false)
112
- else
113
- FileUtils.cp_r(@base_location, options[:to].to_s, :verbose => false)
114
- end
115
- end
116
-
117
- def mkdir_p
118
- FileUtils.mkdir_p(@base_location)
119
- end
120
-
121
- def to_s
122
- @base_location
123
- end
124
- end
125
-
126
- gem_dir = Path.new(:gem)
127
- macro_dir = Path.new(macro_name)
128
-
129
- [macro_dir/'lib', macro_dir/'test'/'unit', macro_dir/'test'/'fixtures', macro_dir/'test'/'integration', macro_dir/'tasks'].each(&:mkdir_p)
130
-
131
- (gem_dir/'test'/'fixtures'/'sample').cp :to => macro_dir/'test'/'fixtures'
132
- (gem_dir/'test'/'unit'/'fixture_loader.rb').cp :to => macro_dir/'test'/'unit'/'fixture_loader.rb'
133
- (gem_dir/'test'/'integration'/'rest_loader.rb').cp :to => macro_dir/'test'/'integration'/'rest_loader.rb'
134
- (gem_dir/'tasks'/'test.rake').cp :to => macro_dir/'tasks'/'test.rake'
135
- (gem_dir/'example'/'deploy.rake').cp :to => macro_dir/'tasks'/'deploy.rake'
136
- (gem_dir/'getting_started.txt').cp :to => macro_dir/'getting_started.txt'
137
-
138
- templates = {
139
- gem_dir/'example'/'Rakefile' => macro_dir/'Rakefile',
140
- gem_dir/'example'/'init.rb' => macro_dir/'init.rb',
141
- gem_dir/'example'/'macro.rb' => macro_dir/'lib'/"#{macro_name}.rb",
142
- gem_dir/'example'/'unit_test.rb' => macro_dir/'test'/'unit'/"#{macro_name}_test.rb",
143
- gem_dir/'example'/'unit_test_helper.rb' => macro_dir/'test'/'unit'/'unit_test_helper.rb',
144
- gem_dir/'example'/'integration_test.rb' => macro_dir/'test'/'integration'/"#{macro_name}_integration_test.rb",
145
- gem_dir/'example'/'integration_test_helper.rb' => macro_dir/'test'/'integration'/'integration_test_helper.rb'
146
- }
147
-
148
- templates.each do |template, output|
149
- template_file = File.open(template.to_s)
150
- File.open(output.to_s, 'w').write(ERB.new(template_file.read, nil, '-').result(binding))
35
+ Dir.chdir(destination) do
36
+ FileUtils.mv("lib/macro.rb", File.join("lib", "#{macro_name}.rb"))
37
+ FileUtils.mv("test/unit/unit_test.rb", File.join("test", "unit", "#{macro_name}_test.rb"))
38
+ FileUtils.mv("test/integration/integration_test.rb", File.join("test", "integration", "#{macro_name}_integration_test.rb"))
151
39
  end
@@ -0,0 +1,4 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ require "rubygems"
3
+ require 'mingle_macro_models'
4
+ require "mingle_macro_development_toolkit/loaders"
@@ -0,0 +1,5 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+
3
+ Dir.glob(File.join(File.dirname(__FILE__), "loaders", "**/*.rb")).each do |file|
4
+ require file
5
+ end
@@ -0,0 +1,19 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ require "yaml"
3
+
4
+ module FixtureLoaders
5
+ class Base
6
+ def initialize(attributes)
7
+ @attributes = attributes
8
+ end
9
+
10
+ def load_fixtures_for(name)
11
+ path = File.join(FixtureLoaders::FIXTURE_PATH, "#{name}.yml")
12
+ YAML::load(File.read(path))
13
+ end
14
+
15
+ def match?(record)
16
+ @attributes.all? { |key, value| value == record[key] }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ module FixtureLoaders
3
+ class CardTypeLoader < Base
4
+ def card_type
5
+ @card_type ||= load
6
+ end
7
+
8
+ def load
9
+ record = load_fixtures_for('card_types').find {|ct| match?(ct)}
10
+ card_type = Mingle::CardType.new(OpenStruct.new(record))
11
+ card_type.card_types_property_definitions_loader = CardTypesPropertyDefinitionsLoader.new('card_type_id' => record['id'])
12
+ card_type
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ module FixtureLoaders
3
+ class CardTypesLoader < Base
4
+ def load
5
+ load_fixtures_for('card_types').collect do |ct|
6
+ CardTypeLoader.new('id' => ct['id']) if match?(ct)
7
+ end.compact.sort_by { |loader| loader.card_type.position }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ module FixtureLoaders
3
+ class CardTypesPropertyDefinitionsLoader < Base
4
+ def load
5
+ load_fixtures_for('property_type_mappings').collect do |mapping|
6
+ pd = PropertyDefinitionLoader.new('id' => mapping['property_definition_id']) if match?(mapping)
7
+ ct = CardTypeLoader.new('id' => mapping['card_type_id']) if match?(mapping)
8
+ OpenStruct.new(:card_type => ct.load, :property_definition => pd.load) if ct && pd
9
+ end.compact
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ require "ostruct"
3
+
4
+ module FixtureLoaders
5
+ class ProjectLoader < Base
6
+ attr_reader :project
7
+ def initialize(identifier)
8
+ project_attributes = load_fixtures_for('projects').detect {|project| project['identifier'] == identifier }
9
+ @project = Mingle::Project.new(OpenStruct.new(project_attributes), nil)
10
+ project.card_types_loader = CardTypesLoader.new('project_id' => project_attributes['id'])
11
+ project.property_definitions_loader = PropertyDefinitionsLoader.new('project_id' => project_attributes['id'])
12
+ project.team_loader = TeamLoader.new('project_id' => project_attributes['id'])
13
+ project.project_variables_loader = ProjectVariablesLoader.new('project_id' => project_attributes['id'])
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ module FixtureLoaders
3
+ class ProjectVariablesLoader < Base
4
+ def load
5
+ load_fixtures_for('project_variables').collect do |pv|
6
+ Mingle::ProjectVariable.new(OpenStruct.new(pv)) if match?(pv)
7
+ end.compact
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ module FixtureLoaders
3
+ class PropertyDefinitionLoader < Base
4
+ def property_definition
5
+ @property_definition ||= load
6
+ end
7
+
8
+ def load
9
+ record = load_fixtures_for('property_definitions').find { |pd| match?(pd)}
10
+ property_definition = Mingle::PropertyDefinition.new(OpenStruct.new(record))
11
+ property_definition.card_types_property_definitions_loader = CardTypesPropertyDefinitionsLoader.new('property_definition_id' => record['id'])
12
+ property_definition.values_loader = PropertyValuesLoader.new('property_definition_id' => record['id'])
13
+ property_definition
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ module FixtureLoaders
3
+ class PropertyDefinitionsLoader < Base
4
+ def load
5
+ load_fixtures_for('property_definitions').collect do |pd|
6
+ PropertyDefinitionLoader.new('id' => pd['id']) if match?(pd)
7
+ end.compact
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ module FixtureLoaders
3
+ class PropertyValuesLoader < Base
4
+ def load
5
+ load_fixtures_for('property_values').collect do |pv|
6
+ Mingle::PropertyValue.new(OpenStruct.new(pv)) if match?(pv)
7
+ end.compact
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ module FixtureLoaders
3
+ class TeamLoader < Base
4
+ def load
5
+ load_fixtures_for('users').collect do |user|
6
+ Mingle::User.new(OpenStruct.new(user)) if match?(user)
7
+ end.compact
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,85 @@
1
+ #Copyright 2012 ThoughtWorks, Inc. All rights reserved.
2
+ require 'delegate'
3
+ require 'uri'
4
+ require 'net/http'
5
+ require 'thread'
6
+ require 'active_support'
7
+
8
+ module RESTfulLoaders
9
+
10
+ class RemoteError < StandardError
11
+ def self.parse(response_body)
12
+ Hash.from_xml(response_body)['errors'].delete("error")
13
+ end
14
+ end
15
+
16
+ module LoaderHelper
17
+
18
+ def extract(key, container)
19
+ container[key] ? container[key][key.singularize] : []
20
+ end
21
+
22
+ def get(resource)
23
+ url = URI.parse(resource)
24
+ get_request = Net::HTTP::Get.new(url.request_uri)
25
+ get_request.basic_auth(url.user, url.password)
26
+ response = Net::HTTP.start(url.host, url.port) { |http| http.request(get_request) }
27
+ if response.code.to_s != "200"
28
+ raise RemoteError, RemoteError.parse(response.body)
29
+ end
30
+ Hash.from_xml(response.body)
31
+ end
32
+ end
33
+
34
+ class MqlExecutor < SimpleDelegator
35
+ include LoaderHelper
36
+
37
+ def initialize(resource, error_handler, delegator)
38
+ super(delegator)
39
+ @uri = URI.parse(resource)
40
+ @error_handler = error_handler
41
+ @version = /(\/api\/([^\/]*))\//.match(@uri.request_uri)[2]
42
+ end
43
+
44
+ def execute_mql(mql)
45
+ from_xml_data(get(url_for(:action => "execute_mql", :query => "mql=#{mql}")))
46
+ rescue => e
47
+ @error_handler.alert(e.message)
48
+ []
49
+ end
50
+
51
+ def can_be_cached?(mql)
52
+ from_xml_data(get(url_for(:action => "can_be_cached", :query => "mql=#{mql}")))
53
+ rescue => e
54
+ @error_handler.alert(e.message)
55
+ []
56
+ end
57
+
58
+ def format_number_with_project_precision(number)
59
+ from_xml_data(get(url_for(:action => "format_number_to_project_precision", :query => "number=#{number}")))
60
+ rescue => e
61
+ @error_handler.alert(e.message)
62
+ []
63
+ end
64
+
65
+ def format_date_with_project_date_format(date)
66
+ from_xml_data(get(url_for(:action => "format_string_to_date_format", :query => "date=#{date}")))
67
+ rescue => e
68
+ @error_handler.alert(e.message)
69
+ []
70
+ end
71
+
72
+ def url_for(params)
73
+ relative_path = URI.escape("/api/#{@version}/projects/#{identifier}/cards/#{params[:action]}.xml?#{params[:query]}")
74
+ @uri.merge(relative_path).to_s
75
+ end
76
+
77
+ def from_xml_data(data)
78
+ if data.is_a?(Hash) && data.keys.size == 1
79
+ from_xml_data(data.values.first)
80
+ else
81
+ data
82
+ end
83
+ end
84
+ end
85
+ end