Merge pull request #50 from finnlabs/feature/houndci-config-ruby-style

Add Hound/Rubocop config; Make Ruby style consistent
pull/6827/head
Alex Coles 10 years ago
commit bdd4e14cb5
  1. 3
      .hound.yml
  2. 265
      .rubocop.yml
  3. 55
      app/controllers/cost_reports_controller.rb
  4. 38
      app/helpers/reporting_helper.rb
  5. 6
      app/models/cost_query.rb
  6. 7
      app/models/cost_query/custom_field_mixin.rb
  7. 3
      app/models/cost_query/filter/activity_id.rb
  8. 2
      app/models/cost_query/filter/category_id.rb
  9. 2
      app/models/cost_query/filter/cost_object_id.rb
  10. 2
      app/models/cost_query/filter/cost_type_id.rb
  11. 2
      app/models/cost_query/filter/created_on.rb
  12. 2
      app/models/cost_query/filter/fixed_version_id.rb
  13. 2
      app/models/cost_query/filter/no_filter.rb
  14. 3
      app/models/cost_query/filter/overridden_costs.rb
  15. 12
      app/models/cost_query/filter/permission_filter.rb
  16. 2
      app/models/cost_query/filter/priority_id.rb
  17. 8
      app/models/cost_query/filter/project_id.rb
  18. 4
      app/models/cost_query/filter/status_id.rb
  19. 2
      app/models/cost_query/filter/tmonth.rb
  20. 2
      app/models/cost_query/filter/tweek.rb
  21. 2
      app/models/cost_query/filter/tyear.rb
  22. 2
      app/models/cost_query/filter/type_id.rb
  23. 2
      app/models/cost_query/filter/updated_on.rb
  24. 4
      app/models/cost_query/filter/user_id.rb
  25. 7
      app/models/cost_query/filter/work_package_id.rb
  26. 2
      app/models/cost_query/group_by/sql_aggregation.rb
  27. 8
      app/models/cost_query/operator.rb
  28. 16
      app/models/cost_query/sql_statement.rb
  29. 2
      features/step_definitions/custom_steps.rb
  30. 4
      features/step_definitions/disabled_scenarios.rb
  31. 34
      lib/open_project/reporting/engine.rb
  32. 2
      lib/open_project/reporting/hooks.rb
  33. 16
      lib/open_project/reporting/patches/costlog_controller_patch.rb
  34. 14
      lib/open_project/reporting/patches/timelog_controller_patch.rb
  35. 48
      lib/widget/entry_table.rb
  36. 4
      lib/widget/settings_patch.rb
  37. 18
      lib/widget/simple_table.rb
  38. 2
      lib/widget/sortable_init.rb
  39. 4
      spec/controllers/cost_reports_controller_spec.rb
  40. 4
      spec/factories/cost_query_factory.rb
  41. 28
      spec/models/cost_query/chaining_spec.rb
  42. 8
      spec/models/cost_query/cost_query_spec.rb
  43. 166
      spec/models/cost_query/filter_spec.rb
  44. 24
      spec/models/cost_query/group_by_spec.rb
  45. 12
      spec/models/cost_query/integration_spec.rb
  46. 68
      spec/models/cost_query/operator_spec.rb
  47. 6
      spec/models/cost_query/result_spec.rb
  48. 2
      spec/models/cost_query/validation_spec.rb
  49. 2
      spec/models/cost_query/walker_spec.rb
  50. 8
      spec/support/plugin_spec_helper.rb
  51. 6
      spec/support/project_helper.rb
  52. 2
      spec/support/query_helper.rb

@ -0,0 +1,3 @@
ruby:
enabled: true
config_file: .rubocop.yml

@ -0,0 +1,265 @@
AllCops:
Exclude:
- *.gemspec
AccessorMethodName:
Enabled: false
ActionFilter:
Enabled: false
Alias:
Enabled: false
AndOr:
Enabled: false
ArrayJoin:
Enabled: false
AsciiComments:
Enabled: false
AsciiIdentifiers:
Enabled: false
Attr:
Enabled: false
BlockNesting:
Enabled: false
Blocks:
Enabled: false
CaseEquality:
Enabled: false
CharacterLiteral:
Enabled: false
ClassAndModuleChildren:
Enabled: false
ClassLength:
Enabled: false
ClassVars:
Enabled: false
CollectionMethods:
PreferredMethods:
find: detect
reduce: inject
collect: map
find_all: select
ColonMethodCall:
Enabled: false
CommentAnnotation:
Enabled: false
CyclomaticComplexity:
Enabled: false
Delegate:
Enabled: false
DeprecatedHashMethods:
Enabled: false
Documentation:
Enabled: false
DotPosition:
EnforcedStyle: leading
DoubleNegation:
Enabled: false
EachWithObject:
Enabled: false
EmptyLiteral:
Enabled: false
Encoding:
Enabled: false
EvenOdd:
Enabled: false
FileName:
Enabled: false
FlipFlop:
Enabled: false
FormatString:
Enabled: false
GlobalVars:
Enabled: false
GuardClause:
Enabled: false
IfUnlessModifier:
Enabled: false
IfWithSemicolon:
Enabled: false
InlineComment:
Enabled: false
Lambda:
Enabled: false
LambdaCall:
Enabled: false
LineEndConcatenation:
Enabled: false
LineLength:
Max: 100
MethodLength:
Enabled: false
ModuleFunction:
Enabled: false
NegatedIf:
Enabled: false
NegatedWhile:
Enabled: false
Next:
Enabled: false
NilComparison:
Enabled: false
Not:
Enabled: false
NumericLiterals:
Enabled: false
OneLineConditional:
Enabled: false
OpMethod:
Enabled: false
ParameterLists:
Enabled: false
PercentLiteralDelimiters:
Enabled: false
PerlBackrefs:
Enabled: false
PredicateName:
NamePrefixBlacklist:
- is_
Proc:
Enabled: false
RaiseArgs:
Enabled: false
RegexpLiteral:
Enabled: false
SelfAssignment:
Enabled: false
SingleLineBlockParams:
Enabled: false
SingleLineMethods:
Enabled: false
SignalException:
Enabled: false
SpecialGlobalVars:
Enabled: false
StringLiterals:
EnforcedStyle: single_quotes
VariableInterpolation:
Enabled: false
TrailingComma:
Enabled: false
TrivialAccessors:
Enabled: false
VariableInterpolation:
Enabled: false
WhenThen:
Enabled: false
WhileUntilModifier:
Enabled: false
WordArray:
Enabled: false
# Lint
AmbiguousOperator:
Enabled: false
AmbiguousRegexpLiteral:
Enabled: false
AssignmentInCondition:
Enabled: false
ConditionPosition:
Enabled: false
DeprecatedClassMethods:
Enabled: false
ElseLayout:
Enabled: false
HandleExceptions:
Enabled: false
InvalidCharacterLiteral:
Enabled: false
LiteralInCondition:
Enabled: false
LiteralInInterpolation:
Enabled: false
Loop:
Enabled: false
ParenthesesAsGroupedExpression:
Enabled: false
RequireParentheses:
Enabled: false
UnderscorePrefixedVariableName:
Enabled: false
Void:
Enabled: false

@ -18,17 +18,15 @@
#++
class CostReportsController < ApplicationController
rescue_from Exception do |exception|
session.delete(CostQuery.name.underscore.to_sym)
raise exception
end
rescue_from ActiveRecord::RecordNotFound do |exception|
rescue_from ActiveRecord::RecordNotFound do |_exception|
render_404
end
Widget::Base.dont_cache!
before_filter :check_cache
@ -38,8 +36,8 @@ class CostReportsController < ApplicationController
include Report::Controller
before_filter :set_cost_types # has to be set AFTER the Report::Controller filters run
verify :method => :delete, :only => %w[delete]
verify :method => :post, :only => %w[create update rename]
verify method: :delete, only: %w[delete]
verify method: :post, only: %w[create update rename]
helper_method :cost_types
helper_method :cost_type
@ -53,7 +51,7 @@ class CostReportsController < ApplicationController
# Checks if custom fields have been updated, added or removed since we
# last saw them, to rebuild the filters and group bys.
# Called once per request.
def check_cache(force_update=false)
def check_cache(force_update = false)
custom_fields_updated_on = WorkPackageCustomField.maximum(:updated_at)
custom_fields_id_sum = WorkPackageCustomField.sum(:id) + WorkPackageCustomField.count
@ -81,13 +79,13 @@ class CostReportsController < ApplicationController
respond_to do |format|
format.html {
session[report_engine.name.underscore.to_sym].try(:delete, :name)
render :action => "index"
render action: 'index'
}
end unless performed?
end
def drill_down
redirect_to :action => :index
redirect_to action: :index
end
##
@ -106,12 +104,12 @@ class CostReportsController < ApplicationController
##
# Set a default query to cut down initial load time
def default_filter_parameters
{:operators => {:user_id => "=", :spent_on => ">d"},
:values => {:user_id => [User.current.id], :spent_on => [30.days.ago.strftime('%Y-%m-%d')]}
{ operators: { user_id: '=', spent_on: '>d' },
values: { user_id: [User.current.id], spent_on: [30.days.ago.strftime('%Y-%m-%d')] }
}.tap do |hash|
if @project
hash[:operators].merge! :project_id => "="
hash[:values].merge! :project_id => [@project.id]
hash[:operators].merge! project_id: '='
hash[:values].merge! project_id: [@project.id]
end
end
end
@ -119,7 +117,7 @@ class CostReportsController < ApplicationController
##
# Set a default query to cut down initial load time
def default_group_parameters
{:columns => [:week], :rows => []}.tap do |h|
{ columns: [:week], rows: [] }.tap do |h|
if @project
h[:rows] << :work_package_id
else
@ -133,8 +131,8 @@ class CostReportsController < ApplicationController
def ensure_project_scope!(filters)
return unless ensure_project_scope?
if @project
filters[:operators].merge! :project_id => "="
filters[:values].merge! :project_id => @project.id.to_s
filters[:operators].merge! project_id: '='
filters[:values].merge! project_id: @project.id.to_s
else
filters[:operators].delete :project_id
filters[:values].delete :project_id
@ -159,7 +157,7 @@ class CostReportsController < ApplicationController
@unit_id = if set_unit?
params[:unit].to_i
elsif @query.present?
cost_type_filter = @query.filters.detect{ |f| f.is_a?(CostQuery::Filter::CostTypeId) }
cost_type_filter = @query.filters.detect { |f| f.is_a?(CostQuery::Filter::CostTypeId) }
cost_type_filter.values.first.to_i if cost_type_filter
end
@ -171,7 +169,7 @@ class CostReportsController < ApplicationController
# sets the @cost_type -> this is used to select the proper units for display
def set_cost_type
if @unit_id != 0 && @query
@query.filter :cost_type_id, :operator => '=', :value => @unit_id.to_s, :display => false
@query.filter :cost_type_id, operator: '=', value: @unit_id.to_s, display: false
@cost_type = CostType.find(@unit_id) if @unit_id > 0
end
end
@ -179,7 +177,7 @@ class CostReportsController < ApplicationController
# set the @cost_types -> this is used to determine which tabs to display
def set_active_cost_types
unless session[:report] && (@cost_types = session[:report][:filters][:values][:cost_type_id].try(:collect, &:to_i))
relevant_cost_types = CostType.find(:all, :select => "id", :order => "id ASC").select do |t|
relevant_cost_types = CostType.find(:all, select: 'id', order: 'id ASC').select do |t|
t.cost_entries.count > 0
end.collect(&:id)
@cost_types = [-1, 0, *relevant_cost_types]
@ -215,7 +213,7 @@ class CostReportsController < ApplicationController
if report.project.present?
options = {}
else
options = {:global => true}
options = { global: true }
end
case action
@ -242,37 +240,38 @@ class CostReportsController < ApplicationController
def public_queries
if @project
CostQuery.find(:all,
:conditions => ["is_public = ? AND (project_id IS NULL OR project_id = ?)",
conditions: ['is_public = ? AND (project_id IS NULL OR project_id = ?)',
true, @project],
:order => "name ASC")
order: 'name ASC')
else
CostQuery.find(:all,
:conditions => ["is_public = ? AND project_id IS NULL",
conditions: ['is_public = ? AND project_id IS NULL',
true],
:order => "name ASC")
order: 'name ASC')
end
end
def private_queries
if @project
CostQuery.find(:all,
:conditions => ["user_id = ? AND is_public = ? AND (project_id IS NULL OR project_id = ?)",
conditions: ['user_id = ? AND is_public = ? AND (project_id IS NULL OR project_id = ?)',
current_user, false, @project],
:order => "name ASC")
order: 'name ASC')
else
CostQuery.find(:all,
:conditions => ["user_id = ? AND is_public = ? AND project_id IS NULL",
conditions: ['user_id = ? AND is_public = ? AND project_id IS NULL',
current_user, false],
:order => "name ASC")
order: 'name ASC')
end
end
def display_report_list
report_type = params[:report_type] || :public
render :partial => "report_list", :locals => { :report_type => report_type }, :layout => !request.xhr?
render partial: 'report_list', locals: { report_type: report_type }, layout: !request.xhr?
end
private
def find_optional_user
@current_user = User.current || User.anonymous
end

@ -40,7 +40,7 @@ module ReportingHelper
def label_for(field)
name = field.to_s
if name.starts_with?("label")
if name.starts_with?('label')
return I18n.t(field)
end
name = name.camelcase
@ -50,15 +50,15 @@ module ReportingHelper
CostQuery::GroupBy.const_defined? name
CostQuery::GroupBy.const_get(name).label
else
#note that using WorkPackage.human_attribute_name relies on the attribute
#being an work_package attribute or a general attribute for all models whicht might not
#be the case but so far I have only seen the "comments" attribute in reports
# note that using WorkPackage.human_attribute_name relies on the attribute
# being an work_package attribute or a general attribute for all models whicht might not
# be the case but so far I have only seen the "comments" attribute in reports
WorkPackage.human_attribute_name(field)
end
end
def debug_fields(result, prefix = ", ")
prefix << result.fields.inspect << ", " << result.important_fields.inspect << ', ' << result.key.inspect if params[:debug]
def debug_fields(result, prefix = ', ')
prefix << result.fields.inspect << ', ' << result.important_fields.inspect << ', ' << result.key.inspect if params[:debug]
end
def month_name(index)
@ -68,12 +68,12 @@ module ReportingHelper
# ======================= SHARED CODE END
def show_field(key, value)
@show_row ||= Hash.new { |h,k| h[k] = {}}
@show_row ||= Hash.new { |h, k| h[k] = {} }
@show_row[key][value] ||= field_representation_map(key, value)
end
def raw_field(key, value)
@raw_row ||= Hash.new { |h,k| h[k] = {}}
@raw_row ||= Hash.new { |h, k| h[k] = {} }
@raw_row[key][value] ||= field_sort_map(key, value)
end
@ -104,18 +104,18 @@ module ReportingHelper
when :week then "#{l(:label_week)} #%s" % value.to_i.modulo(100)
when :priority_id then h(IssuePriority.find(value.to_i).name)
when :fixed_version_id then h(Version.find(value.to_i).name)
when :singleton_value then ""
when :singleton_value then ''
when :status_id then h(Status.find(value.to_i).name)
else h(value.to_s)
end
end
def field_sort_map(key, value)
return "" if value.blank?
return '' if value.blank?
case key.to_sym
when :work_package_id, :tweek, :tmonth, :week then value.to_i
when :spent_on then value.to_date.mjd
else h(field_representation_map(key, value).gsub(/<\/?[^>]*>/, ""))
else h(field_representation_map(key, value).gsub(/<\/?[^>]*>/, ''))
end
end
@ -130,7 +130,7 @@ module ReportingHelper
end
def set_filter_options(struct, key, value)
struct[:operators][key] = "="
struct[:operators][key] = '='
struct[:values][key] = value.to_s
end
@ -138,10 +138,10 @@ module ReportingHelper
tabs = cost_types.to_a
tabs.delete 0 # remove money from list
tabs.unshift 0 # add money as first tab
tabs.map {|cost_type_id| [cost_type_id, cost_type_label(cost_type_id)] }
tabs.map { |cost_type_id| [cost_type_id, cost_type_label(cost_type_id)] }
end
def cost_type_label(cost_type_id, cost_type_inst = nil, plural = true)
def cost_type_label(cost_type_id, cost_type_inst = nil, _plural = true)
case cost_type_id
when -1 then l(:caption_labor)
when 0 then l(:label_money)
@ -151,7 +151,7 @@ module ReportingHelper
def link_to_details(result)
return '' # unless result.respond_to? :fields # uncomment to display
session_filter = {:operators => session[:report][:filters][:operators].dup, :values => session[:report][:filters][:values].dup }
session_filter = { operators: session[:report][:filters][:operators].dup, values: session[:report][:filters][:values].dup }
filters = result.fields.inject session_filter do |struct, (key, value)|
key = key.to_sym
case key
@ -166,14 +166,14 @@ module ReportingHelper
end
struct
end
options = { :fields => filters[:operators].keys, :set_filter => 1, :action => :drill_down }
link_to '[+]', filters.merge(options), :class => 'drill_down', :title => l(:description_drill_down)
options = { fields: filters[:operators].keys, set_filter: 1, action: :drill_down }
link_to '[+]', filters.merge(options), class: 'drill_down', title: l(:description_drill_down)
end
##
# Create the appropriate action for an entry with the type of log to use
def action_for(result, options = {})
options.merge :controller => result.fields['type'] == 'TimeEntry' ? 'timelog' : 'costlog', :id => result.fields['id'].to_i
options.merge controller: result.fields['type'] == 'TimeEntry' ? 'timelog' : 'costlog', id: result.fields['id'].to_i
end
##
@ -187,7 +187,7 @@ module ReportingHelper
# For a given row, determine how to render it's contents according to usability and
# localization rules
def show_row(row)
row_text = link_to_details(row) << row.render { |k,v| show_field(k,v) }
row_text = link_to_details(row) << row.render { |k, v| show_field(k, v) }
row_text.html_safe
end

@ -25,9 +25,9 @@ class CostQuery < Report
CostQuery.update_all ['user_id = ?', DeletedUser.first.id], ['user_id = ?', user.id]
max_query_id = 0
while((current_queries = CostQuery.all(:limit => 1000,
:conditions => ["id > ?", max_query_id],
:order => "id ASC")).size > 0) do
while((current_queries = CostQuery.all(limit: 1000,
conditions: ["id > ?", max_query_id],
order: "id ASC")).size > 0) do
current_queries.each do |query|
serialized = query.serialized

@ -44,7 +44,7 @@ module CostQuery::CustomFieldMixin
end
def generate_subclasses
WorkPackageCustomField.all(:conditions => "field_format in ('#{SQL_TYPES.keys.join('\',\'')}')").map do |field|
WorkPackageCustomField.all(conditions: "field_format in ('#{SQL_TYPES.keys.join('\',\'')}')").map do |field|
class_name = "CustomField#{field.id}"
parent.send(:remove_const, class_name) if parent.const_defined? class_name
parent.const_set class_name, Class.new(self)
@ -59,7 +59,7 @@ module CostQuery::CustomFieldMixin
def on_prepare(&block)
return factory.on_prepare unless factory?
@on_prepare = block if block
@on_prepare ||= proc { }
@on_prepare ||= proc {}
@on_prepare
end
@ -76,7 +76,7 @@ module CostQuery::CustomFieldMixin
@class_name = class_name
dont_inherit :group_fields
db_field table_name
join_table (<<-SQL % [CustomValue.table_name, table_name, field.id, field.name, SQL_TYPES[field.field_format]]).gsub(/^ /, "")
join_table (<<-SQL % [CustomValue.table_name, table_name, field.id, field.name, SQL_TYPES[field.field_format]]).gsub(/^ /, '')
-- BEGIN Custom Field Join: "%4$s"
LEFT OUTER JOIN (
\tSELECT
@ -100,5 +100,4 @@ module CostQuery::CustomFieldMixin
fail "Only subclasses of #{self} should be instanciated." if factory?
super
end
end

@ -18,12 +18,11 @@
#++
class CostQuery::Filter::ActivityId < Report::Filter::Base
def self.label
TimeEntry.human_attribute_name(:activity)
end
def self.available_values(*)
TimeEntryActivity.find(:all, :order => 'name').map { |a| [a.name, a.id] }
TimeEntryActivity.find(:all, order: 'name').map { |a| [a.name, a.id] }
end
end

@ -27,7 +27,7 @@ class CostQuery::Filter::CategoryId < Report::Filter::Base
end
def self.available_values(*)
categories = Category.find :all, :conditions => {:project_id => Project.visible.map{|p| p.id}}
categories = Category.find :all, conditions: { project_id: Project.visible.map(&:id) }
categories.map { |c| ["#{c.project.name} - #{c.name} ", c.id] }.sort_by { |a| a.first.to_s + a.second.to_s }
end
end

@ -26,6 +26,6 @@ class CostQuery::Filter::CostObjectId < Report::Filter::Base
end
def self.available_values(*)
([[l(:caption_labor), -1]] + CostObject.find(:all, :order => 'name').map { |t| [t.name, t.id] })
([[l(:caption_labor), -1]] + CostObject.find(:all, order: 'name').map { |t| [t.name, t.id] })
end
end

@ -39,6 +39,6 @@ class CostQuery::Filter::CostTypeId < Report::Filter::Base
end
def self.available_values(*)
([[::I18n.t(:caption_labor), -1]] + CostType.find(:all, :order => 'name').map { |t| [t.name, t.id] })
([[::I18n.t(:caption_labor), -1]] + CostType.find(:all, order: 'name').map { |t| [t.name, t.id] })
end
end

@ -18,7 +18,7 @@
#++
class CostQuery::Filter::CreatedOn < Report::Filter::Base
db_field "entries.created_on"
db_field 'entries.created_on'
use :time_operators
def self.label

@ -27,7 +27,7 @@ class CostQuery::Filter::FixedVersionId < Report::Filter::Base
end
def self.available_values(*)
versions = Version.find :all, :conditions => {:project_id => Project.visible.map{|p| p.id}}
versions = Version.find :all, conditions: { project_id: Project.visible.map(&:id) }
versions.map { |a| ["#{a.project.name} - #{a.name}", a.id] }.sort_by { |a| a.first.to_s + a.second.to_s }
end
end

@ -18,7 +18,7 @@
#++
class CostQuery::Filter::NoFilter < Report::Filter::NoFilter
table_name "entries"
table_name 'entries'
dont_display!
singleton

@ -18,13 +18,12 @@
#++
class CostQuery::Filter::OverriddenCosts < Report::Filter::Base
def self.label
CostEntry.human_attribute_name(:overridden_costs)
end
def self.available_operators
['y', 'n'].map { |s| s.to_operator }
['y', 'n'].map(&:to_operator)
end
def self.available_values(*)

@ -20,10 +20,10 @@
class CostQuery::Filter::PermissionFilter < Report::Filter::Base
dont_display!
not_selectable!
db_field ""
db_field ''
singleton
initialize_query_with { |query| query.filter self.to_s.demodulize.to_sym }
initialize_query_with { |query| query.filter to_s.demodulize.to_sym }
def permission_statement(permission)
User.current.allowed_to_condition_with_project_id(permission).gsub(/(user|project)s?\.id/, '\1_id')
@ -37,10 +37,10 @@ class CostQuery::Filter::PermissionFilter < Report::Filter::Base
def display_costs
"(#{permission_statement :view_hourly_rates} " \
"AND #{permission_statement :view_cost_rates}) " \
"OR " \
'OR ' \
"(#{permission_statement :view_own_hourly_rate} " \
"AND type = 'TimeEntry' AND user_id = #{User.current.id}) " \
"OR " \
'OR ' \
"(#{permission_statement :view_cost_rates} " \
"AND type = 'CostEntry' AND user_id = #{User.current.id})"
end
@ -49,8 +49,8 @@ class CostQuery::Filter::PermissionFilter < Report::Filter::Base
super.tap do |query|
query.from.each_subselect do |sub|
sub.where permission_for(sub == query.from.first ? 'time' : 'cost')
sub.select.delete_if { |f| f.end_with? "display_costs" }
sub.select :display_costs => switch(display_costs => '1', :else => 0)
sub.select.delete_if { |f| f.end_with? 'display_costs' }
sub.select display_costs: switch(display_costs => '1', else: 0)
end
end
end

@ -26,6 +26,6 @@ class CostQuery::Filter::PriorityId < Report::Filter::Base
end
def self.available_values(*)
IssuePriority.find(:all, :order => 'position DESC').map { |i| [i.name, i.id] }
IssuePriority.find(:all, order: 'position DESC').map { |i| [i.name, i.id] }
end
end

@ -18,14 +18,14 @@
#++
class CostQuery::Filter::ProjectId < Report::Filter::Base
db_field "entries.project_id"
db_field 'entries.project_id'
def self.label
Project.model_name.human
end
def self.available_operators
["=", "!", "=_child_projects", "!_child_projects"].map { |s| s.to_operator }
['=', '!', '=_child_projects', '!_child_projects'].map(&:to_operator)
end
##
@ -37,10 +37,10 @@ class CostQuery::Filter::ProjectId < Report::Filter::Base
map = []
ancestors = []
Project.visible.sort_by(&:lft).each do |project|
while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
while ancestors.any? && !project.is_descendant_of?(ancestors.last)
ancestors.pop
end
map << [project.name, project.id, {:level => ancestors.size}]
map << [project.name, project.id, { level: ancestors.size }]
ancestors << project
end
map

@ -17,7 +17,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#++
#we have to require this here because the operators would not be defined otherwise
# we have to require this here because the operators would not be defined otherwise
require_dependency 'cost_query/operator'
class CostQuery::Filter::StatusId < Report::Filter::Base
available_operators 'c', 'o'
@ -29,6 +29,6 @@ class CostQuery::Filter::StatusId < Report::Filter::Base
end
def self.available_values(*)
Status.find(:all, :order => 'name').map { |i| [i.name, i.id] }
Status.find(:all, order: 'name').map { |i| [i.name, i.id] }
end
end

@ -25,6 +25,6 @@ class CostQuery::Filter::Tmonth < Report::Filter::Base
end
def self.available_values(*)
1.upto(12).map {|i| [ ::I18n.t('date.month_names')[i], i ]}
1.upto(12).map { |i| [::I18n.t('date.month_names')[i], i] }
end
end

@ -25,6 +25,6 @@ class CostQuery::Filter::Tweek < Report::Filter::Base
end
def self.available_values(*)
1.upto(53).map {|i| [ i.to_s, i ]}
1.upto(53).map { |i| [i.to_s, i] }
end
end

@ -25,6 +25,6 @@ class CostQuery::Filter::Tyear < Report::Filter::Base
end
def self.available_values(*)
1970.upto(Date.today.year).map {|i| [ i.to_s, i ]}.reverse
1970.upto(Date.today.year).map { |i| [i.to_s, i] }.reverse
end
end

@ -26,6 +26,6 @@ class CostQuery::Filter::TypeId < Report::Filter::Base
end
def self.available_values(*)
Type.find(:all, :order => 'name').map { |i| [i.name, i.id] }
Type.find(:all, order: 'name').map { |i| [i.name, i.id] }
end
end

@ -18,7 +18,7 @@
#++
class CostQuery::Filter::UpdatedOn < Report::Filter::Base
db_field "entries.updated_on"
db_field 'entries.updated_on'
use :time_operators
def self.label

@ -23,9 +23,9 @@ class CostQuery::Filter::UserId < Report::Filter::Base
end
def self.available_values(*)
users = Project.visible.collect {|p| p.users}.flatten.uniq.sort
users = Project.visible.collect(&:users).flatten.uniq.sort
values = users.map { |u| [u.name, u.id] }
values.delete_if { |u| (u.first.include? "OpenProject Admin") || (u.first.include? "Anonymous")}
values.delete_if { |u| (u.first.include? 'OpenProject Admin') || (u.first.include? 'Anonymous') }
values.sort!
values.unshift ["<< #{::I18n.t(:label_me)} >>", User.current.id.to_s] if User.current.logged?
values

@ -18,13 +18,12 @@
#++
class CostQuery::Filter::WorkPackageId < Report::Filter::Base
def self.label
WorkPackage.model_name.human
end
def self.available_values(*)
work_packages = Project.visible.collect { |p| p.work_packages }.flatten.uniq.sort_by { |i| i.id }
work_packages = Project.visible.map { |p| p.work_packages }.flatten.uniq.sort_by { |i| i.id }
work_packages.map { |i| [text_for_work_package(i), i.id] }
end
@ -45,12 +44,12 @@ class CostQuery::Filter::WorkPackageId < Report::Filter::Base
def self.text_for_work_package(i)
i = i.first if i.is_a? Array
str = "##{i.id} "
str << (i.subject.length > 30 ? i.subject.first(26)+'...': i.subject)
str << (i.subject.length > 30 ? i.subject.first(26) + '...' : i.subject)
end
def self.text_for_id(i)
text_for_work_package WorkPackage.find(i)
rescue ActiveRecord::RecordNotFound
""
''
end
end

@ -23,7 +23,7 @@ class CostQuery::GroupBy
def sql_statement
super.tap do |sql|
sql.sum :units => :units, :real_costs => :real_costs, :display_costs => :display_costs
sql.sum units: :units, real_costs: :real_costs, display_costs: :display_costs
end
end
end

@ -19,7 +19,7 @@
class CostQuery::Operator < Report::Operator
# Operators from Redmine
new "c", :arity => 0, :label => :label_closed do
new "c", arity: 0, label: :label_closed do
def modify(query, field, *values)
raise "wrong field" if field.to_s.split('.').last != "status_id"
query.where "(#{Status.table_name}.is_closed = #{quoted_true})"
@ -27,7 +27,7 @@ class CostQuery::Operator < Report::Operator
end
end
new "o", :arity => 0, :label => :label_open do
new "o", arity: 0, label: :label_open do
def modify(query, field, *values)
raise "wrong field" if field.to_s.split('.').last != "status_id"
query.where "(#{Status.table_name}.is_closed = #{quoted_false})"
@ -35,7 +35,7 @@ class CostQuery::Operator < Report::Operator
end
end
new "=_child_projects", :validate => :integers, :label => :label_is_project_with_subprojects do
new "=_child_projects", validate: :integers, label: :label_is_project_with_subprojects do
def modify(query, field, *values)
p_ids = []
values.each do |value|
@ -47,7 +47,7 @@ class CostQuery::Operator < Report::Operator
end
end
new "!_child_projects", :validate => :integers, :label => :label_is_not_project_with_subprojects do
new "!_child_projects", validate: :integers, label: :label_is_not_project_with_subprojects do
def modify(query, field, *values)
p_ids = []
values.each do |value|

@ -77,10 +77,10 @@ class CostQuery::SqlStatement < Report::SqlStatement
query.select COMMON_FIELDS
query.desc = "Subquery for #{table}"
query.select({
:count => 1, :id => [model, :id], :display_costs => 1,
:real_costs => switch("#{table}.overridden_costs IS NULL" => [model, :costs], :else => [model, :overridden_costs]),
:week => iso_year_week(:spent_on, model),
:singleton_value => 1 })
count: 1, id: [model, :id], display_costs: 1,
real_costs: switch("#{table}.overridden_costs IS NULL" => [model, :costs], else: [model, :overridden_costs]),
week: iso_year_week(:spent_on, model),
singleton_value: 1 })
#FIXME: build this subquery from a sql_statement
query.from "(SELECT *, #{typed :text, model.model_name} AS type FROM #{table}) AS #{table}"
send("unify_#{table}", query)
@ -92,8 +92,8 @@ class CostQuery::SqlStatement < Report::SqlStatement
#
# @param [CostQuery::SqlStatement] query The statement to adjust
def self.unify_time_entries(query)
query.select :activity_id, :units => :hours, :cost_type_id => -1
query.select :cost_type => quoted_label(:caption_labor)
query.select :activity_id, units: :hours, cost_type_id: -1
query.select cost_type: quoted_label(:caption_labor)
end
##
@ -101,8 +101,8 @@ class CostQuery::SqlStatement < Report::SqlStatement
#
# @param [CostQuery::SqlStatement] query The statement to adjust
def self.unify_cost_entries(query)
query.select :units, :cost_type_id, :activity_id => -1
query.select :cost_type => "cost_types.name"
query.select :units, :cost_type_id, activity_id: -1
query.select cost_type: "cost_types.name"
query.join CostType
end

@ -119,7 +119,7 @@ Given /^I group (rows|columns) by "([^\"]*)"/ do |target, group|
end
Given /^I remove "([^\"]*)" from (rows|columns)/ do |group, source|
element_name = find_by_id("group_by_#{source}").find("label", :text => "#{group}")[:for]
element_name = find_by_id("group_by_#{source}").find("label", text: "#{group}")[:for]
find_by_id("#{element_name}_remove").click
end

@ -17,5 +17,5 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#++
ScenarioDisabler.disable(:feature => "Tracking Time", :scenario => "Adding a time entry")
ScenarioDisabler.disable(:feature => "Tracking Time", :scenario => "Editing a time entry")
ScenarioDisabler.disable(feature: "Tracking Time", scenario: "Adding a time entry")
ScenarioDisabler.disable(feature: "Tracking Time", scenario: "Editing a time entry")

@ -24,16 +24,16 @@ module OpenProject::Reporting
include OpenProject::Plugins::ActsAsOpEngine
register 'openproject-reporting',
:author_url => 'http://finn.de',
:requires_openproject => '>= 4.0.0' do
author_url: 'http://finn.de',
requires_openproject: '>= 4.0.0' do
view_actions = [:index, :show, :drill_down, :available_values, :display_report_list]
edit_actions = [:create, :update, :rename, :delete]
#register reporting_module including permissions
project_module :reporting_module do
permission :save_cost_reports, {:cost_reports => edit_actions}
permission :save_private_cost_reports, {:cost_reports => edit_actions}
permission :save_cost_reports, {cost_reports: edit_actions}
permission :save_private_cost_reports, {cost_reports: edit_actions}
end
#register additional permissions for viewing time and cost entries through the CostReportsController
@ -45,23 +45,23 @@ module OpenProject::Reporting
end
#menu extensions
menu :top_menu, :cost_reports_global, {:controller => 'cost_reports', :action => 'index', :project_id => nil},
:caption => :cost_reports_title,
:if => Proc.new {
( User.current.allowed_to?(:view_time_entries, nil, :global => true) ||
User.current.allowed_to?(:view_own_time_entries, nil, :global => true) ||
User.current.allowed_to?(:view_cost_entries, nil, :global => true) ||
User.current.allowed_to?(:view_own_cost_entries, nil, :global => true)
menu :top_menu, :cost_reports_global, {controller: 'cost_reports', action: 'index', project_id: nil},
caption: :cost_reports_title,
if: Proc.new {
( User.current.allowed_to?(:view_time_entries, nil, global: true) ||
User.current.allowed_to?(:view_own_time_entries, nil, global: true) ||
User.current.allowed_to?(:view_cost_entries, nil, global: true) ||
User.current.allowed_to?(:view_own_cost_entries, nil, global: true)
)
}
menu :project_menu, :cost_reports,
{:controller => 'cost_reports', :action => 'index'},
:param => :project_id,
:after => :cost_objects,
:caption => :cost_reports_title,
:if => Proc.new { |project| project.module_enabled?(:reporting_module) },
:html => {:class => 'icon2 icon-stats'}
{controller: 'cost_reports', action: 'index'},
param: :project_id,
after: :cost_objects,
caption: :cost_reports_title,
if: Proc.new { |project| project.module_enabled?(:reporting_module) },
html: {class: 'icon2 icon-stats'}
end
initializer "reporting.register_hooks" do

@ -18,5 +18,5 @@
#++
class ViewProjectsShowSidebarBottomHook < Redmine::Hook::ViewListener
render_on :view_projects_show_sidebar_bottom, :partial => 'hooks/view_projects_show_sidebar_bottom_hook'
render_on :view_projects_show_sidebar_bottom, partial: 'hooks/view_projects_show_sidebar_bottom_hook'
end

@ -39,7 +39,7 @@ module OpenProject::Reporting::Patches
# This is for cost reporting
def redirect_to(*args, &block)
if args.first == :back and args.size == 1 and request.referer =~ /cost_reports/
super(:controller => '/cost_reports', :action => :index)
super(controller: '/cost_reports', action: :index)
else
super(*args, &block)
end
@ -50,11 +50,11 @@ module OpenProject::Reporting::Patches
if @project.nil? || !@project.module_enabled?(:reporting_module)
return index_without_reports_view
end
filters = {:operators => {}, :values => {}}
filters = {operators: {}, values: {}}
if @work_package
if @work_package.respond_to?("lft")
work_package_ids = WorkPackage.all(:select => :id, :conditions => ["root_id = ? AND lft >= ? AND rgt <= ?", @work_package.root_id, @work_package.lft, @work_package.rgt]).collect{|i| i.id}
work_package_ids = WorkPackage.all(select: :id, conditions: ["root_id = ? AND lft >= ? AND rgt <= ?", @work_package.root_id, @work_package.lft, @work_package.rgt]).collect{|i| i.id}
else
work_package_ids = [@work_package.id]
end
@ -68,12 +68,12 @@ module OpenProject::Reporting::Patches
respond_to do |format|
format.html {
session[CostQuery.name.underscore.to_sym] = { :filters => filters, :groups => {:rows => [], :columns => []} }
session[CostQuery.name.underscore.to_sym] = { filters: filters, groups: {rows: [], columns: []} }
if @cost_type
redirect_to :controller => "/cost_reports", :action => "index", :project_id => @project, :unit => @cost_type.id
redirect_to controller: "/cost_reports", action: "index", project_id: @project, unit: @cost_type.id
else
redirect_to :controller => "/cost_reports", :action => "index", :project_id => @project
redirect_to controller: "/cost_reports", action: "index", project_id: @project
end
return
}
@ -85,8 +85,8 @@ module OpenProject::Reporting::Patches
def find_optional_project_with_own
find_optional_project_without_own
deny_access unless User.current.allowed_to?(:view_cost_entries, @project, :global => true) ||
User.current.allowed_to?(:view_own_cost_entries, @project, :global => true)
deny_access unless User.current.allowed_to?(:view_cost_entries, @project, global: true) ||
User.current.allowed_to?(:view_own_cost_entries, @project, global: true)
end
end
end

@ -39,7 +39,7 @@ module OpenProject::Reporting::Patches
# This is for cost reporting
def redirect_to(*args, &block)
if args.first == :back and args.size == 1 and request.referer =~ /cost_reports/
super(:controller => '/cost_reports', :action => :index)
super(controller: '/cost_reports', action: :index)
else
super(*args, &block)
end
@ -50,11 +50,11 @@ module OpenProject::Reporting::Patches
if @project.nil? || !@project.module_enabled?(:reporting_module)
return index_without_reports_view
end
filters = {:operators => {}, :values => {}}
filters = {operators: {}, values: {}}
if @issue
if @issue.respond_to?("lft")
work_package_ids = WorkPackage.all(:select => :id, :conditions => ["root_id = ? AND lft >= ? AND rgt <= ?", @issue.root_id, @issue.lft, @issue.rgt]).collect{|i| i.id.to_s}
work_package_ids = WorkPackage.all(select: :id, conditions: ["root_id = ? AND lft >= ? AND rgt <= ?", @issue.root_id, @issue.lft, @issue.rgt]).collect{|i| i.id.to_s}
else
work_package_ids = [@issue.id.to_s]
end
@ -68,9 +68,9 @@ module OpenProject::Reporting::Patches
respond_to do |format|
format.html {
session[::CostQuery.name.underscore.to_sym] = { :filters => filters, :groups => {:rows => [], :columns => []} }
session[::CostQuery.name.underscore.to_sym] = { filters: filters, groups: {rows: [], columns: []} }
redirect_to :controller => "/cost_reports", :action => "index", :project_id => @project, :unit => -1
redirect_to controller: "/cost_reports", action: "index", project_id: @project, unit: -1
}
format.all {
index_without_report_view
@ -85,8 +85,8 @@ module OpenProject::Reporting::Patches
elsif !params[:project_id].blank?
@project = Project.find(params[:project_id])
end
deny_access unless User.current.allowed_to?(:view_time_entries, @project, :global => true) ||
User.current.allowed_to?(:view_own_time_entries, @project, :global => true)
deny_access unless User.current.allowed_to?(:view_time_entries, @project, global: true) ||
User.current.allowed_to?(:view_own_time_entries, @project, global: true)
end
end
end

@ -23,27 +23,27 @@ class Widget::Table::EntryTable < Widget::Table
detailed_table self
def render
content = content_tag :table, { :class => "report detail-report", :id => "sortable-table" } do
content = content_tag :table, { class: "report detail-report", id: "sortable-table" } do
concat head
concat foot
concat body
end
# FIXME do that js-only, like a man's man
render_widget Widget::Table::SortableInit, @subject, :to => content, :sort_first_row => true
render_widget Widget::Table::SortableInit, @subject, to: content, sort_first_row: true
write content
end
def head
content_tag :thead do
content_tag :tr do
Fields.collect { |field| concat content_tag(:th) { label_for(field) } }
concat content_tag(:th, :class => 'right') { cost_type.try(:unit_plural) || l(:units) }
concat content_tag(:th, :class => 'right') { CostEntry.human_attribute_name(:costs) }
Fields.map { |field| concat content_tag(:th) { label_for(field) } }
concat content_tag(:th, class: 'right') { cost_type.try(:unit_plural) || l(:units) }
concat content_tag(:th, class: 'right') { CostEntry.human_attribute_name(:costs) }
hit = false
@subject.each_direct_result do |result|
next if hit
if entry_for(result).editable_by? User.current
concat content_tag(:th, :class => "unsortable") { "&nbsp;".html_safe }
concat content_tag(:th, class: "unsortable") { "&nbsp;".html_safe }
hit = true
end
end
@ -55,12 +55,12 @@ class Widget::Table::EntryTable < Widget::Table
content_tag :tfoot do
content_tag :tr do
if show_result(@subject, 0) != show_result(@subject)
concat content_tag(:th, show_result(@subject), :class => "inner right", :colspan => Fields.size + 1)
concat content_tag(:th, show_result(@subject, 0), :class => "result right")
concat content_tag(:th, show_result(@subject), class: "inner right", colspan: Fields.size + 1)
concat content_tag(:th, show_result(@subject, 0), class: "result right")
else
concat content_tag(:th, show_result(@subject), :class => "result right", :colspan => Fields.size + 2)
concat content_tag(:th, show_result(@subject), class: "result right", colspan: Fields.size + 2)
end
concat content_tag(:th, "", :class => "unsortable")
concat content_tag(:th, "", class: "unsortable")
end
end
end
@ -70,18 +70,18 @@ class Widget::Table::EntryTable < Widget::Table
rows = "".html_safe
@subject.each_direct_result do |result|
odd = !odd
rows << (content_tag(:tr, :class => (odd ? "odd" : "even")) do
rows << (content_tag(:tr, class: (odd ? "odd" : "even")) do
"".html_safe
Fields.each do |field|
concat content_tag(:td, show_field(field, result.fields[field.to_s]).html_safe,
:"raw-data" => raw_field(field, result.fields[field.to_s]),
:class => "left")
class: "left")
end
concat content_tag :td, show_result(result, result.fields['cost_type_id'].to_i).html_safe,
:class => "units right", :"raw-data" => result.units
class: "units right", :"raw-data" => result.units
concat content_tag :td, (show_result(result, 0)).html_safe,
:class => "currency right", :"raw-data" => result.real_costs
concat content_tag :td, icons(result), :style => "width: 40px"
class: "currency right", :"raw-data" => result.real_costs
concat content_tag :td, icons(result), style: "width: 40px"
end)
end
rows
@ -93,16 +93,16 @@ class Widget::Table::EntryTable < Widget::Table
with_project(result.fields['project_id']) do
if entry_for(result).editable_by? User.current
icons = link_to(icon_wrapper('icon-context icon-edit', l(:button_edit)),
action_for(result, :action => 'edit'),
:class => 'no-decoration-on-hover',
:title => l(:button_edit))
action_for(result, action: 'edit'),
class: 'no-decoration-on-hover',
title: l(:button_edit))
icons << link_to(icon_wrapper('icon-context icon-delete', l(:button_delete)),
(action_for(result, :action => 'destroy').reverse_merge(:authenticity_token => form_authenticity_token)),
:title => l(:button_edit),
:confirm => l(:text_are_you_sure),
:method => :delete,
:class => 'no-decoration-on-hover',
:title => l(:button_delete))
(action_for(result, action: 'destroy').reverse_merge(authenticity_token: form_authenticity_token)),
title: l(:button_edit),
confirm: l(:text_are_you_sure),
method: :delete,
class: 'no-decoration-on-hover',
title: l(:button_delete))
end
end
icons

@ -27,10 +27,10 @@ class Widget::Settings < Widget::Base
@@settings_to_render.insert -2, :cost_types
def render_cost_types_settings
render_widget Widget::Settings::Fieldset, @subject, { :type => "units" } do
render_widget Widget::Settings::Fieldset, @subject, { type: "units" } do
render_widget Widget::CostTypes,
@cost_types,
:selected_type_id => @selected_type_id
selected_type_id: @selected_type_id
end
end

@ -21,16 +21,16 @@ class Widget::Table::SimpleTable < Widget::Table
simple_table self
def render
@list = @subject.collect {|r| r.important_fields }.flatten.uniq
@list = @subject.map {|r| r.important_fields }.flatten.uniq
@show_units = @list.include? "cost_type_id"
content = content_tag :table, { :class => "report", :id => "sortable-table" } do
content = content_tag :table, { class: "report", id: "sortable-table" } do
concat head
concat foot
concat body
end
# FIXME do that js-only, like a man's man
render_widget Widget::Table::SortableInit, @subject, :to => content
render_widget Widget::Table::SortableInit, @subject, to: content
write content.html_safe
end
@ -38,10 +38,10 @@ class Widget::Table::SimpleTable < Widget::Table
content_tag :thead do
content_tag :tr do
@list.each do |field|
concat content_tag(:th, :class => "right") { label_for(field) }
concat content_tag(:th, class: "right") { label_for(field) }
end
concat content_tag(:th, :class => "right") { label_for(:units) } if @show_units
concat content_tag(:th, :class => "right") { label_for(:label_sum) }
concat content_tag(:th, class: "right") { label_for(:units) } if @show_units
concat content_tag(:th, class: "right") { label_for(:label_sum) }
end
end
end
@ -49,8 +49,8 @@ class Widget::Table::SimpleTable < Widget::Table
def foot
content_tag :tfoot do
content_tag :tr do
concat content_tag(:th, '', :class => "result inner", :colspan => @list.size)
concat content_tag(:th, show_result(@subject), (@show_units ? {:class => "result right", :colspan => "2"} : {:class => "result right"}))
concat content_tag(:th, '', class: "result inner", colspan: @list.size)
concat content_tag(:th, show_result(@subject), (@show_units ? {class: "result right", colspan: "2"} : {class: "result right"}))
end
end
end
@ -58,7 +58,7 @@ class Widget::Table::SimpleTable < Widget::Table
def body
content_tag :tbody do
@subject.each do |result|
concat (content_tag :tr, :class => cycle("odd", "even") do
concat (content_tag :tr, class: cycle("odd", "even") do
concat (content_tag :td, :'raw-data' => raw_field(*result.fields.first) do
show_row result
end)

@ -22,7 +22,7 @@ class Widget::Table::SortableInit < Widget::Base
def render
sort_first_row = @options[:sort_first_row] || false
write (content_tag :script, :type => "text/javascript" do
write (content_tag :script, type: "text/javascript" do
content = %Q{//<![CDATA[
var table_date_header = $$('#sortable-table th').first();
sortables_init(); }.html_safe

@ -19,7 +19,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe CostReportsController, :type => :controller do
describe CostReportsController, type: :controller do
include OpenProject::Reporting::PluginSpecHelper
let(:user) { FactoryGirl.build(:user) }
@ -34,7 +34,7 @@ describe CostReportsController, :type => :controller do
describe "WHEN providing invalid units
WHEN having the view_cost_entries permission" do
before do
get :show, :id => 1, :unit => -1
get :show, id: 1, unit: -1
end
it "should respond with a 404 error" do

@ -19,8 +19,8 @@
FactoryGirl.define do
factory :cost_query do
association :user, :factory => :user
association :project, :factory => :project
association :user, factory: :user
association :project, factory: :project
sequence(:name) { |n| "Cost Query #{n}" }
factory :private_cost_query do
is_public false

@ -19,7 +19,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery, type: :model, reporting_query_helper: true do
let(:project) { FactoryGirl.create(:project) }
minimal_query
@ -107,14 +107,14 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
@query.filter :project_id
@query.group_by :project_id
expect(@query.filters.size).to eq(2)
expect(@query.filters.collect {|f| f.class.underscore_name}).to include "project_id"
expect(@query.filters.map {|f| f.class.underscore_name}).to include "project_id"
end
it "should return all group_bys" do
@query.filter :project_id
@query.group_by :project_id
expect(@query.group_bys.size).to eq(1)
expect(@query.group_bys.collect {|g| g.class.underscore_name}).to include "project_id"
expect(@query.group_bys.map {|g| g.class.underscore_name}).to include "project_id"
end
it "should initialize the chain through a block" do
@ -123,17 +123,17 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
CostQuery
end
end
TestFilter.send(:initialize_query_with) {|query| query.filter(:project_id, :value => project.id)}
TestFilter.send(:initialize_query_with) {|query| query.filter(:project_id, value: project.id)}
@query.build_new_chain
expect(@query.filters.collect {|f| f.class.underscore_name}).to include "project_id"
expect(@query.filters.map {|f| f.class.underscore_name}).to include "project_id"
expect(@query.filters.detect {|f| f.class.underscore_name == "project_id"}.values).to eq(Array(project.id))
end
context "store and load" do
before do
@query.filter :project_id, :value => project.id
@query.filter :cost_type_id, :value => CostQuery::Filter::CostTypeId.available_values.first
@query.filter :category_id, :value => CostQuery::Filter::CategoryId.available_values.first
@query.filter :project_id, value: project.id
@query.filter :cost_type_id, value: CostQuery::Filter::CostTypeId.available_values.first
@query.filter :category_id, value: CostQuery::Filter::CategoryId.available_values.first
@query.group_by :activity_id
@query.group_by :cost_object_id
@query.group_by :cost_type_id
@ -202,7 +202,7 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
describe :inherited_attribute do
before do
@a = Class.new Report::Chainable
@a.inherited_attribute :foo, :default => 42
@a.inherited_attribute :foo, default: 42
@b = Class.new @a
@c = Class.new @a
@d = Class.new @b
@ -227,14 +227,14 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it 'is able to map values' do
@a.inherited_attribute :bar, :map => proc { |x| x*2 }
@a.inherited_attribute :bar, map: proc { |x| x*2 }
@a.bar 21
expect(@a.bar).to eq(42)
end
describe :list do
it "merges lists" do
@a.inherited_attribute :bar, :list => true
@a.inherited_attribute :bar, list: true
@a.bar 1; @b.bar 2; @d.bar 3, 4
expect(@a.bar).to eq([1])
expect(@b.bar.sort).to eq([1, 2])
@ -243,7 +243,7 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "is able to map lists" do
@a.inherited_attribute :bar, :list => true, :map => :to_s
@a.inherited_attribute :bar, list: true, map: :to_s
@a.bar 1; @b.bar 1; @d.bar 1
expect(@a.bar).to eq(%w[1])
expect(@b.bar).to eq(%w[1 1])
@ -252,14 +252,14 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "is able to produce uniq lists" do
@a.inherited_attribute :bar, :list => true, :uniq => true
@a.inherited_attribute :bar, list: true, uniq: true
@a.bar 1, 1, 2
@b.bar 2, 3
expect(@b.bar.sort).to eq([1, 2, 3])
end
it "keeps old entries" do
@a.inherited_attribute :bar, :list => true
@a.inherited_attribute :bar, list: true
@a.bar 1
@a.bar 2
expect(@a.bar.sort).to eq([1, 2])

@ -19,7 +19,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
describe User, "#destroy", :type => :model do
describe User, "#destroy", type: :model do
let(:substitute_user) { DeletedUser.first }
let(:private_query) { FactoryGirl.create(:private_cost_query) }
let(:public_query) { FactoryGirl.create(:public_cost_query) }
@ -49,7 +49,7 @@ describe User, "#destroy", :type => :model do
describe "WHEN the filter has the deleted user as it's value" do
before do
public_query.filter(filter_symbol, :values => [user.id.to_s], :operator => "=")
public_query.filter(filter_symbol, values: [user.id.to_s], operator: "=")
public_query.save!
user.destroy
@ -60,7 +60,7 @@ describe User, "#destroy", :type => :model do
describe "WHEN the filter has another user as it's value" do
before do
public_query.filter(filter_symbol, :values => [user2.id.to_s], :operator => "=")
public_query.filter(filter_symbol, values: [user2.id.to_s], operator: "=")
public_query.save!
user.destroy
@ -72,7 +72,7 @@ describe User, "#destroy", :type => :model do
describe "WHEN the filter has the deleted user and another user as it's value" do
before do
public_query.filter(filter_symbol, :values => [user.id.to_s, user2.id.to_s], :operator => "=")
public_query.filter(filter_symbol, values: [user.id.to_s, user2.id.to_s], operator: "=")
public_query.save!
user.destroy

@ -19,18 +19,18 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery, type: :model, reporting_query_helper: true do
minimal_query
let!(:project) { FactoryGirl.create(:project_with_types) }
let!(:user) { FactoryGirl.create(:user, :member_in_project => project) }
let!(:user) { FactoryGirl.create(:user, member_in_project: project) }
def create_work_package_with_entry(entry_type, work_package_params={}, entry_params = {})
work_package_params = {:project => project}.merge!(work_package_params)
work_package_params = {project: project}.merge!(work_package_params)
work_package = FactoryGirl.create(:work_package, work_package_params)
entry_params = {:work_package => work_package,
:project => work_package_params[:project],
:user => user}.merge!(entry_params)
entry_params = {work_package: work_package,
project: work_package_params[:project],
user: user}.merge!(entry_params)
FactoryGirl.create(entry_type, entry_params)
work_package
end
@ -68,43 +68,43 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
describe filter do
let!(:non_matching_entry) { FactoryGirl.create(:cost_entry) }
let!(:object) { send(object_name) }
let!(:author) { FactoryGirl.create(:user, :member_in_project => project) }
let!(:work_package) { FactoryGirl.create(:work_package, :project => project,
:author => author) }
let!(:author) { FactoryGirl.create(:user, member_in_project: project) }
let!(:work_package) { FactoryGirl.create(:work_package, project: project,
author: author) }
let!(:cost_type) { FactoryGirl.create(:cost_type) }
let!(:cost_entry) { FactoryGirl.create(:cost_entry, :work_package => work_package,
:user => user,
:project => project,
:cost_type => cost_type) }
let!(:cost_entry) { FactoryGirl.create(:cost_entry, work_package: work_package,
user: user,
project: project,
cost_type: cost_type) }
let!(:activity) { FactoryGirl.create(:time_entry_activity) }
let!(:time_entry) { FactoryGirl.create(:time_entry, :work_package => work_package,
:user => user,
:project => project,
:activity => activity) }
let!(:time_entry) { FactoryGirl.create(:time_entry, work_package: work_package,
user: user,
project: project,
activity: activity) }
it "should only return entries from the given #{filter.to_s}" do
@query.filter field, :value => object.id
@query.filter field, value: object.id
@query.result.each do |result|
expect(result[field].to_s).to eq(object.id.to_s)
end
end
it "should allow chaining the same filter" do
@query.filter field, :value => object.id
@query.filter field, :value => object.id
@query.filter field, value: object.id
@query.filter field, value: object.id
@query.result.each do |result|
expect(result[field].to_s).to eq(object.id.to_s)
end
end
it "should return no results for excluding filters" do
@query.filter field, :value => object.id
@query.filter field, :value => object.id + 1
@query.filter field, value: object.id
@query.filter field, value: object.id + 1
expect(@query.result.count).to eq(0)
end
it "should compute the correct number of results" do
@query.filter field, :value => object.id
@query.filter field, value: object.id
expect(@query.result.count).to eq(expected_count)
end
end
@ -114,22 +114,22 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery::Filter::AuthorId do
let!(:non_matching_entry) { FactoryGirl.create(:cost_entry) }
let!(:author) { FactoryGirl.create(:user, :member_in_project => project) }
let!(:work_package) { FactoryGirl.create(:work_package, :project => project,
:author => author) }
let!(:author) { FactoryGirl.create(:user, member_in_project: project) }
let!(:work_package) { FactoryGirl.create(:work_package, project: project,
author: author) }
let!(:cost_type) { FactoryGirl.create(:cost_type) }
let!(:cost_entry) { FactoryGirl.create(:cost_entry, :work_package => work_package,
:user => user,
:project => project,
:cost_type => cost_type) }
let!(:cost_entry) { FactoryGirl.create(:cost_entry, work_package: work_package,
user: user,
project: project,
cost_type: cost_type) }
let!(:activity) { FactoryGirl.create(:time_entry_activity) }
let!(:time_entry) { FactoryGirl.create(:time_entry, :work_package => work_package,
:user => user,
:project => project,
:activity => activity) }
let!(:time_entry) { FactoryGirl.create(:time_entry, work_package: work_package,
user: user,
project: project,
activity: activity) }
it "should only return entries from the given CostQuery::Filter::AuthorId" do
@query.filter 'author_id', :value => author.id
@query.filter 'author_id', value: author.id
@query.result.each do |result|
work_package_id = result["work_package_id"]
expect(WorkPackage.find(work_package_id).author.id).to eq(author.id)
@ -137,8 +137,8 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "should allow chaining the same filter" do
@query.filter 'author_id', :value => author.id
@query.filter 'author_id', :value => author.id
@query.filter 'author_id', value: author.id
@query.filter 'author_id', value: author.id
@query.result.each do |result|
work_package_id = result["work_package_id"]
expect(WorkPackage.find(work_package_id).author.id).to eq(author.id)
@ -146,30 +146,30 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "should return no results for excluding filters" do
@query.filter 'author_id', :value => author.id
@query.filter 'author_id', :value => author.id + 1
@query.filter 'author_id', value: author.id
@query.filter 'author_id', value: author.id + 1
expect(@query.result.count).to eq(0)
end
it "should compute the correct number of results" do
@query.filter 'author_id', :value => author.id
@query.filter 'author_id', value: author.id
expect(@query.result.count).to eq(2)
end
end
it "filters spent_on" do
@query.filter :spent_on, :operator=> 'w'
@query.filter :spent_on, operator: 'w'
expect(@query.result.count).to eq(Entry.all.select { |e| e.spent_on.cweek == TimeEntry.all.first.spent_on.cweek }.count)
end
it "filters created_on" do
@query.filter :created_on, :operator => 't'
@query.filter :created_on, operator: 't'
# we assume that some of our fixtures set created_on to Time.now
expect(@query.result.count).to eq(Entry.all.select { |e| e.created_on.to_date == Date.today }.count)
end
it "filters updated_on" do
@query.filter :updated_on, :value => Date.today.years_ago(20), :operator => '>d'
@query.filter :updated_on, value: Date.today.years_ago(20), operator: '>d'
# we assume that our were updated in the last 20 years
expect(@query.result.count).to eq(Entry.all.select { |e| e.updated_on.to_date > Date.today.years_ago(20) }.count)
end
@ -178,10 +178,10 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
old_user = User.current
# create non-matching entry
anonymous = FactoryGirl.create(:anonymous)
create_work_package_with_time_entry({}, {:user => anonymous})
create_work_package_with_time_entry({}, {user: anonymous})
# create matching entry
create_work_package_with_time_entry()
@query.filter :user_id, :value => user.id, :operator => '='
@query.filter :user_id, value: user.id, operator: '='
expect(@query.result.count).to eq(1)
end
@ -199,80 +199,80 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "filters overridden_costs" do
@query.filter :overridden_costs, :operator => 'y'
@query.filter :overridden_costs, operator: 'y'
expect(@query.result.count).to eq(Entry.all.select { |e| not e.overridden_costs.nil? }.count)
end
it "filters status" do
matching_status = FactoryGirl.create(:status, :is_closed => true)
create_work_packages_and_time_entries(3, :status => matching_status)
@query.filter :status_id, :operator => 'c'
matching_status = FactoryGirl.create(:status, is_closed: true)
create_work_packages_and_time_entries(3, status: matching_status)
@query.filter :status_id, operator: 'c'
expect(@query.result.count).to eq(3)
end
it "filters types" do
matching_type = project.types.first
create_work_packages_and_time_entries(3, :type => matching_type)
@query.filter :type_id, :operator => '=', :value => matching_type.id
create_work_packages_and_time_entries(3, type: matching_type)
@query.filter :type_id, operator: '=', value: matching_type.id
expect(@query.result.count).to eq(3)
end
it "filters work_package authors" do
matching_author = create_matching_object_with_time_entries(:user, :author, 3)
@query.filter :author_id, :operator => '=', :value => matching_author.id
@query.filter :author_id, operator: '=', value: matching_author.id
expect(@query.result.count).to eq(3)
end
it "filters priority" do
matching_priority = create_matching_object_with_time_entries(:priority, :priority, 3)
@query.filter :priority_id, :operator => '=', :value => matching_priority.id
@query.filter :priority_id, operator: '=', value: matching_priority.id
expect(@query.result.count).to eq(3)
end
it "filters assigned to" do
matching_user = create_matching_object_with_time_entries(:user, :assigned_to, 3)
@query.filter :assigned_to_id, :operator => '=', :value => matching_user.id
@query.filter :assigned_to_id, operator: '=', value: matching_user.id
expect(@query.result.count).to eq(3)
end
it "filters category" do
category = create_matching_object_with_time_entries(:category, :category, 3)
@query.filter :category_id, :operator => '=', :value => category.id
@query.filter :category_id, operator: '=', value: category.id
expect(@query.result.count).to eq(3)
end
it "filters target version" do
matching_version = FactoryGirl.create(:version, :project => project)
create_work_packages_and_time_entries(3, :fixed_version => matching_version)
matching_version = FactoryGirl.create(:version, project: project)
create_work_packages_and_time_entries(3, fixed_version: matching_version)
@query.filter :fixed_version_id, :operator => '=', :value => matching_version.id
@query.filter :fixed_version_id, operator: '=', value: matching_version.id
expect(@query.result.count).to eq(3)
end
it "filters subject" do
matching_work_package = create_work_package_with_time_entry(:subject => 'matching subject')
@query.filter :subject, :operator => '=', :value => 'matching subject'
matching_work_package = create_work_package_with_time_entry(subject: 'matching subject')
@query.filter :subject, operator: '=', value: 'matching subject'
expect(@query.result.count).to eq(1)
end
it "filters start" do
start_date = Date.new(2013, 1, 1)
matching_work_package = create_work_package_with_time_entry(:start_date => start_date)
@query.filter :start_date, :operator => '=d', :value => start_date
matching_work_package = create_work_package_with_time_entry(start_date: start_date)
@query.filter :start_date, operator: '=d', value: start_date
expect(@query.result.count).to eq(1)
#Entry.all.select { |e| e.work_package.start_date == WorkPackage.all(:order => "id ASC").first.start_date }.count
end
it "filters due date" do
due_date = Date.new(2013, 1, 1)
matching_work_package = create_work_package_with_time_entry(:due_date => due_date)
@query.filter :due_date, :operator => '=d', :value => due_date
matching_work_package = create_work_package_with_time_entry(due_date: due_date)
@query.filter :due_date, operator: '=d', value: due_date
expect(@query.result.count).to eq(1)
#Entry.all.select { |e| e.work_package.due_date == WorkPackage.all(:order => "id ASC").first.due_date }.count
end
it "raises an error if operator is not supported" do
expect { @query.filter :spent_on, :operator => 'c' }.to raise_error(ArgumentError)
expect { @query.filter :spent_on, operator: 'c' }.to raise_error(ArgumentError)
end
end
@ -318,7 +318,7 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery::Filter::CustomFieldEntries do
let!(:custom_field) do
cf = FactoryGirl.create(:work_package_custom_field,
:name => 'My custom field')
name: 'My custom field')
clear_cache
cf
end
@ -361,9 +361,9 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "should provide the correct available values" do
FactoryGirl.create(:work_package_custom_field, :name => 'Database',
:field_format => "list",
:possible_values => ['value'])
FactoryGirl.create(:work_package_custom_field, name: 'Database',
field_format: "list",
possible_values: ['value'])
clear_cache
ao = class_name_for('Database').constantize.available_operators.map(&:name)
CostQuery::Operator.null_operators.each do |o|
@ -372,15 +372,15 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "should update the available values on change" do
FactoryGirl.create(:work_package_custom_field, :name => 'Database',
:field_format => "list",
:possible_values => ['value'])
update_work_package_custom_field("Database", :field_format => "string")
FactoryGirl.create(:work_package_custom_field, name: 'Database',
field_format: "list",
possible_values: ['value'])
update_work_package_custom_field("Database", field_format: "string")
ao = class_name_for('Database').constantize.available_operators.map(&:name)
CostQuery::Operator.string_operators.each do |o|
expect(ao).to include o.name
end
update_work_package_custom_field("Database", :field_format => "int")
update_work_package_custom_field("Database", field_format: "int")
ao = class_name_for('Database').constantize.available_operators.map(&:name)
CostQuery::Operator.integer_operators.each do |o|
expect(ao).to include o.name
@ -401,33 +401,33 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
def create_searchable_fields_and_values
searchable_field = FactoryGirl.create(:work_package_custom_field,
:field_format => "text",
:name => "Searchable Field")
field_format: "text",
name: "Searchable Field")
2.times do
work_package = create_work_package_with_entry(:cost_entry)
FactoryGirl.create(:work_package_custom_value,
:custom_field => searchable_field,
:customized => work_package,
:value => "125")
custom_field: searchable_field,
customized: work_package,
value: "125")
end
work_package = create_work_package_with_entry(:cost_entry)
FactoryGirl.create(:custom_value,
:custom_field => searchable_field,
:value => "non-matching value")
custom_field: searchable_field,
value: "non-matching value")
clear_cache
end
it "is usable as filter" do
create_searchable_fields_and_values
id = WorkPackageCustomField.find_by_name("Searchable Field").id
@query.filter "custom_field_#{id}".to_sym, :operator => '=', :value => "125"
@query.filter "custom_field_#{id}".to_sym, operator: '=', value: "125"
expect(@query.result.count).to eq(2)
end
it "is usable as filter #2" do
create_searchable_fields_and_values
id = WorkPackageCustomField.find_by_name("Searchable Field").id
@query.filter "custom_field_#{id}".to_sym, :operator => '=', :value => "finnlabs"
@query.filter "custom_field_#{id}".to_sym, operator: '=', value: "finnlabs"
expect(@query.result.count).to eq(0)
end
end

@ -19,7 +19,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery, type: :model, reporting_query_helper: true do
let!(:type) { FactoryGirl.create(:type) }
let!(:project1){ FactoryGirl.create(:project_with_types, types: [type]) }
let!(:work_package1) { FactoryGirl.create(:work_package, project: project1, type: type)}
@ -228,17 +228,17 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
def create_work_package_custom_field(name)
WorkPackageCustomField.create(:name => name,
:min_length => 1,
:regexp => "",
:is_for_all => true,
:max_length => 100,
:possible_values => "",
:is_required => false,
:field_format => "string",
:searchable => true,
:default_value => "Default string",
:editable => true)
WorkPackageCustomField.create(name: name,
min_length: 1,
regexp: "",
is_for_all: true,
max_length: 100,
possible_values: "",
is_required: false,
field_format: "string",
searchable: true,
default_value: "Default string",
editable: true)
check_cache
end

@ -19,7 +19,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery, type: :model, reporting_query_helper: true do
minimal_query
let!(:project1){ FactoryGirl.create(:project_with_types) }
@ -39,7 +39,7 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
describe "the reporting system" do
it "should compute group_by and a filter" do
@query.group_by :project_id
@query.filter :status_id, :operator => 'o'
@query.filter :status_id, operator: 'o'
sql_result = @query.result
expect(sql_result.size).to eq(2)
@ -54,9 +54,9 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "should apply two filter and a group_by correctly" do
@query.filter :project_id, :operator => '=', :value => [project1.id]
@query.filter :project_id, operator: '=', value: [project1.id]
@query.group_by :user_id
@query.filter :overridden_costs, :operator => 'n'
@query.filter :overridden_costs, operator: 'n'
sql_result = @query.result
expect(sql_result.size).to eq(2)
@ -71,8 +71,8 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
end
it "should apply two different filters on the same field" do
@query.filter :project_id, :operator => '=', :value => [project1.id, project2.id]
@query.filter :project_id, :operator => '!', :value => [project2.id]
@query.filter :project_id, operator: '=', value: [project1.id, project2.id]
@query.filter :project_id, operator: '!', value: [project2.id]
sql_result = @query.result
expect(sql_result.count).to eq(2)

@ -19,7 +19,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery, type: :model, reporting_query_helper: true do
minimal_query
let!(:project1) { FactoryGirl.create(:project, name: "project1", created_on: 5.minutes.ago) }
@ -115,95 +115,95 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
#somehow this test doesn't work on sundays
n = query('projects', 'created_on', 'w').size
day_in_this_week = Time.now.at_beginning_of_week + 1.day
Project.mock! :created_on => day_in_this_week
Project.mock! created_on: day_in_this_week
expect(query('projects', 'created_on', 'w').size).to eq(n + 1)
Project.mock! :created_on => day_in_this_week + 7.days
Project.mock! :created_on => day_in_this_week - 7.days
Project.mock! created_on: day_in_this_week + 7.days
Project.mock! created_on: day_in_this_week - 7.days
expect(query('projects', 'created_on', 'w').size).to eq(n + 1)
end
it "does t (today)" do
s = query('projects', 'created_on', 't').size
Project.mock! :created_on => Date.yesterday
Project.mock! created_on: Date.yesterday
expect(query('projects', 'created_on', 't').size).to eq(s)
Project.mock! :created_on => Time.now
Project.mock! created_on: Time.now
expect(query('projects', 'created_on', 't').size).to eq(s + 1)
end
it "does <t+ (before the day which is n days in the future)" do
n = query('projects', 'created_on', '<t+', 2).size
Project.mock! :created_on => Date.tomorrow + 1
Project.mock! created_on: Date.tomorrow + 1
expect(query('projects', 'created_on', '<t+', 2).size).to eq(n + 1)
Project.mock! :created_on => Date.tomorrow + 2
Project.mock! created_on: Date.tomorrow + 2
expect(query('projects', 'created_on', '<t+', 2).size).to eq(n + 1)
end
it "does t+ (n days in the future)" do
n = query('projects', 'created_on', 't+', 1).size
Project.mock! :created_on => Date.tomorrow
Project.mock! created_on: Date.tomorrow
expect(query('projects', 'created_on', 't+', 1).size).to eq(n + 1)
Project.mock! :created_on => Date.tomorrow + 2
Project.mock! created_on: Date.tomorrow + 2
expect(query('projects', 'created_on', 't+', 1).size).to eq(n + 1)
end
it "does >t+ (after the day which is n days in the furure)" do
n = query('projects', 'created_on', '>t+', 1).size
Project.mock! :created_on => Time.now
Project.mock! created_on: Time.now
expect(query('projects', 'created_on', '>t+', 1).size).to eq(n)
Project.mock! :created_on => Date.tomorrow + 1
Project.mock! created_on: Date.tomorrow + 1
expect(query('projects', 'created_on', '>t+', 1).size).to eq(n + 1)
end
it "does >t- (after the day which is n days ago)" do
n = query('projects', 'created_on', '>t-', 1).size
Project.mock! :created_on => Date.today
Project.mock! created_on: Date.today
expect(query('projects', 'created_on', '>t-', 1).size).to eq(n + 1)
Project.mock! :created_on => Date.yesterday - 1
Project.mock! created_on: Date.yesterday - 1
expect(query('projects', 'created_on', '>t-', 1).size).to eq(n + 1)
end
it "does t- (n days ago)" do
n = query('projects', 'created_on', 't-', 1).size
Project.mock! :created_on => Date.yesterday
Project.mock! created_on: Date.yesterday
expect(query('projects', 'created_on', 't-', 1).size).to eq(n + 1)
Project.mock! :created_on => Date.yesterday - 2
Project.mock! created_on: Date.yesterday - 2
expect(query('projects', 'created_on', 't-', 1).size).to eq(n + 1)
end
it "does <t- (before the day which is n days ago)" do
n = query('projects', 'created_on', '<t-', 1).size
Project.mock! :created_on => Date.today
Project.mock! created_on: Date.today
expect(query('projects', 'created_on', '<t-', 1).size).to eq(n)
Project.mock! :created_on => Date.yesterday - 1
Project.mock! created_on: Date.yesterday - 1
expect(query('projects', 'created_on', '<t-', 1).size).to eq(n + 1)
end
#Our own operators
it "does =_child_projects" do
expect(query('projects', 'id', '=_child_projects', project1.id).size).to eq(1)
p_c1 = create_project :parent => project1
p_c1 = create_project parent: project1
expect(query('projects', 'id', '=_child_projects', project1.id).size).to eq(2)
create_project :parent => p_c1
create_project parent: p_c1
expect(query('projects', 'id', '=_child_projects', project1.id).size).to eq(3)
end
it "does =_child_projects on multiple projects" do
expect(query('projects', 'id', '=_child_projects', project1.id, project2.id).size).to eq(2)
p1_c1 = create_project :parent => project1
p2_c1 = create_project :parent => project2
p1_c1 = create_project parent: project1
p2_c1 = create_project parent: project2
expect(query('projects', 'id', '=_child_projects', project1.id, project2.id).size).to eq(4)
p1_c1_c1 = create_project :parent => p1_c1
create_project :parent => p1_c1_c1
create_project :parent => p2_c1
p1_c1_c1 = create_project parent: p1_c1
create_project parent: p1_c1_c1
create_project parent: p2_c1
expect(query('projects', 'id', '=_child_projects', project1.id, project2.id).size).to eq(7)
end
it "does !_child_projects" do
expect(query('projects', 'id', '!_child_projects', project1.id).size).to eq(1)
p_c1 = create_project :parent => project1
p_c1 = create_project parent: project1
expect(query('projects', 'id', '!_child_projects', project1.id).size).to eq(1)
create_project :parent => project1
create_project :parent => p_c1
create_project parent: project1
create_project parent: p_c1
expect(query('projects', 'id', '!_child_projects', project1.id).size).to eq(1)
create_project
expect(query('projects', 'id', '!_child_projects', project1.id).size).to eq(2)
@ -211,13 +211,13 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
it "does !_child_projects on multiple projects" do
expect(query('projects', 'id', '!_child_projects', project1.id, project2.id).size).to eq(0)
p1_c1 = create_project :parent => project1
p2_c1 = create_project :parent => project2
p1_c1 = create_project parent: project1
p2_c1 = create_project parent: project2
create_project
expect(query('projects', 'id', '!_child_projects', project1.id, project2.id).size).to eq(1)
p1_c1_c1 = create_project :parent => p1_c1
create_project :parent => p1_c1_c1
create_project :parent => p2_c1
p1_c1_c1 = create_project parent: p1_c1
create_project parent: p1_c1_c1
create_project parent: p2_c1
create_project
expect(query('projects', 'id', '!_child_projects', project1.id, project2.id).size).to eq(2)
end
@ -243,7 +243,7 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
it "does =d" do
#assuming that there aren't more than one project created at the same time
expect(query('projects', 'created_on', '=d', Project.first(:order => "id ASC").created_on).size).to eq(1)
expect(query('projects', 'created_on', '=d', Project.first(order: "id ASC").created_on).size).to eq(1)
end
it "does <d" do

@ -19,7 +19,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery, type: :model, reporting_query_helper: true do
before do
FactoryGirl.create(:admin)
project = FactoryGirl.create(:project_with_types)
@ -32,11 +32,11 @@ describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery::Result do
def direct_results(quantity = 0)
(1..quantity).collect {|i| CostQuery::Result.new :real_costs=>i.to_f, :count=>1 ,:units=>i.to_f}
(1..quantity).map {|i| CostQuery::Result.new real_costs:i.to_f, count:1 ,units:i.to_f}
end
def wrapped_result(source, quantity=1)
CostQuery::Result.new((1..quantity).collect { |i| source})
CostQuery::Result.new((1..quantity).map { |i| source})
end
it "should travel recursively depth-first" do

@ -19,7 +19,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe CostQuery::Validation, :type => :model do
describe CostQuery::Validation, type: :model do
class CostQuery::SomeBase
include CostQuery::Validation
end

@ -19,7 +19,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe CostQuery, :type => :model, :reporting_query_helper => true do
describe CostQuery, type: :model, reporting_query_helper: true do
minimal_query
before do

@ -20,11 +20,11 @@
module OpenProject::Reporting
module PluginSpecHelper
def is_member(project, user, permissions = [])
role = FactoryGirl.create(:role, :permissions => permissions)
role = FactoryGirl.create(:role, permissions: permissions)
FactoryGirl.create(:member, :project => project,
:principal => user,
:roles => [role])
FactoryGirl.create(:member, project: project,
principal: user,
roles: [role])
end
end
end

@ -20,9 +20,9 @@
class Project
def self.mock!(options = {})
time = Time.now
options = options.reverse_merge({:created_on => time,
:identifier => "#{Project.all.size}project#{time.to_i}"[0..19],
:name => "Project#{Project.all.size}"})
options = options.reverse_merge({created_on: time,
identifier: "#{Project.all.size}project#{time.to_i}"[0..19],
name: "Project#{Project.all.size}"})
generate! options
end
end

@ -29,5 +29,5 @@ module OpenProject::Reporting
end
RSpec.configure do |c|
c.extend OpenProject::Reporting::QueryHelper, :reporting_query_helper => true
c.extend OpenProject::Reporting::QueryHelper, reporting_query_helper: true
end

Loading…
Cancel
Save