wrstudios/frodata

View on GitHub
lib/frodata/entity_set.rb

Summary

Maintainability
A
25 mins
Test Coverage

Assignment Branch Condition size for << is too high. [18.63/15]
Open

    def <<(entity)
      url_chunk, options = setup_entity_post_request(entity)
      result = execute_entity_post_request(options, url_chunk)
      if entity.is_new?
        doc = ::Nokogiri::XML(result.body).remove_namespaces!
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric

Method has too many lines. [12/10]
Open

    def execute_entity_post_request(options, url_chunk)
      result = service.execute(url_chunk, options)
      unless result.code.to_s =~ /^2[0-9][0-9]$/
        service.logger.debug <<-EOS
          [ODATA: #{service_name}]
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.

Method has too many lines. [11/10]
Open

    def setup_entity_post_request(entity)
      primary_key = entity.get_property(entity.primary_key).url_value
      chunk = entity.is_new? ? name : "#{name}(#{primary_key})"
      options = {
          method: :post,
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.

Method has too many lines. [11/10]
Open

    def <<(entity)
      url_chunk, options = setup_entity_post_request(entity)
      result = execute_entity_post_request(options, url_chunk)
      if entity.is_new?
        doc = ::Nokogiri::XML(result.body).remove_namespaces!
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cop checks if the length of a method exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.

Assignment Branch Condition size for execute_entity_post_request is too high. [15.07/15]
Open

    def execute_entity_post_request(options, url_chunk)
      result = service.execute(url_chunk, options)
      unless result.code.to_s =~ /^2[0-9][0-9]$/
        service.logger.debug <<-EOS
          [ODATA: #{service_name}]
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric

FrOData::EntitySet#<< refers to 'entity' more than self (maybe move it to another class?)
Open

      if entity.is_new?
        doc = ::Nokogiri::XML(result.body).remove_namespaces!
        primary_key_node = doc.xpath("//content/properties/#{entity.primary_key}").first
        entity[entity.primary_key] = primary_key_node.content unless primary_key_node.nil?
      end
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

Example

Running Reek on:

class Warehouse
  def sale_price(item)
    (item.price - item.rebate) * @vat
  end
end

would report:

Warehouse#total_price refers to item more than self (FeatureEnvy)

since this:

(item.price - item.rebate)

belongs to the Item class, not the Warehouse.

FrOData::EntitySet#setup_entity_post_request refers to 'entity' more than self (maybe move it to another class?)
Open

      primary_key = entity.get_property(entity.primary_key).url_value
      chunk = entity.is_new? ? name : "#{name}(#{primary_key})"
      options = {
          method: :post,
          body: entity.to_xml.gsub(/\n\s+/, ''),
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

Example

Running Reek on:

class Warehouse
  def sale_price(item)
    (item.price - item.rebate) * @vat
  end
end

would report:

Warehouse#total_price refers to item more than self (FeatureEnvy)

since this:

(item.price - item.rebate)

belongs to the Item class, not the Warehouse.

FrOData::EntitySet#first refers to 'result' more than self (maybe move it to another class?)
Open

      count == 1 ? result.first : result.to_a
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

Feature Envy reduces the code's ability to communicate intent: code that "belongs" on one class but which is located in another can be hard to find, and may upset the "System of Names" in the host class.

Feature Envy also affects the design's flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application's domain, and creates a loss of cohesion in the unwilling host class.

Feature Envy often arises because it must manipulate other objects (usually its arguments) to get them into a useful form, and one force preventing them (the arguments) doing this themselves is that the common knowledge lives outside the arguments, or the arguments are of too basic a type to justify extending that type. Therefore there must be something which 'knows' about the contents or purposes of the arguments. That thing would have to be more than just a basic type, because the basic types are either containers which don't know about their contents, or they are single objects which can't capture their relationship with their fellows of the same type. So, this thing with the extra knowledge should be reified into a class, and the utility method will most likely belong there.

Example

Running Reek on:

class Warehouse
  def sale_price(item)
    (item.price - item.rebate) * @vat
  end
end

would report:

Warehouse#total_price refers to item more than self (FeatureEnvy)

since this:

(item.price - item.rebate)

belongs to the Item class, not the Warehouse.

FrOData::EntitySet has at least 5 instance variables
Open

  class EntitySet
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

Too Many Instance Variables is a special case of LargeClass.

Example

Given this configuration

TooManyInstanceVariables:
  max_instance_variables: 3

and this code:

class TooManyInstanceVariables
  def initialize
    @arg_1 = :dummy
    @arg_2 = :dummy
    @arg_3 = :dummy
    @arg_4 = :dummy
  end
end

Reek would emit the following warning:

test.rb -- 5 warnings:
  [1]:TooManyInstanceVariables has at least 4 instance variables (TooManyInstanceVariables)

FrOData::EntitySet#<< has approx 7 statements
Open

    def <<(entity)
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

A method with Too Many Statements is any method that has a large number of lines.

Too Many Statements warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements counts +1 for every simple statement in a method and +1 for every statement within a control structure (if, else, case, when, for, while, until, begin, rescue) but it doesn't count the control structure itself.

So the following method would score +6 in Reek's statement-counting algorithm:

def parse(arg, argv, &error)
  if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
    return nil, block, nil                                         # +1
  end
  opt = (val = parse_arg(val, &error))[1]                          # +2
  val = conv_arg(*val)                                             # +3
  if opt and !arg
    argv.shift                                                     # +4
  else
    val[0] = nil                                                   # +5
  end
  val                                                              # +6
end

(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)

FrOData::EntitySet#[] calls 'options[:expand]' 2 times
Open

      properties_to_expand = if options[:expand] == :all
        new_entity.navigation_property_names
      else
        [ options[:expand] ].compact.flatten
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

Reek implements a check for Duplicate Method Call.

Example

Here's a very much simplified and contrived example. The following method will report a warning:

def double_thing()
  @other.thing + @other.thing
end

One quick approach to silence Reek would be to refactor the code thus:

def double_thing()
  thing = @other.thing
  thing + thing
end

A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

class Other
  def double_thing()
    thing + thing
  end
end

The approach you take will depend on balancing other factors in your code.

FrOData::EntitySet#<< calls 'entity.primary_key' 2 times
Open

        primary_key_node = doc.xpath("//content/properties/#{entity.primary_key}").first
        entity[entity.primary_key] = primary_key_node.content unless primary_key_node.nil?
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

Reek implements a check for Duplicate Method Call.

Example

Here's a very much simplified and contrived example. The following method will report a warning:

def double_thing()
  @other.thing + @other.thing
end

One quick approach to silence Reek would be to refactor the code thus:

def double_thing()
  thing = @other.thing
  thing + thing
end

A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

class Other
  def double_thing()
    thing + thing
  end
end

The approach you take will depend on balancing other factors in your code.

FrOData::EntitySet#execute_entity_post_request calls 'service.logger' 2 times
Open

        service.logger.debug <<-EOS
          [ODATA: #{service_name}]
          An error was encountered committing your entity:

            POSTed URL:
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

Reek implements a check for Duplicate Method Call.

Example

Here's a very much simplified and contrived example. The following method will report a warning:

def double_thing()
  @other.thing + @other.thing
end

One quick approach to silence Reek would be to refactor the code thus:

def double_thing()
  thing = @other.thing
  thing + thing
end

A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

class Other
  def double_thing()
    thing + thing
  end
end

The approach you take will depend on balancing other factors in your code.

Complex method FrOData::EntitySet#<< (21.5)
Open

    def <<(entity)
      url_chunk, options = setup_entity_post_request(entity)
      result = execute_entity_post_request(options, url_chunk)
      if entity.is_new?
        doc = ::Nokogiri::XML(result.body).remove_namespaces!
Severity: Minor
Found in lib/frodata/entity_set.rb by flog

Flog calculates the ABC score for methods. The ABC score is based on assignments, branches (method calls), and conditions.

You can read more about ABC metrics or the flog tool

FrOData::EntitySet#<< performs a nil-check
Open

        entity[entity.primary_key] = primary_key_node.content unless primary_key_node.nil?
Severity: Minor
Found in lib/frodata/entity_set.rb by reek

A NilCheck is a type check. Failures of NilCheck violate the "tell, don't ask" principle.

Additionally, type checks often mask bigger problems in your source code like not using OOP and / or polymorphism when you should.

Example

Given

class Klass
  def nil_checker(argument)
    if argument.nil?
      puts "argument isn't nil!"
    end
  end
end

Reek would emit the following warning:

test.rb -- 1 warning:
  [3]:Klass#nil_checker performs a nil-check. (NilCheck)

Method << has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring.
Open

    def <<(entity)
      url_chunk, options = setup_entity_post_request(entity)
      result = execute_entity_post_request(options, url_chunk)
      if entity.is_new?
        doc = ::Nokogiri::XML(result.body).remove_namespaces!
Severity: Minor
Found in lib/frodata/entity_set.rb - About 25 mins to fix

Cognitive Complexity

Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

A method's cognitive complexity is based on a few simple rules:

  • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
  • Code is considered more complex for each "break in the linear flow of the code"
  • Code is considered more complex when "flow breaking structures are nested"

Further reading

Use meaningful heredoc delimiters.
Open

        EOS
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cop checks that your heredocs are using meaningful delimiters. By default it disallows END and EO*, and can be configured through blacklisting additional delimiters.

Example:

# good
<<-SQL
  SELECT * FROM foo
SQL

# bad
<<-END
  SELECT * FROM foo
END

# bad
<<-EOS
  SELECT * FROM foo
EOS

Line is too long. [81/80]
Open

  # FrOData::Service#[] method call. It also provides Enumerable behavior so that
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

end at 81, 6 is not aligned with if at 77, 29.
Open

      end
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cop checks whether the end keywords are aligned properly.

Three modes are supported through the EnforcedStyleAlignWith configuration parameter:

If it's set to keyword (which is the default), the end shall be aligned with the start of the keyword (if, class, etc.).

If it's set to variable the end shall be aligned with the left-hand-side of the variable assignment, if there is one.

If it's set to start_of_line, the end shall be aligned with the start of the line where the matching keyword appears.

Example: EnforcedStyleAlignWith: keyword (default)

# bad

variable = if true
    end

# good

variable = if true
           end

Example: EnforcedStyleAlignWith: variable

# bad

variable = if true
    end

# good

variable = if true
end

Example: EnforcedStyleAlignWith: startofline

# bad

variable = if true
    end

# good

puts(if true
end)

Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.
Open

              'Accept' => 'application/atom+xml',
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cops checks the indentation of the first key in a hash literal where the opening brace and the first key are on separate lines. The other keys' indentations are handled by the AlignHash cop.

By default, Hash literals that are arguments in a method call with parentheses, and where the opening curly brace of the hash is on the same line as the opening parenthesis of the method call, shall have their first key indented one step (two spaces) more than the position inside the opening parenthesis.

Other hash literals shall have their first key indented one step more than the start of the line where the opening curly brace is.

This default style is called 'specialinsideparentheses'. Alternative styles are 'consistent' and 'align_braces'. Here are examples:

Example: EnforcedStyle: specialinsideparentheses (default)

# The `special_inside_parentheses` style enforces that the first key
# in a hash literal where the opening brace and the first key are on
# separate lines is indented one step (two spaces) more than the
# position inside the opening parentheses.

# bad
hash = {
  key: :value
}
and_in_a_method_call({
  no: :difference
                     })

# good
special_inside_parentheses
hash = {
  key: :value
}
but_in_a_method_call({
                       its_like: :this
                     })

Example: EnforcedStyle: consistent

# The `consistent` style enforces that the first key in a hash
# literal where the opening brace and the first key are on
# seprate lines is indented the same as a hash literal which is not
# defined inside a method call.

# bad
hash = {
  key: :value
}
but_in_a_method_call({
                       its_like: :this
                      })

# good
hash = {
  key: :value
}
and_in_a_method_call({
  no: :difference
})

Example: EnforcedStyle: align_braces

# The `align_brackets` style enforces that the opening and closing
# braces are indented to the same position.

# bad
and_now_for_something = {
                          completely: :different
}

# good
and_now_for_something = {
                          completely: :different
                        }

Line is too long. [84/80]
Open

    # If count is 1 it returns the single entity, otherwise its an array of entities
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

Align else with if.
Open

      else
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cops checks the alignment of else keywords. Normally they should be aligned with an if/unless/while/until/begin/def keyword, but there are special cases when they should follow the same rules as the alignment of end.

Example:

# bad
if something
  code
 else
  code
end

# bad
if something
  code
 elsif something
  code
end

# good
if something
  code
else
  code
end

Surrounding space missing in default value assignment.
Open

    def [](key, options={})
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

Checks that the equals signs in parameter default assignments have or don't have surrounding space depending on configuration.

Example:

# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
  # do something...
end

# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end

Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.
Open

          method: :post,
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cops checks the indentation of the first key in a hash literal where the opening brace and the first key are on separate lines. The other keys' indentations are handled by the AlignHash cop.

By default, Hash literals that are arguments in a method call with parentheses, and where the opening curly brace of the hash is on the same line as the opening parenthesis of the method call, shall have their first key indented one step (two spaces) more than the position inside the opening parenthesis.

Other hash literals shall have their first key indented one step more than the start of the line where the opening curly brace is.

This default style is called 'specialinsideparentheses'. Alternative styles are 'consistent' and 'align_braces'. Here are examples:

Example: EnforcedStyle: specialinsideparentheses (default)

# The `special_inside_parentheses` style enforces that the first key
# in a hash literal where the opening brace and the first key are on
# separate lines is indented one step (two spaces) more than the
# position inside the opening parentheses.

# bad
hash = {
  key: :value
}
and_in_a_method_call({
  no: :difference
                     })

# good
special_inside_parentheses
hash = {
  key: :value
}
but_in_a_method_call({
                       its_like: :this
                     })

Example: EnforcedStyle: consistent

# The `consistent` style enforces that the first key in a hash
# literal where the opening brace and the first key are on
# seprate lines is indented the same as a hash literal which is not
# defined inside a method call.

# bad
hash = {
  key: :value
}
but_in_a_method_call({
                       its_like: :this
                      })

# good
hash = {
  key: :value
}
and_in_a_method_call({
  no: :difference
})

Example: EnforcedStyle: align_braces

# The `align_brackets` style enforces that the opening and closing
# braces are indented to the same position.

# bad
and_now_for_something = {
                          completely: :different
}

# good
and_now_for_something = {
                          completely: :different
                        }

Line is too long. [88/80]
Open

        primary_key_node = doc.xpath("//content/properties/#{entity.primary_key}").first
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

Do not use space inside array brackets.
Open

        [ options[:expand] ].compact.flatten
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

Checks that brackets used for array literals have or don't have surrounding space depending on configuration.

Example: EnforcedStyle: space

# The `space` style enforces that array literals have
# surrounding space.

# bad
array = [a, b, c, d]

# good
array = [ a, b, c, d ]

Example: EnforcedStyle: no_space

# The `no_space` style enforces that array literals have
# no surrounding space.

# bad
array = [ a, b, c, d ]

# good
array = [a, b, c, d]

Example: EnforcedStyle: compact

# The `compact` style normally requires a space inside
# array brackets, with the exception that successive left
# or right brackets are collapsed together in nested arrays.

# bad
array = [ a, [ b, c ] ]

# good
array = [ a, [ b, c ]]

Line is too long. [92/80]
Open

        service.logger.info "[ODATA: #{service_name}] Unable to commit data to #{url_chunk}"
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

Do not use space inside array brackets.
Open

        [ options[:expand] ].compact.flatten
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

Checks that brackets used for array literals have or don't have surrounding space depending on configuration.

Example: EnforcedStyle: space

# The `space` style enforces that array literals have
# surrounding space.

# bad
array = [a, b, c, d]

# good
array = [ a, b, c, d ]

Example: EnforcedStyle: no_space

# The `no_space` style enforces that array literals have
# no surrounding space.

# bad
array = [ a, b, c, d ]

# good
array = [a, b, c, d]

Example: EnforcedStyle: compact

# The `compact` style normally requires a space inside
# array brackets, with the exception that successive left
# or right brackets are collapsed together in nested arrays.

# bad
array = [ a, [ b, c ] ]

# good
array = [ a, [ b, c ]]

Redundant return detected. To return multiple values, use an array.
Open

      return chunk, options
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cop checks for redundant return expressions.

Example:

def test
  return something
end

def test
  one
  two
  three
  return something
end

It should be extended to handle methods whose body is if/else or a case expression with a default branch.

Use 2 (not -21) spaces for indentation.
Open

        new_entity.navigation_property_names
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

This cops checks for indentation that doesn't use the specified number of spaces.

See also the IndentationConsistency cop which is the companion to this one.

Example:

# bad
class A
 def test
  puts 'hello'
 end
end

# good
class A
  def test
    puts 'hello'
  end
end

Example: IgnoredPatterns: ['^\s*module']

# bad
module A
class B
  def test
  puts 'hello'
  end
end
end

# good
module A
class B
  def test
    puts 'hello'
  end
end
end

Line is too long. [90/80]
Open

        entity[entity.primary_key] = primary_key_node.content unless primary_key_node.nil?
Severity: Minor
Found in lib/frodata/entity_set.rb by rubocop

There are no issues that match your filters.

Category
Status