Commit 8271d89c by Tute Costa

Merge branch 'master' into v4.2

parents 67580ee3 db1ebd13
AllCops:
Include:
- "**/*.gemspec"
- "**/*.podspec"
- "**/*.jbuilder"
- "**/*.rake"
- "**/*.opal"
- "**/Gemfile"
- "**/Rakefile"
- "**/Capfile"
- "**/Guardfile"
- "**/Podfile"
- "**/Thorfile"
- "**/Vagrantfile"
- "**/Berksfile"
- "**/Cheffile"
- "**/Vagabondfile"
Exclude:
- "vendor/**/*"
- "db/schema.rb"
- 'vendor/**/*'
- 'gemfiles/vendor/**/*'
RunRailsCops: false
DisplayCopNames: false
StyleGuideCopsOnly: false
Style/AccessModifierIndentation:
Description: Check indentation of private/protected visibility modifiers.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#indent-public-private-protected
Enabled: true
EnforcedStyle: indent
SupportedStyles:
- outdent
- indent
Style/AlignHash:
Description: Align the elements of a hash literal if they span more than one line.
Enabled: true
EnforcedHashRocketStyle: key
EnforcedColonStyle: key
EnforcedLastArgumentHashStyle: always_inspect
SupportedLastArgumentHashStyles:
- always_inspect
- always_ignore
- ignore_implicit
- ignore_explicit
Style/AlignParameters:
Description: Align the parameters of a method call if they span more than one line.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-double-indent
Enabled: true
EnforcedStyle: with_first_parameter
SupportedStyles:
- with_first_parameter
- with_fixed_indentation
Style/AndOr:
Description: Use &&/|| instead of and/or.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-and-or-or
Enabled: true
EnforcedStyle: always
SupportedStyles:
- always
- conditionals
Style/BarePercentLiterals:
Description: Checks if usage of %() or %Q() matches configuration.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-q-shorthand
Enabled: true
EnforcedStyle: bare_percent
SupportedStyles:
- percent_q
- bare_percent
Style/BracesAroundHashParameters:
Description: Enforce braces style around hash parameters.
Enabled: true
EnforcedStyle: no_braces
SupportedStyles:
- braces
- no_braces
- context_dependent
Style/CaseIndentation:
Description: Indentation of when in a case/when/[else/]end.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#indent-when-to-case
Enabled: true
IndentWhenRelativeTo: case
SupportedStyles:
- case
- end
IndentOneStep: false
Style/ClassAndModuleChildren:
Description: Checks style of children classes and modules.
Enabled: false
EnforcedStyle: nested
SupportedStyles:
- nested
- compact
Style/ClassCheck:
Description: Enforces consistent use of `Object#is_a?` or `Object#kind_of?`.
Enabled: true
EnforcedStyle: is_a?
SupportedStyles:
- is_a?
- kind_of?
Style/CollectionMethods:
Description: Preferred collection methods.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
Enabled: true
PreferredMethods:
collect: map
collect!: map!
find: detect
find_all: select
reduce: inject
Style/CommentAnnotation:
Description: Checks formatting of special comments (TODO, FIXME, OPTIMIZE, HACK,
REVIEW).
StyleGuide: https://github.com/bbatsov/ruby-style-guide#annotate-keywords
Enabled: false
Keywords:
- TODO
- FIXME
- OPTIMIZE
- HACK
- REVIEW
Style/DotPosition:
Description: Checks the position of the dot in multi-line method calls.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
Enabled: true
EnforcedStyle: trailing
SupportedStyles:
- leading
- trailing
Style/EmptyLineBetweenDefs:
Description: Use empty lines between defs.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#empty-lines-between-methods
Enabled: true
AllowAdjacentOneLineDefs: false
Style/EmptyLinesAroundBlockBody:
Description: Keeps track of empty lines around block bodies.
Enabled: true
EnforcedStyle: no_empty_lines
SupportedStyles:
- empty_lines
- no_empty_lines
Style/EmptyLinesAroundClassBody:
Description: Keeps track of empty lines around class bodies.
Enabled: true
EnforcedStyle: no_empty_lines
SupportedStyles:
- empty_lines
- no_empty_lines
Style/EmptyLinesAroundModuleBody:
Description: Keeps track of empty lines around module bodies.
Enabled: true
EnforcedStyle: no_empty_lines
SupportedStyles:
- empty_lines
- no_empty_lines
Style/Encoding:
Description: Use UTF-8 as the source file encoding.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#utf-8
Enabled: false
EnforcedStyle: always
SupportedStyles:
- when_needed
- always
Style/FileName:
Description: Use snake_case for source file names.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
Enabled: false
Exclude: []
Style/FirstParameterIndentation:
Description: Checks the indentation of the first parameter in a method call.
Enabled: true
EnforcedStyle: special_for_inner_method_call_in_parentheses
SupportedStyles:
- consistent
- special_for_inner_method_call
- special_for_inner_method_call_in_parentheses
Style/For:
Description: Checks use of for or each in multiline loops.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-for-loops
Enabled: true
EnforcedStyle: each
SupportedStyles:
- for
- each
Style/FormatString:
Description: Enforce the use of Kernel#sprintf, Kernel#format or String#%.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#sprintf
Enabled: false
EnforcedStyle: format
SupportedStyles:
- format
- sprintf
- percent
Style/GlobalVars:
Description: Do not introduce global variables.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#instance-vars
Enabled: false
AllowedVariables: []
Style/GuardClause:
Description: Check for conditionals that can be replaced with guard clauses
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
Enabled: false
MinBodyLength: 1
Style/HashSyntax:
Description: 'Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax { :a =>
1, :b => 2 }.'
StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-literals
Enabled: true
EnforcedStyle: ruby19
SupportedStyles:
- ruby19
- hash_rockets
Style/IfUnlessModifier:
Description: Favor modifier if/unless usage when you have a single-line body.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
Enabled: false
MaxLineLength: 80
Style/IndentationWidth:
Description: Use 2 spaces for indentation.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-indentation
Enabled: true
Width: 2
Style/IndentHash:
Description: Checks the indentation of the first key in a hash literal.
Enabled: true
EnforcedStyle: special_inside_parentheses
SupportedStyles:
- special_inside_parentheses
- consistent
Style/LambdaCall:
Description: Use lambda.call(...) instead of lambda.(...).
StyleGuide: https://github.com/bbatsov/ruby-style-guide#proc-call
Enabled: false
EnforcedStyle: call
SupportedStyles:
- call
- braces
Style/Next:
Description: Use `next` to skip iteration instead of a condition at the end.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
Enabled: false
EnforcedStyle: skip_modifier_ifs
MinBodyLength: 3
SupportedStyles:
- skip_modifier_ifs
- always
Style/NonNilCheck:
Description: Checks for redundant nil checks.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-non-nil-checks
Enabled: true
IncludeSemanticChanges: false
Style/MethodDefParentheses:
Description: Checks if the method definitions have or don't have parentheses.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#method-parens
Enabled: true
EnforcedStyle: require_parentheses
SupportedStyles:
- require_parentheses
- require_no_parentheses
Style/MethodName:
Description: Use the configured style when naming methods.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars
Enabled: true
EnforcedStyle: snake_case
SupportedStyles:
- snake_case
- camelCase
Style/MultilineOperationIndentation:
Description: Checks indentation of binary operations that span more than one line.
Enabled: true
EnforcedStyle: aligned
SupportedStyles:
- aligned
- indented
Style/NumericLiterals:
Description: Add underscores to large numeric literals to improve their readability.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics
Enabled: false
MinDigits: 5
Style/ParenthesesAroundCondition:
Description: Don't use parentheses around the condition of an if/unless/while.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-parens-if
Enabled: true
AllowSafeAssignment: true
Style/PercentLiteralDelimiters:
Description: Use `%`-literal delimiters consistently
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
Enabled: false
PreferredDelimiters:
"%": "()"
"%i": "()"
"%q": "()"
"%Q": "()"
"%r": "{}"
"%s": "()"
"%w": "()"
"%W": "()"
"%x": "()"
Style/PercentQLiterals:
Description: Checks if uses of %Q/%q match the configured preference.
Enabled: true
EnforcedStyle: lower_case_q
SupportedStyles:
- lower_case_q
- upper_case_q
Style/PredicateName:
Description: Check the names of predicate methods.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
Enabled: true
NamePrefix:
- is_
- has_
- have_
NamePrefixBlacklist:
- is_
Style/RaiseArgs:
Description: Checks the arguments passed to raise/fail.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
Enabled: false
EnforcedStyle: exploded
SupportedStyles:
- compact
- exploded
Style/RedundantReturn:
Description: Don't use return where it's not required.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-explicit-return
Enabled: true
AllowMultipleReturnValues: false
Style/RegexpLiteral:
Description: Use %r for regular expressions matching more than `MaxSlashes` '/'
characters. Use %r only for regular expressions matching more than `MaxSlashes`
'/' character.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-r
Enabled: false
MaxSlashes: 1
Style/Semicolon:
Description: Don't use semicolons to terminate expressions.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-semicolon
Enabled: true
AllowAsExpressionSeparator: false
Style/SignalException:
Description: Checks for proper usage of fail and raise.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
Enabled: false
EnforcedStyle: semantic
SupportedStyles:
- only_raise
- only_fail
- semantic
Style/SingleLineBlockParams:
Description: Enforces the names of some block params.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
Enabled: false
Methods:
- reduce:
- a
- e
- inject:
- a
- e
Style/SingleLineMethods:
Description: Avoid single-line methods.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
Enabled: false
AllowIfMethodIsEmpty: true
Style/StringLiterals:
Description: Checks if uses of quotes match the configured preference.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
Enabled: true
EnforcedStyle: double_quotes
SupportedStyles:
- single_quotes
- double_quotes
Style/StringLiteralsInInterpolation:
Description: Checks if uses of quotes inside expressions in interpolated strings
match the configured preference.
Enabled: true
EnforcedStyle: single_quotes
SupportedStyles:
- single_quotes
- double_quotes
Style/SpaceAroundBlockParameters:
Description: Checks the spacing inside and after block parameters pipes.
Enabled: true
EnforcedStyleInsidePipes: no_space
SupportedStyles:
- space
- no_space
Style/SpaceAroundEqualsInParameterDefault:
Description: Checks that the equals signs in parameter default assignments have
or don't have surrounding space depending on configuration.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-around-equals
Enabled: true
EnforcedStyle: space
SupportedStyles:
- space
- no_space
Style/SpaceBeforeBlockBraces:
Description: Checks that the left block brace has or doesn't have space before it.
Enabled: true
EnforcedStyle: space
SupportedStyles:
- space
- no_space
Style/SpaceInsideBlockBraces:
Description: Checks that block braces have or don't have surrounding space. For
blocks taking parameters, checks that the left brace has or doesn't have trailing
space.
Enabled: true
EnforcedStyle: space
SupportedStyles:
- space
- no_space
EnforcedStyleForEmptyBraces: no_space
SpaceBeforeBlockParameters: true
Style/SpaceInsideHashLiteralBraces:
Description: Use spaces inside hash literal braces - or don't.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
Enabled: true
EnforcedStyle: space
EnforcedStyleForEmptyBraces: no_space
SupportedStyles:
- space
- no_space
Style/SymbolProc:
Description: Use symbols as procs instead of blocks when possible.
Enabled: true
IgnoredMethods:
- respond_to
Style/TrailingBlankLines:
Description: Checks trailing blank lines and final newline.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#newline-eof
Enabled: true
EnforcedStyle: final_newline
SupportedStyles:
- final_newline
- final_blank_line
Style/TrailingComma:
Description: Checks for trailing comma in parameter lists and literals.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
Enabled: false
EnforcedStyleForMultiline: no_comma
SupportedStyles:
- comma
- no_comma
Style/TrivialAccessors:
Description: Prefer attr_* methods to trivial readers/writers.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#attr_family
Enabled: false
ExactNameMatch: false
AllowPredicates: false
AllowDSLWriters: false
Whitelist:
- to_ary
- to_a
- to_c
- to_enum
- to_h
- to_hash
- to_i
- to_int
- to_io
- to_open
- to_path
- to_proc
- to_r
- to_regexp
- to_str
- to_s
- to_sym
Style/VariableName:
Description: Use the configured style when naming variables.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars
Enabled: true
EnforcedStyle: snake_case
SupportedStyles:
- snake_case
- camelCase
Style/WhileUntilModifier:
Description: Favor modifier while/until usage when you have a single-line body.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#while-as-a-modifier
Enabled: false
MaxLineLength: 80
Style/WordArray:
Description: Use %w or %W for arrays of words.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-w
Enabled: false
MinSize: 0
WordRegex: !ruby/regexp /\A[\p{Word}]+\z/
Metrics/AbcSize:
Description: A calculated magnitude based on number of assignments, branches, and
conditions.
Enabled: true
Max: 15
Metrics/BlockNesting:
Description: Avoid excessive block nesting
StyleGuide: https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count
Enabled: false
Max: 3
Metrics/ClassLength:
Description: Avoid classes longer than 100 lines of code.
Enabled: false
CountComments: false
Max: 100
Metrics/CyclomaticComplexity:
Description: A complexity metric that is strongly correlated to the number of test
cases needed to validate a method.
Enabled: false
Max: 6
Metrics/LineLength:
Description: Limit lines to 80 characters.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#80-character-limits
Enabled: true
Max: 80
AllowURI: true
URISchemes:
- http
- https
Metrics/MethodLength:
Description: Avoid methods longer than 10 lines of code.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
Enabled: false
CountComments: false
Max: 10
Metrics/ParameterLists:
Description: Avoid parameter lists longer than three or four parameters.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
Enabled: false
Max: 5
CountKeywordArgs: true
Metrics/PerceivedComplexity:
Description: A complexity metric geared towards measuring complexity for a human
reader.
Enabled: false
Max: 7
Lint/AssignmentInCondition:
Description: Don't use assignment in conditions.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
Enabled: false
AllowSafeAssignment: true
Lint/EndAlignment:
Description: Align ends correctly.
Enabled: true
AlignWith: keyword
SupportedStyles:
- keyword
- variable
Lint/DefEndAlignment:
Description: Align ends corresponding to defs correctly.
Enabled: true
AlignWith: start_of_line
SupportedStyles:
- start_of_line
- def
Rails/ActionFilter:
Description: Enforces consistent use of action filter methods.
Enabled: false
EnforcedStyle: action
SupportedStyles:
- action
- filter
Include:
- app/controllers/**/*.rb
Rails/DefaultScope:
Description: Checks if the argument passed to default_scope is a block.
Enabled: true
Include:
- app/models/**/*.rb
Rails/HasAndBelongsToMany:
Description: Prefer has_many :through to has_and_belongs_to_many.
Enabled: true
Include:
- app/models/**/*.rb
Rails/Output:
Description: Checks for calls to puts, print, etc.
Enabled: true
Include:
- app/**/*.rb
- config/**/*.rb
- db/**/*.rb
- lib/**/*.rb
Rails/ReadWriteAttribute:
Description: Checks for read_attribute(:attr) and write_attribute(:attr, val).
Enabled: true
Include:
- app/models/**/*.rb
Rails/ScopeArgs:
Description: Checks the arguments of ActiveRecord scopes.
Enabled: true
Include:
- app/models/**/*.rb
Rails/Validation:
Description: Use validates :attribute, hash of validations.
Enabled: true
Include:
- app/models/**/*.rb
Style/InlineComment:
Description: Avoid inline comments.
Enabled: false
Style/MethodCalledOnDoEndBlock:
Description: Avoid chaining a method call on a do...end block.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#single-line-blocks
Enabled: false
Style/SymbolArray:
Description: Use %i or %I for arrays of symbols.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-i
Enabled: false
Style/ExtraSpacing:
Description: Do not use unnecessary spacing.
Enabled: true
Style/AccessorMethodName:
Description: Check the naming of accessor methods for get_/set_.
Enabled: false
Style/Alias:
Description: Use alias_method instead of alias.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
Enabled: false
Style/AlignArray:
Description: Align the elements of an array literal if they span more than one line.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#align-multiline-arrays
Enabled: true
Style/ArrayJoin:
Description: Use Array#join instead of Array#*.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#array-join
Enabled: false
Style/AsciiComments:
Description: Use only ascii symbols in comments.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#english-comments
Enabled: false
Style/AsciiIdentifiers:
Description: Use only ascii symbols in identifiers.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#english-identifiers
Enabled: false
Style/Attr:
Description: Checks for uses of Module#attr.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#attr
Enabled: false
Style/BeginBlock:
Description: Avoid the use of BEGIN blocks.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-BEGIN-blocks
Enabled: true
Style/BlockComments:
Description: Do not use block comments.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-block-comments
Enabled: true
Style/BlockEndNewline:
Description: Put end statement of multiline block on its own line.
Enabled: true
Style/Blocks:
Description: Avoid using {...} for multi-line blocks (multiline chaining is always
ugly). Prefer {...} over do...end for single-line blocks.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#single-line-blocks
Enabled: true
Style/CaseEquality:
Description: Avoid explicit use of the case equality operator(===).
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-case-equality
Enabled: false
Style/CharacterLiteral:
Description: Checks for uses of character literals.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-character-literals
Enabled: false
Style/ClassAndModuleCamelCase:
Description: Use CamelCase for classes and modules.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#camelcase-classes
Enabled: true
Style/ClassMethods:
Description: Use self when defining module/class methods.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#def-self-singletons
Enabled: true
Style/ClassVars:
Description: Avoid the use of class variables.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-class-vars
Enabled: false
Style/ColonMethodCall:
Description: 'Do not use :: for method call.'
StyleGuide: https://github.com/bbatsov/ruby-style-guide#double-colons
Enabled: false
Style/CommentIndentation:
Description: Indentation of comments.
Enabled: true
Style/ConstantName:
Description: Constants should use SCREAMING_SNAKE_CASE.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#screaming-snake-case
Enabled: true
Style/DefWithParentheses:
Description: Use def with parentheses when there are arguments.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#method-parens
Enabled: true
Style/DeprecatedHashMethods:
Description: Checks for use of deprecated Hash methods.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-key
Enabled: false
Style/Documentation:
Description: Document classes and non-namespace modules.
Enabled: false
Style/DoubleNegation:
Description: Checks for uses of double negation (!!).
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
Enabled: false
Style/EachWithObject:
Description: Prefer `each_with_object` over `inject` or `reduce`.
Enabled: false
Style/ElseAlignment:
Description: Align elses and elsifs correctly.
Enabled: true
Style/EmptyElse:
Description: Avoid empty else-clauses.
Enabled: true
Style/EmptyLines:
Description: Don't use several empty lines in a row.
Enabled: true
Style/EmptyLinesAroundAccessModifier:
Description: Keep blank lines around access modifiers.
Enabled: true
Style/EmptyLinesAroundMethodBody:
Description: Keeps track of empty lines around method bodies.
Enabled: true
Style/EmptyLiteral:
Description: Prefer literals to Array.new/Hash.new/String.new.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
Enabled: false
Style/EndBlock:
Description: Avoid the use of END blocks.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-END-blocks
Enabled: true
Style/EndOfLine:
Description: Use Unix-style line endings.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#crlf
Enabled: true
Style/EvenOdd:
Description: Favor the use of Fixnum#even? && Fixnum#odd?
StyleGuide: https://github.com/bbatsov/ruby-style-guide#predicate-methods
Enabled: false
Style/FlipFlop:
Description: Checks for flip flops
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-flip-flops
Enabled: false
Style/IfWithSemicolon:
Description: Do not use if x; .... Use the ternary operator instead.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs
Enabled: false
Style/IndentationConsistency:
Description: Keep indentation straight.
Enabled: true
Style/IndentArray:
Description: Checks the indentation of the first element in an array literal.
Enabled: true
Style/InfiniteLoop:
Description: Use Kernel#loop for infinite loops.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#infinite-loop
Enabled: true
Style/Lambda:
Description: Use the new lambda literal syntax for single-line blocks.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#lambda-multi-line
Enabled: false
Style/LeadingCommentSpace:
Description: Comments should start with a space.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-space
Enabled: true
Style/LineEndConcatenation:
Description: Use \ instead of + or << to concatenate two string literals at line
end.
Enabled: false
Style/MethodCallParentheses:
Description: Do not use parentheses for method calls with no arguments.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-args-no-parens
Enabled: true
Style/ModuleFunction:
Description: Checks for usage of `extend self` in modules.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
Enabled: false
Style/MultilineBlockChain:
Description: Avoid multi-line chains of blocks.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#single-line-blocks
Enabled: true
Style/MultilineBlockLayout:
Description: Ensures newlines after multiline block do statements.
Enabled: true
Style/MultilineIfThen:
Description: Do not use then for multi-line if/unless.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-then
Enabled: true
Style/MultilineTernaryOperator:
Description: 'Avoid multi-line ?: (the ternary operator); use if/unless instead.'
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-multiline-ternary
Enabled: true
Style/NegatedIf:
Description: Favor unless over if for negative conditions (or control flow or).
StyleGuide: https://github.com/bbatsov/ruby-style-guide#unless-for-negatives
Enabled: false
Style/NegatedWhile:
Description: Favor until over while for negative conditions.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#until-for-negatives
Enabled: false
Style/NestedTernaryOperator:
Description: Use one expression per branch in a ternary operator.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-ternary
Enabled: true
Style/NilComparison:
Description: Prefer x.nil? to x == nil.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#predicate-methods
Enabled: false
Style/Not:
Description: Use ! instead of not.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#bang-not-not
Enabled: false
Style/OneLineConditional:
Description: Favor the ternary operator(?:) over if/then/else/end constructs.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
Enabled: false
Style/OpMethod:
Description: When defining binary operators, name the argument other.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#other-arg
Enabled: false
Style/PerlBackrefs:
Description: Avoid Perl-style regex back references.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
Enabled: false
Style/Proc:
Description: Use proc instead of Proc.new.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#proc
Enabled: false
Style/RedundantBegin:
Description: Don't use begin blocks when they are not needed.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#begin-implicit
Enabled: true
Style/RedundantException:
Description: Checks for an obsolete RuntimeException argument in raise/fail.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-explicit-runtimeerror
Enabled: true
Style/RedundantSelf:
Description: Don't use self where it's not needed.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-self-unless-required
Enabled: true
Style/RescueModifier:
Description: Avoid using rescue in its modifier form.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-rescue-modifiers
Enabled: true
Style/SelfAssignment:
Description: Checks for places where self-assignment shorthand should have been
used.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#self-assignment
Enabled: false
Style/SingleSpaceBeforeFirstArg:
Description: Checks that exactly one space is used between a method name and the
first argument for method calls without parentheses.
Enabled: true
Style/SpaceAfterColon:
Description: Use spaces after colons.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
Enabled: true
Style/SpaceAfterComma:
Description: Use spaces after commas.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
Enabled: true
Style/SpaceAfterControlKeyword:
Description: Use spaces after if/elsif/unless/while/until/case/when.
Enabled: true
Style/SpaceAfterMethodName:
Description: Do not put a space between a method name and the opening parenthesis
in a method definition.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-no-spaces
Enabled: true
Style/SpaceAfterNot:
Description: Tracks redundant space after the ! operator.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-space-bang
Enabled: true
Style/SpaceAfterSemicolon:
Description: Use spaces after semicolons.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
Enabled: true
Style/SpaceBeforeComma:
Description: No spaces before commas.
Enabled: true
Style/SpaceBeforeComment:
Description: Checks for missing space between code and a comment on the same line.
Enabled: true
Style/SpaceBeforeSemicolon:
Description: No spaces before semicolons.
Enabled: true
Style/SpaceAroundOperators:
Description: Use spaces around operators.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
Enabled: true
Style/SpaceBeforeModifierKeyword:
Description: Put a space before the modifier keyword.
Enabled: true
Style/SpaceInsideBrackets:
Description: No spaces after [ or before ].
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-spaces-braces
Enabled: true
Style/SpaceInsideParens:
Description: No spaces after ( or before ).
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-spaces-braces
Enabled: true
Style/SpaceInsideRangeLiteral:
Description: No spaces inside range literals.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-space-inside-range-literals
Enabled: true
Style/SpecialGlobalVars:
Description: Avoid Perl-style global variables.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
Enabled: false
Style/StructInheritance:
Description: Checks for inheritance from Struct.new.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-extend-struct-new
Enabled: true
Style/Tab:
Description: No hard tabs.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-indentation
Enabled: true
Style/TrailingWhitespace:
Description: Avoid trailing whitespace.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-whitespace
Enabled: true
Style/UnlessElse:
Description: Do not use unless with else. Rewrite these with the positive case first.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-else-with-unless
Enabled: true
Style/UnneededCapitalW:
Description: Checks for %W when interpolation is not needed.
Enabled: true
Style/UnneededPercentQ:
Description: Checks for %q/%Q when single quotes or double quotes would do.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-q
Enabled: true
Style/UnneededPercentX:
Description: Checks for %x when `` would do.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-x
Enabled: true
Style/VariableInterpolation:
Description: Don't interpolate global, instance and class variables directly in
strings.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
Enabled: false
Style/WhenThen:
Description: Use when x then ... for one-line cases.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
Enabled: false
Style/WhileUntilDo:
Description: Checks for redundant do after while or until.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-multiline-while-do
Enabled: true
Lint/AmbiguousOperator:
Description: Checks for ambiguous operators in the first argument of a method invocation
without parentheses.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-as-args
Enabled: false
Lint/AmbiguousRegexpLiteral:
Description: Checks for ambiguous regexp literals in the first argument of a method
invocation without parenthesis.
Enabled: false
Lint/BlockAlignment:
Description: Align block ends correctly.
Enabled: true
Lint/ConditionPosition:
Description: Checks for condition placed in a confusing position relative to the
keyword.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#same-line-condition
Enabled: false
Lint/Debugger:
Description: Check for debugger calls.
Enabled: true
Lint/DeprecatedClassMethods:
Description: Check for deprecated class method calls.
Enabled: false
Lint/DuplicateMethods:
Description: Check for duplicate methods calls.
Enabled: true
Lint/ElseLayout:
Description: Check for odd code arrangement in an else block.
Enabled: false
Lint/EmptyEnsure:
Description: Checks for empty ensure block.
Enabled: true
Lint/EmptyInterpolation:
Description: Checks for empty string interpolation.
Enabled: true
Lint/EndInMethod:
Description: END blocks should not be placed inside method definitions.
Enabled: true
Lint/EnsureReturn:
Description: Do not use return in an ensure block.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-return-ensure
Enabled: true
Lint/Eval:
Description: The use of eval represents a serious security risk.
Enabled: true
Lint/HandleExceptions:
Description: Don't suppress exception.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
Enabled: false
Lint/InvalidCharacterLiteral:
Description: Checks for invalid character literals with a non-escaped whitespace
character.
Enabled: false
Lint/LiteralInCondition:
Description: Checks of literals used in conditions.
Enabled: false
Lint/LiteralInInterpolation:
Description: Checks for literals used in interpolation.
Enabled: false
Lint/Loop:
Description: Use Kernel#loop with break rather than begin/end/until or begin/end/while
for post-loop tests.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#loop-with-break
Enabled: false
Lint/ParenthesesAsGroupedExpression:
Description: Checks for method calls with a space before the opening parenthesis.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-no-spaces
Enabled: false
Lint/RequireParentheses:
Description: Use parentheses in the method call to avoid confusion about precedence.
Enabled: false
Lint/RescueException:
Description: Avoid rescuing the Exception class.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-blind-rescues
Enabled: true
Lint/ShadowingOuterLocalVariable:
Description: Do not use the same name as outer local variable for block arguments
or block local variables.
Enabled: true
Lint/SpaceBeforeFirstArg:
Description: Put a space between a method name and the first argument in a method
call without parentheses.
Enabled: true
Lint/StringConversionInInterpolation:
Description: Checks for Object#to_s usage in string interpolation.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-to-s
Enabled: true
Lint/UnderscorePrefixedVariableName:
Description: Do not use prefix `_` for a variable that is used.
Enabled: false
Lint/UnusedBlockArgument:
Description: Checks for unused block arguments.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars
Enabled: true
Lint/UnusedMethodArgument:
Description: Checks for unused method arguments.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars
Enabled: true
Lint/UnreachableCode:
Description: Unreachable code.
Enabled: true
Lint/UselessAccessModifier:
Description: Checks for useless access modifiers.
Enabled: true
Lint/UselessAssignment:
Description: Checks for useless assignment to a local variable.
StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars
Enabled: true
Lint/UselessComparison:
Description: Checks for comparison of something with itself.
Enabled: true
Lint/UselessElseWithoutRescue:
Description: Checks for useless `else` in `begin..end` without `rescue`.
Enabled: true
Lint/UselessSetterCall:
Description: Checks for useless setter call to a local variable.
Enabled: true
Lint/Void:
Description: Possible use of operator/literal/variable in void context.
Enabled: false
Rails/Delegate:
Description: Prefer delegate method for delegations.
Enabled: false
inherit_from: .hound.yml
...@@ -4,20 +4,24 @@ rvm: ...@@ -4,20 +4,24 @@ rvm:
- rbx-2 - rbx-2
- 2.0.0 - 2.0.0
- 2.1.1 - 2.1.1
- 2.2.2
install: install:
- "travis_retry bundle install" - "travis_retry bundle install"
before_script: "sudo ntpdate -ub ntp.ubuntu.com pool.ntp.org; true"
script: "bundle exec rake clean spec cucumber" script: "bundle exec rake clean spec cucumber"
gemfile: gemfile:
- gemfiles/3.2.gemfile - gemfiles/3.2.gemfile
- gemfiles/4.0.gemfile - gemfiles/4.0.gemfile
- gemfiles/4.1.gemfile - gemfiles/4.1.gemfile
- gemfiles/4.2.gemfile
matrix: matrix:
fast_finish: true fast_finish: true
allow_failures: allow_failures:
- rvm: jruby-19mode - rvm: jruby-19mode
- rvm: rbx-2 - rvm: rbx-2
sudo: false
cache: bundler
...@@ -14,6 +14,6 @@ appraise "4.1" do ...@@ -14,6 +14,6 @@ appraise "4.1" do
end end
appraise "4.2" do appraise "4.2" do
gem "rails", "~> 4.2.0.rc2" gem "rails", "~> 4.2.0"
gem "paperclip", :path => "../" gem "paperclip", :path => "../"
end end
...@@ -6,7 +6,7 @@ We love pull requests. Here's a quick guide: ...@@ -6,7 +6,7 @@ We love pull requests. Here's a quick guide:
1. Fork the repo. 1. Fork the repo.
2. Run the tests. We only take pull requests with passing tests, and it's great 2. Run the tests. We only take pull requests with passing tests, and it's great
to know that you have a clean slate: `bundle && rake` to know that you have a clean slate: `bundle && bundle exec rake`
3. Add a test for your change. Only refactoring and documentation changes 3. Add a test for your change. Only refactoring and documentation changes
require no new tests. If you are adding functionality or fixing a bug, we need require no new tests. If you are adding functionality or fixing a bug, we need
...@@ -43,14 +43,14 @@ will be asked to rewrite them before we'll accept. ...@@ -43,14 +43,14 @@ will be asked to rewrite them before we'll accept.
### Bootstrapping your test suite: ### Bootstrapping your test suite:
bundle install bundle install
bundle exec rake appraisal:install bundle exec appraisal install
This will install all the required gems that requires to test against each This will install all the required gems that requires to test against each
version of Rails, which defined in `gemfiles/*.gemfile`. version of Rails, which defined in `gemfiles/*.gemfile`.
### To run a full test suite: ### To run a full test suite:
bundle exec rake bundle exec appraisal rake
This will run RSpec and Cucumber against all version of Rails This will run RSpec and Cucumber against all version of Rails
......
...@@ -2,7 +2,7 @@ source "https://rubygems.org" ...@@ -2,7 +2,7 @@ source "https://rubygems.org"
gemspec gemspec
gem 'sqlite3', '1.3.8', :platforms => :ruby gem 'sqlite3', '~>1.3.8', :platforms => :ruby
gem 'jruby-openssl', :platforms => :jruby gem 'jruby-openssl', :platforms => :jruby
gem 'activerecord-jdbcsqlite3-adapter', :platforms => :jruby gem 'activerecord-jdbcsqlite3-adapter', :platforms => :jruby
...@@ -17,4 +17,5 @@ gem 'pry' ...@@ -17,4 +17,5 @@ gem 'pry'
group :development, :test do group :development, :test do
gem 'mime-types', '~> 1.16' gem 'mime-types', '~> 1.16'
gem 'builder' gem 'builder'
gem 'rubocop', require: false
end end
...@@ -3,7 +3,7 @@ LICENSE ...@@ -3,7 +3,7 @@ LICENSE
The MIT License The MIT License
Copyright (c) 2008-2014 Jon Yurek and thoughtbot, inc. Copyright (c) 2008-2015 Jon Yurek and thoughtbot, inc.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
...@@ -12,7 +12,7 @@ New in 4.2.1: ...@@ -12,7 +12,7 @@ New in 4.2.1:
* Improvement: Better escaping for characters in URLs * Improvement: Better escaping for characters in URLs
* Improvement: Honor `fog_credentials[:scheme]` * Improvement: Honor `fog_credentials[:scheme]`
* Improvement: Also look for custom processors in lib/paperclip * Improvement: Also look for custom processors in lib/paperclip
* Improvement: id partitioning for string IDs works liks integer id * Improvement: id partitioning for string IDs works like integer id
* Improvement: Can pass options to DB adapters in migrations * Improvement: Can pass options to DB adapters in migrations
* Improvement: Update expiring_url creation for later versions of fog * Improvement: Update expiring_url creation for later versions of fog
* Improvement: `path` can be a Proc in S3 attachments * Improvement: `path` can be a Proc in S3 attachments
......
Paperclip Paperclip
========= =========
[![Build Status](https://secure.travis-ci.org/thoughtbot/paperclip.png?branch=master)](http://travis-ci.org/thoughtbot/paperclip) [![Dependency Status](https://gemnasium.com/thoughtbot/paperclip.png?travis)](https://gemnasium.com/thoughtbot/paperclip) [![Code Climate](https://codeclimate.com/github/thoughtbot/paperclip.png)](https://codeclimate.com/github/thoughtbot/paperclip) [![Inline docs](http://inch-ci.org/github/thoughtbot/paperclip.png)](http://inch-ci.org/github/thoughtbot/paperclip) [![Security](https://hakiri.io/github/thoughtbot/paperclip/master.svg)](https://hakiri.io/github/thoughtbot/paperclip/master) [![Build Status](https://secure.travis-ci.org/thoughtbot/paperclip.svg?branch=master)](http://travis-ci.org/thoughtbot/paperclip) [![Dependency Status](https://gemnasium.com/thoughtbot/paperclip.svg?travis)](https://gemnasium.com/thoughtbot/paperclip) [![Code Climate](https://codeclimate.com/github/thoughtbot/paperclip.svg)](https://codeclimate.com/github/thoughtbot/paperclip) [![Inline docs](http://inch-ci.org/github/thoughtbot/paperclip.svg)](http://inch-ci.org/github/thoughtbot/paperclip) [![Security](https://hakiri.io/github/thoughtbot/paperclip/master.svg)](https://hakiri.io/github/thoughtbot/paperclip/master)
- [Requirements](#requirements)
- [Ruby on Rails](#ruby-and-rails)
- [Image Processor](#image-processor)
- [file](#file)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Models](#models)
- [Migrations](#migrations)
- [Edit and New Views](#edit-and-new-views)
- [Edit and New Views with Simple Form](#edit-and-new-views-with-simple-form)
- [Controller](#controller)
- [Show View](#show-view)
- [Deleting an Attachment](#deleting-an-attachment)
- [Usage](#usage)
- [Validations](#validations)
- [Security Validations](#security-validations)
- [Defaults](#defaults)
- [Migrations](#migrations-1)
- [Table Definition](#table-definition)
- [Schema Definition](#schema-definition)
- [Vintage Syntax](#vintage-syntax)
- [Storage](#storage)
- [Understanding Storage](#understanding-storage)
- [Post Processing](#post-processing)
- [Events](#events)
- [URI Obfuscation](#uri-obfuscation)
- [MD5 Checksum / Fingerprint](#md5-checksum--fingerprint)
- [File Preservation for Soft-Delete](#file-preservation-for-soft-delete)
- [Custom Attachment Processors](#custom-attachment-processors)
- [Dynamic Configuration](#dynamic-configuration)
- [Dynamic Styles](#dynamic-styles)
- [Dynamic Processors](#dynamic-processors)
- [Logging](#logging)
- [Deployment](#deployment)
- [Testing](#testing)
- [Contributing](#contributing)
- [License](#license)
- [About thoughtbot](#about-thoughtbot)
Paperclip is intended as an easy file attachment library for Active Record. The Paperclip is intended as an easy file attachment library for Active Record. The
intent behind it was to keep setup as easy as possible and to treat files as intent behind it was to keep setup as easy as possible and to treat files as
...@@ -52,15 +91,15 @@ If you're on Mac OS X, you'll want to run the following with Homebrew: ...@@ -52,15 +91,15 @@ If you're on Mac OS X, you'll want to run the following with Homebrew:
brew install imagemagick brew install imagemagick
If you are dealing with pdf uploads or running the test suite, you'll also need If you are dealing with pdf uploads or running the test suite, you'll also need
GhostScript to be installed. On Mac OS X, you can also install that using Homebrew: to install GhostScript. On Mac OS X, you can also install that using Homebrew:
brew install gs brew install gs
### `file` ### `file`
The Unix [`file` command](http://en.wikipedia.org/wiki/File_(command)) is required for content type checking. The Unix [`file` command](http://en.wikipedia.org/wiki/File_(command)) is required for content-type checking.
This utility isn't available in Windows, but comes bundled with Ruby [Devkit](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit), This utility isn't available in Windows, but comes bundled with Ruby [Devkit](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit),
so Windows users must make sure that the devkit is installed and added to system `PATH`. so Windows users must make sure that the devkit is installed and added to the system `PATH`.
**Manual Installation** **Manual Installation**
...@@ -70,16 +109,16 @@ To manually install, you should perform the following: ...@@ -70,16 +109,16 @@ To manually install, you should perform the following:
> **Download & install `file` from [this URL](http://gnuwin32.sourceforge.net/packages/file.htm)** > **Download & install `file` from [this URL](http://gnuwin32.sourceforge.net/packages/file.htm)**
To test, you can use the following: To test, you can use the image below:
![untitled](https://cloud.githubusercontent.com/assets/1104431/4524452/a1f8cce4-4d44-11e4-872e-17adb96f79c9.png) ![untitled](https://cloud.githubusercontent.com/assets/1104431/4524452/a1f8cce4-4d44-11e4-872e-17adb96f79c9.png)
Next, you need to integrate with your environment - preferrably through the `PATH` variable, or by changing your `config/environments/development.rb` file Next, you need to integrate with your environment - preferably through the `PATH` variable, or by changing your `config/environments/development.rb` file
**PATH** **PATH**
1. Click "Start" 1. Click "Start"
2. On "Computer", right-click and select "Properties" 2. On "Computer", right-click and select "Properties"
3. In properties, select "Advanced System Settings" 3. In Properties, select "Advanced System Settings"
4. Click the "Environment Variables" button 4. Click the "Environment Variables" button
5. Locate the "PATH" var - at the end, add the path to your newly installed `file.exe` (typically `C:\Program Files (x86)\GnuWin32\bin`) 5. Locate the "PATH" var - at the end, add the path to your newly installed `file.exe` (typically `C:\Program Files (x86)\GnuWin32\bin`)
6. Restart any CMD shells you have open & see if it works 6. Restart any CMD shells you have open & see if it works
...@@ -92,7 +131,7 @@ OR ...@@ -92,7 +131,7 @@ OR
2. Add the following line: `Paperclip.options[:command_path] = 'C:\Program Files (x86)\GnuWin32\bin'` 2. Add the following line: `Paperclip.options[:command_path] = 'C:\Program Files (x86)\GnuWin32\bin'`
3. Restart your Rails server 3. Restart your Rails server
Either of these methods will give your Rails setup access to the `file.exe` functionality, this providing the ability to check the contents of a file (fixing the spoofing problem) Either of these methods will give your Rails setup access to the `file.exe` functionality, thus providing the ability to check the contents of a file (fixing the spoofing problem)
--- ---
...@@ -163,17 +202,17 @@ end ...@@ -163,17 +202,17 @@ end
```ruby ```ruby
class AddAvatarColumnsToUsers < ActiveRecord::Migration class AddAvatarColumnsToUsers < ActiveRecord::Migration
def self.up def up
add_attachment :users, :avatar add_attachment :users, :avatar
end end
def self.down def down
remove_attachment :users, :avatar remove_attachment :users, :avatar
end end
end end
``` ```
(Or you can use migration generator: `rails generate paperclip user avatar`) (Or you can use the Rails migration generator: `rails generate paperclip user avatar`)
### Edit and New Views ### Edit and New Views
...@@ -183,6 +222,13 @@ end ...@@ -183,6 +222,13 @@ end
<% end %> <% end %>
``` ```
### Edit and New Views with Simple Form
```erb
<%= simple_form_for @user, url: users_path do |form| %>
<%= form.input :avatar, as: :file %>
<% end %>
```
### Controller ### Controller
**Rails 3** **Rails 3**
...@@ -231,7 +277,7 @@ Set the attribute to `nil` and save. ...@@ -231,7 +277,7 @@ Set the attribute to `nil` and save.
Usage Usage
----- -----
The basics of paperclip are quite simple: Declare that your model has an The basics of Paperclip are quite simple: Declare that your model has an
attachment with the `has_attached_file` method, and give it a name. attachment with the `has_attached_file` method, and give it a name.
Paperclip will wrap up to four attributes (all prefixed with that attachment's name, Paperclip will wrap up to four attributes (all prefixed with that attachment's name,
...@@ -243,11 +289,11 @@ friendly front end. These attributes are: ...@@ -243,11 +289,11 @@ friendly front end. These attributes are:
* `<attachment>_content_type` * `<attachment>_content_type`
* `<attachment>_updated_at` * `<attachment>_updated_at`
By default, only `<attachment>_file_name` is required for paperclip to operate. By default, only `<attachment>_file_name` is required for Paperclip to operate.
You'll need to add `<attachment>_content_type` in case you want to use content type You'll need to add `<attachment>_content_type` in case you want to use content type
validation. validation.
More information about the options to `has_attached_file` is available in the More information about the options passed to `has_attached_file` is available in the
documentation of [`Paperclip::ClassMethods`](http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods). documentation of [`Paperclip::ClassMethods`](http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods).
Validations Validations
...@@ -288,8 +334,8 @@ validates_attachment :avatar, :presence => true, ...@@ -288,8 +334,8 @@ validates_attachment :avatar, :presence => true,
:size => { :in => 0..10.kilobytes } :size => { :in => 0..10.kilobytes }
``` ```
_NOTE: Post processing will not even *start* if the attachment is not valid _NOTE: Post-processing will not even **start** if the attachment is not valid
according to the validations. Your callbacks and processors will *only* be according to the validations. Your callbacks and processors will **only** be
called with valid attachments._ called with valid attachments._
```ruby ```ruby
...@@ -382,18 +428,18 @@ NOTE: Also starting at version 4.0.0, Paperclip has another validation that ...@@ -382,18 +428,18 @@ NOTE: Also starting at version 4.0.0, Paperclip has another validation that
cannot be turned off. This validation will prevent content type spoofing. That cannot be turned off. This validation will prevent content type spoofing. That
is, uploading a PHP document (for example) as part of the EXIF tags of a is, uploading a PHP document (for example) as part of the EXIF tags of a
well-formed JPEG. This check is limited to the media type (the first part of the well-formed JPEG. This check is limited to the media type (the first part of the
MIME type, so, 'text' in 'text/plain'). This will prevent HTML documents from MIME type, so, 'text' in `text/plain`). This will prevent HTML documents from
being uploaded as JPEGs, but will not prevent GIFs from being uploaded with a being uploaded as JPEGs, but will not prevent GIFs from being uploaded with a
.jpg extension. This validation will only add validation errors to the form. It `.jpg` extension. This validation will only add validation errors to the form. It
will not cause Errors to be raised. will not cause errors to be raised.
This can sometimes cause false validation errors in applications that use custom This can sometimes cause false validation errors in applications that use custom
file extensions. In these cases you may wish to add your custom extension to the file extensions. In these cases you may wish to add your custom extension to the
list of file extensions allowed for your mime type configured by the mime-types list of file extensions allowed for your MIME type configured by the `mime-types`
gem: gem:
```ruby ```ruby
# Allow ".foo" as an extension for files with the mime type "text/plain". # Allow ".foo" as an extension for files with the MIME type "text/plain".
text_plain = MIME::Types["text/plain"].first text_plain = MIME::Types["text/plain"].first
text_plain.extensions << "foo" text_plain.extensions << "foo"
MIME::Types.index_extensions text_plain MIME::Types.index_extensions text_plain
...@@ -403,9 +449,9 @@ MIME::Types.index_extensions text_plain ...@@ -403,9 +449,9 @@ MIME::Types.index_extensions text_plain
Defaults Defaults
-------- --------
Global defaults for all your paperclip attachments can be defined by changing the Paperclip::Attachment.default_options Hash, this can be useful for setting your default storage settings per example so you won't have to define them in every has_attached_file definition. Global defaults for all your Paperclip attachments can be defined by changing the Paperclip::Attachment.default_options Hash. This can be useful for setting your default storage settings per example so you won't have to define them in every `has_attached_file` definition.
If you're using Rails you can define a Hash with default options in config/application.rb or in any of the config/environments/*.rb files on config.paperclip_defaults, these will get merged into Paperclip::Attachment.default_options as your Rails app boots. An example: If you're using Rails, you can define a Hash with default options in `config/application.rb` or in any of the `config/environments/*.rb` files on config.paperclip_defaults. These will get merged into `Paperclip::Attachment.default_options` as your Rails app boots. An example:
```ruby ```ruby
module YourApp module YourApp
...@@ -417,7 +463,7 @@ module YourApp ...@@ -417,7 +463,7 @@ module YourApp
end end
``` ```
Another option is to directly modify the Paperclip::Attachment.default_options Hash, this method works for non-Rails applications or is an option if you prefer to place the Paperclip default settings in an initializer. Another option is to directly modify the `Paperclip::Attachment.default_options` Hash - this method works for non-Rails applications or is an option if you prefer to place the Paperclip default settings in an initializer.
An example Rails initializer would look something like this: An example Rails initializer would look something like this:
...@@ -432,25 +478,31 @@ Paperclip::Attachment.default_options[:fog_host] = "http://localhost:3000" ...@@ -432,25 +478,31 @@ Paperclip::Attachment.default_options[:fog_host] = "http://localhost:3000"
Migrations Migrations
---------- ----------
Paperclip defines several migration methods which can be used to create necessary columns in your Paperclip defines several migration methods which can be used to create the necessary columns in your
model. There are two types of method: model. There are two types of helper methods to aid in this, as follows:
### Add Attachment Column To A Table
### Table Definition The `attachment` helper can be used when creating a table:
```ruby ```ruby
class AddAttachmentToUsers < ActiveRecord::Migration class CreateUsersWithAttachments < ActiveRecord::Migration
def self.up def up
create_table :users do |t| create_table :users do |t|
t.attachment :avatar t.attachment :avatar
end end
# This is assuming you are only using the users table for Paperclip attachment. Drop with care!
def down
drop_table :users
end end
end end
``` ```
If you're using Rails 3.2 or newer, this method works in `change` method as well: You can also use the `change` method, instead of the `up`/`down` combination above, as shown below:
```ruby ```ruby
class AddAttachmentToUsers < ActiveRecord::Migration class CreateUsersWithAttachments < ActiveRecord::Migration
def change def change
create_table :users do |t| create_table :users do |t|
t.attachment :avatar t.attachment :avatar
...@@ -461,22 +513,24 @@ end ...@@ -461,22 +513,24 @@ end
### Schema Definition ### Schema Definition
Alternatively, the `add_attachment` and `remove_attachment` methods can be used to add new Paperclip columns to an existing table:
```ruby ```ruby
class AddAttachmentToUsers < ActiveRecord::Migration class AddAttachmentColumnsToUsers < ActiveRecord::Migration
def self.up def up
add_attachment :users, :avatar add_attachment :users, :avatar
end end
def self.down def down
remove_attachment :users, :avatar remove_attachment :users, :avatar
end end
end end
``` ```
If you're using Rails 3.2 or newer, you only need `add_attachment` in your `change` method: Or you can do this with the `change` method:
```ruby ```ruby
class AddAttachmentToUsers < ActiveRecord::Migration class AddAttachmentColumnsToUsers < ActiveRecord::Migration
def change def change
add_attachment :users, :avatar add_attachment :users, :avatar
end end
...@@ -485,7 +539,7 @@ end ...@@ -485,7 +539,7 @@ end
### Vintage syntax ### Vintage syntax
Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`) are still supported in Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`) is still supported in
Paperclip 3.x, but you're advised to update those migration files to use this new syntax. Paperclip 3.x, but you're advised to update those migration files to use this new syntax.
--- ---
...@@ -524,7 +578,7 @@ You may also choose to store your files using Amazon's S3 service. To do so, inc ...@@ -524,7 +578,7 @@ You may also choose to store your files using Amazon's S3 service. To do so, inc
the `aws-sdk` gem in your Gemfile: the `aws-sdk` gem in your Gemfile:
```ruby ```ruby
gem 'aws-sdk', '~> 1.5.7' gem 'aws-sdk', '~> 1.6'
``` ```
And then you can specify using S3 from `has_attached_file`. And then you can specify using S3 from `has_attached_file`.
...@@ -545,12 +599,12 @@ Post Processing ...@@ -545,12 +599,12 @@ Post Processing
Paperclip supports an extensible selection of post-processors. When you define Paperclip supports an extensible selection of post-processors. When you define
a set of styles for an attachment, by default it is expected that those a set of styles for an attachment, by default it is expected that those
"styles" are actually "thumbnails". However, you can do much more than just "styles" are actually "thumbnails." However, you can do much more than just
thumbnail images. By defining a subclass of Paperclip::Processor, you can thumbnail images. By defining a subclass of Paperclip::Processor, you can
perform any processing you want on the files that are attached. Any file in perform any processing you want on the files that are attached. Any file in
your Rails app's `lib/paperclip` and `lib/paperclip_processors` directories is your Rails app's `lib/paperclip` and `lib/paperclip_processors` directories is
automatically loaded by paperclip, allowing you to easily define custom automatically loaded by Paperclip, allowing you to easily define custom
processors. You can specify a processor with the :processors option to processors. You can specify a processor with the `:processors` option to
`has_attached_file`: `has_attached_file`:
```ruby ```ruby
...@@ -564,21 +618,21 @@ more information about defining processors, see Paperclip::Processor. ...@@ -564,21 +618,21 @@ more information about defining processors, see Paperclip::Processor.
The default processor is Paperclip::Thumbnail. For backwards compatibility The default processor is Paperclip::Thumbnail. For backwards compatibility
reasons, you can pass a single geometry string or an array containing a reasons, you can pass a single geometry string or an array containing a
geometry and a format, which the file will be converted to, like so: geometry and a format that the file will be converted to, like so:
```ruby ```ruby
has_attached_file :avatar, :styles => { :thumb => ["32x32#", :png] } has_attached_file :avatar, :styles => { :thumb => ["32x32#", :png] }
``` ```
This will convert the "thumb" style to a 32x32 square in png format, regardless This will convert the "thumb" style to a 32x32 square in PNG format, regardless
of what was uploaded. If the format is not specified, it is kept the same (i.e. of what was uploaded. If the format is not specified, it is kept the same (i.e.
jpgs will remain jpgs). For more information on the accepted style formats, see JPGs will remain JPGs). For more information on the accepted style formats, see
[here](http://www.imagemagick.org/script/command-line-processing.php#geometry). [here](http://www.imagemagick.org/script/command-line-processing.php#geometry).
Multiple processors can be specified, and they will be invoked in the order Multiple processors can be specified, and they will be invoked in the order
they are defined in the :processors array. Each successive processor will they are defined in the `:processors` array. Each successive processor will
be given the result of the previous processor's execution. All processors will be given the result of the previous processor's execution. All processors will
receive the same parameters, which are what you define in the :styles hash. receive the same parameters, which are defined in the `:styles` hash.
For example, assuming we had this definition: For example, assuming we had this definition:
```ruby ```ruby
...@@ -587,7 +641,7 @@ has_attached_file :scan, :styles => { :text => { :quality => :better } }, ...@@ -587,7 +641,7 @@ has_attached_file :scan, :styles => { :text => { :quality => :better } },
``` ```
then both the :rotator processor and the :ocr processor would receive the then both the :rotator processor and the :ocr processor would receive the
options "{ :quality => :better }". This parameter may not mean anything to one options `{ :quality => :better }`. This parameter may not mean anything to one
or more or the processors, and they are expected to ignore it. or more or the processors, and they are expected to ignore it.
_NOTE: Because processors operate by turning the original attachment into the _NOTE: Because processors operate by turning the original attachment into the
...@@ -615,8 +669,8 @@ normal ActiveRecord callbacks as possible, so if you return false (specifically ...@@ -615,8 +669,8 @@ normal ActiveRecord callbacks as possible, so if you return false (specifically
will halt. Returning false in an `after_filter` will not halt anything, but you will halt. Returning false in an `after_filter` will not halt anything, but you
can access the model and the attachment if necessary. can access the model and the attachment if necessary.
_NOTE: Post processing will not even *start* if the attachment is not valid _NOTE: Post processing will not even **start** if the attachment is not valid
according to the validations. Your callbacks and processors will *only* be according to the validations. Your callbacks and processors will **only** be
called with valid attachments._ called with valid attachments._
```ruby ```ruby
...@@ -652,24 +706,24 @@ has_attached_file :avatar, { ...@@ -652,24 +706,24 @@ has_attached_file :avatar, {
The `:hash` interpolation will be replaced with a unique hash made up of whatever The `:hash` interpolation will be replaced with a unique hash made up of whatever
is specified in `:hash_data`. The default value for `:hash_data` is `":class/:attachment/:id/:style/:updated_at"`. is specified in `:hash_data`. The default value for `:hash_data` is `":class/:attachment/:id/:style/:updated_at"`.
`:hash_secret` is required, an exception will be raised if `:hash` is used without `:hash_secret` present. `:hash_secret` is required - an exception will be raised if `:hash` is used without `:hash_secret` present.
For more on this feature read the author's own explanation. [https://github.com/thoughtbot/paperclip/pull/416](https://github.com/thoughtbot/paperclip/pull/416) For more on this feature, read [the author's own explanation](https://github.com/thoughtbot/paperclip/pull/416)
MD5 Checksum / Fingerprint MD5 Checksum / Fingerprint
------- -------
A MD5 checksum of the original file assigned will be placed in the model if it An MD5 checksum of the original file assigned will be placed in the model if it
has an attribute named fingerprint. Following the user model migration example has an attribute named fingerprint. Following the user model migration example
above, the migration would look like the following. above, the migration would look like the following:
```ruby ```ruby
class AddAvatarFingerprintColumnToUser < ActiveRecord::Migration class AddAvatarFingerprintColumnToUser < ActiveRecord::Migration
def self.up def up
add_column :users, :avatar_fingerprint, :string add_column :users, :avatar_fingerprint, :string
end end
def self.down def down
remove_column :users, :avatar_fingerprint remove_column :users, :avatar_fingerprint
end end
end end
...@@ -698,11 +752,11 @@ to inherit from `Paperclip::Processor` (see `lib/paperclip/processor.rb`). ...@@ -698,11 +752,11 @@ to inherit from `Paperclip::Processor` (see `lib/paperclip/processor.rb`).
For example, when `:styles` are specified for an image attachment, the For example, when `:styles` are specified for an image attachment, the
thumbnail processor (see `lib/paperclip/thumbnail.rb`) is loaded without having thumbnail processor (see `lib/paperclip/thumbnail.rb`) is loaded without having
to specify it as a `:processor` parameter to `has_attached_file`. When any to specify it as a `:processor` parameter to `has_attached_file`. When any
other processor is defined it must be called out in the `:processors` other processor is defined, it must be called out in the `:processors`
parameter if it is to be applied to the attachment. The thumbnail processor parameter if it is to be applied to the attachment. The thumbnail processor
uses the imagemagick `convert` command to do the work of resizing image uses the ImageMagick `convert` command to do the work of resizing image
thumbnails. It would be easy to create a custom processor that watermarks thumbnails. It would be easy to create a custom processor that watermarks
an image using imagemagick's `composite` command. Following the an image using ImageMagick's `composite` command. Following the
implementation pattern of the thumbnail processor would be a way to implement a implementation pattern of the thumbnail processor would be a way to implement a
watermark processor. All kinds of attachment processors can be created; watermark processor. All kinds of attachment processors can be created;
a few utility examples would be compression and encryption processors. a few utility examples would be compression and encryption processors.
...@@ -722,7 +776,7 @@ instances. ...@@ -722,7 +776,7 @@ instances.
### Dynamic Styles: ### Dynamic Styles:
Imagine a user model that had different styles based on the role of the user. Imagine a user model that had different styles based on the role of the user.
Perhaps some users are bosses (e.g. a User model instance responds to #boss?) Perhaps some users are bosses (e.g. a User model instance responds to `#boss?`)
and merit a bigger avatar thumbnail than regular users. The configuration to and merit a bigger avatar thumbnail than regular users. The configuration to
determine what style parameters are to be used based on the user role might determine what style parameters are to be used based on the user role might
look as follows where a boss will receive a `300x300` thumbnail otherwise a look as follows where a boss will receive a `300x300` thumbnail otherwise a
...@@ -788,7 +842,11 @@ namespace :deploy do ...@@ -788,7 +842,11 @@ namespace :deploy do
desc "build missing paperclip styles" desc "build missing paperclip styles"
task :build_missing_paperclip_styles do task :build_missing_paperclip_styles do
on roles(:app) do on roles(:app) do
execute "cd #{current_path}; RAILS_ENV=production bundle exec rake paperclip:refresh:missing_styles" within release_path do
with rails_env: fetch(:rails_env) do
execute :rake, "paperclip:refresh:missing_styles"
end
end
end end
end end
end end
...@@ -797,7 +855,7 @@ after("deploy:compile_assets", "deploy:build_missing_paperclip_styles") ...@@ -797,7 +855,7 @@ after("deploy:compile_assets", "deploy:build_missing_paperclip_styles")
``` ```
Now you don't have to remember to refresh thumbnails in production every time you add a new style. Now you don't have to remember to refresh thumbnails in production every time you add a new style.
Unfortunately it does not work with dynamic styles - it just ignores them. Unfortunately, it does not work with dynamic styles - it just ignores them.
If you already have a working app and don't want `rake paperclip:refresh:missing_styles` to refresh old pictures, you need to tell If you already have a working app and don't want `rake paperclip:refresh:missing_styles` to refresh old pictures, you need to tell
Paperclip about existing styles. Simply create a `paperclip_attachments.yml` file by hand. For example: Paperclip about existing styles. Simply create a `paperclip_attachments.yml` file by hand. For example:
...@@ -855,7 +913,7 @@ else ...@@ -855,7 +913,7 @@ else
end end
``` ```
The important part here being the inclusion of `ENV['TEST_ENV_NUMBER']`, or the The important part here being the inclusion of `ENV['TEST_ENV_NUMBER']`, or a
similar mechanism for whichever parallel testing library you use. similar mechanism for whichever parallel testing library you use.
**Integration Tests** **Integration Tests**
...@@ -893,23 +951,25 @@ guidelines: ...@@ -893,23 +951,25 @@ guidelines:
Please see `CONTRIBUTING.md` for more details on contributing and running test. Please see `CONTRIBUTING.md` for more details on contributing and running test.
--- Thank you to all [the contributors](https://github.com/thoughtbot/paperclip/contributors)!
Credits License
------- -------
![thoughtbot](http://thoughtbot.com/logo.png) Paperclip is Copyright © 2008-2015 thoughtbot, inc. It is free software, and may be
redistributed under the terms specified in the MIT-LICENSE file.
Paperclip is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community) About thoughtbot
----------------
Thank you to all [the contributors](https://github.com/thoughtbot/paperclip/contributors)! ![thoughtbot](https://thoughtbot.com/logo.png)
Paperclip is maintained and funded by thoughtbot.
The names and logos for thoughtbot are trademarks of thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc.
--- We love open source software!
See [our other projects][community] or
[hire us][hire] to design, develop, and grow your product.
License [community]: https://thoughtbot.com/community?utm_source=github
------- [hire]: https://thoughtbot.com?utm_source=github
Paperclip is Copyright © 2008-2014 thoughtbot, inc. It is free software, and may be
redistributed under the terms specified in the MIT-LICENSE file.
Releasing paperclip
1. Update `lib/paperclip/version.rb` file accordingly.
2. Update `NEWS` to reflect the changes since last release.
3. Commit changes. There shouldn’t be code changes, and thus CI doesn’t need to
run, you can then add “[ci skip]” to the commit message.
4. Tag the release: `git tag -m 'vVERSION' vVERSION`
5. Push changes: `git push --tags`
6. Build and publish the gem:
```bash
gem build paperclip.gemspec
gem push paperclip-VERSION.gem
```
7. Announce the new release, making sure to say “thank you” to the contributors
who helped shape this version.
Running Tests
=============
Please see `CONTRIBUTING.md` in "Running Tests" section for more information.
...@@ -11,7 +11,7 @@ task :all do |t| ...@@ -11,7 +11,7 @@ task :all do |t|
if ENV['BUNDLE_GEMFILE'] if ENV['BUNDLE_GEMFILE']
exec('rake spec cucumber') exec('rake spec cucumber')
else else
exec("rm gemfiles/*.lock") exec("rm -f gemfiles/*.lock")
Rake::Task["appraisal:gemfiles"].execute Rake::Task["appraisal:gemfiles"].execute
Rake::Task["appraisal:install"].execute Rake::Task["appraisal:install"].execute
exec('rake appraisal') exec('rake appraisal')
......
...@@ -12,17 +12,20 @@ Feature: Rails integration ...@@ -12,17 +12,20 @@ Feature: Rails integration
Scenario: Configure defaults for all attachments through Railtie Scenario: Configure defaults for all attachments through Railtie
Given I add this snippet to config/application.rb: Given I add this snippet to config/application.rb:
""" """
config.paperclip_defaults = {:url => "/paperclip/custom/:attachment/:style/:filename"} config.paperclip_defaults = {
:url => "/paperclip/custom/:attachment/:style/:filename",
:validate_media_type => false
}
""" """
And I attach :attachment And I attach :attachment
And I start the rails application And I start the rails application
When I go to the new user page When I go to the new user page
And I fill in "Name" with "something" And I fill in "Name" with "something"
And I attach the file "spec/support/fixtures/5k.png" to "Attachment" And I attach the file "spec/support/fixtures/animated.unknown" to "Attachment"
And I press "Submit" And I press "Submit"
Then I should see "Name: something" Then I should see "Name: something"
And I should see an image with a path of "/paperclip/custom/attachments/original/5k.png" And I should see an image with a path of "/paperclip/custom/attachments/original/animated.unknown"
And the file at "/paperclip/custom/attachments/original/5k.png" should be the same as "spec/support/fixtures/5k.png" And the file at "/paperclip/custom/attachments/original/animated.unknown" should be the same as "spec/support/fixtures/animated.unknown"
Scenario: Add custom processors Scenario: Add custom processors
Given I add a "test" processor in "lib/paperclip" Given I add a "test" processor in "lib/paperclip"
......
...@@ -49,7 +49,13 @@ end ...@@ -49,7 +49,13 @@ end
Then /^the attachment should have the same content type as the fixture "([^"]*)"$/ do |filename| Then /^the attachment should have the same content type as the fixture "([^"]*)"$/ do |filename|
in_current_dir do in_current_dir do
require 'mime/types' begin
# Use mime/types/columnar if available, for reduced memory usage
require "mime/types/columnar"
rescue LoadError
require "mime/types"
end
attachment_content_type = `bundle exec #{runner_command} "puts User.last.attachment_content_type"`.strip attachment_content_type = `bundle exec #{runner_command} "puts User.last.attachment_content_type"`.strip
attachment_content_type.should == MIME::Types.type_for(filename).first.content_type attachment_content_type.should == MIME::Types.type_for(filename).first.content_type
end end
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "sqlite3", "1.3.8", :platforms => :ruby gem "sqlite3", "~>1.3.8", :platforms => :ruby
gem "jruby-openssl", :platforms => :jruby gem "jruby-openssl", :platforms => :jruby
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
gem "rubysl", :platforms => :rbx gem "rubysl", :platforms => :rbx
...@@ -14,6 +14,7 @@ gem "paperclip", :path => "../" ...@@ -14,6 +14,7 @@ gem "paperclip", :path => "../"
group :development, :test do group :development, :test do
gem "mime-types", "~> 1.16" gem "mime-types", "~> 1.16"
gem "builder" gem "builder"
gem "rubocop", :require => false
end end
gemspec :path => "../" gemspec :path => "../"
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "sqlite3", "1.3.8", :platforms => :ruby gem "sqlite3", "~>1.3.8", :platforms => :ruby
gem "jruby-openssl", :platforms => :jruby gem "jruby-openssl", :platforms => :jruby
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
gem "rubysl", :platforms => :rbx gem "rubysl", :platforms => :rbx
...@@ -14,6 +14,7 @@ gem "paperclip", :path => "../" ...@@ -14,6 +14,7 @@ gem "paperclip", :path => "../"
group :development, :test do group :development, :test do
gem "mime-types", "~> 1.16" gem "mime-types", "~> 1.16"
gem "builder" gem "builder"
gem "rubocop", :require => false
end end
gemspec :path => "../" gemspec :path => "../"
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "sqlite3", "1.3.8", :platforms => :ruby gem "sqlite3", "~>1.3.8", :platforms => :ruby
gem "jruby-openssl", :platforms => :jruby gem "jruby-openssl", :platforms => :jruby
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
gem "rubysl", :platforms => :rbx gem "rubysl", :platforms => :rbx
...@@ -14,6 +14,7 @@ gem "paperclip", :path => "../" ...@@ -14,6 +14,7 @@ gem "paperclip", :path => "../"
group :development, :test do group :development, :test do
gem "mime-types", "~> 1.16" gem "mime-types", "~> 1.16"
gem "builder" gem "builder"
gem "rubocop", :require => false
end end
gemspec :path => "../" gemspec :path => "../"
...@@ -2,18 +2,19 @@ ...@@ -2,18 +2,19 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "sqlite3", "1.3.8", :platforms => :ruby gem "sqlite3", "~>1.3.8", :platforms => :ruby
gem "jruby-openssl", :platforms => :jruby gem "jruby-openssl", :platforms => :jruby
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
gem "rubysl", :platforms => :rbx gem "rubysl", :platforms => :rbx
gem "racc", :platforms => :rbx gem "racc", :platforms => :rbx
gem "pry" gem "pry"
gem "rails", "~> 4.2.0.rc2" gem "rails", "~> 4.2.0"
gem "paperclip", :path => "../" gem "paperclip", :path => "../"
group :development, :test do group :development, :test do
gem "mime-types", "~> 1.16" gem "mime-types", "~> 1.16"
gem "builder" gem "builder"
gem "rubocop", :require => false
end end
gemspec :path => "../" gemspec :path => "../"
...@@ -55,7 +55,17 @@ require 'paperclip/helpers' ...@@ -55,7 +55,17 @@ require 'paperclip/helpers'
require 'paperclip/has_attached_file' require 'paperclip/has_attached_file'
require 'paperclip/attachment_registry' require 'paperclip/attachment_registry'
require 'paperclip/filename_cleaner' require 'paperclip/filename_cleaner'
require 'mime/types' require 'paperclip/rails_environment'
begin
# Use mime/types/columnar if available, for reduced memory usage
require "mime/types/columnar"
rescue LoadError
require "mime/types"
end
require 'mimemagic'
require 'mimemagic/overlay'
require 'logger' require 'logger'
require 'cocaine' require 'cocaine'
......
...@@ -137,6 +137,8 @@ module Paperclip ...@@ -137,6 +137,8 @@ module Paperclip
# +#for(style_name, options_hash)+ # +#for(style_name, options_hash)+
def url(style_name = default_style, options = {}) def url(style_name = default_style, options = {})
return nil if @instance.new_record?
if options == true || options == false # Backwards compatibility. if options == true || options == false # Backwards compatibility.
@url_generator.for(style_name, default_options.merge(:timestamp => options)) @url_generator.for(style_name, default_options.merge(:timestamp => options))
else else
...@@ -528,7 +530,7 @@ module Paperclip ...@@ -528,7 +530,7 @@ module Paperclip
@queued_for_write[name] = Paperclip.io_adapters.for(@queued_for_write[name]) @queued_for_write[name] = Paperclip.io_adapters.for(@queued_for_write[name])
unadapted_file.close if unadapted_file.respond_to?(:close) unadapted_file.close if unadapted_file.respond_to?(:close)
@queued_for_write[name] @queued_for_write[name]
rescue Paperclip::Error => e rescue Paperclip::Errors::NotIdentifiedByImageMagickError => e
log("An error was received while processing: #{e.inspect}") log("An error was received while processing: #{e.inspect}")
(@errors[:processing] ||= []) << e.message if @options[:whiny] (@errors[:processing] ||= []) << e.message if @options[:whiny]
ensure ensure
......
...@@ -52,7 +52,7 @@ module Paperclip ...@@ -52,7 +52,7 @@ module Paperclip
def definitions_for(klass) def definitions_for(klass)
klass.ancestors.each_with_object({}) do |ancestor, inherited_definitions| klass.ancestors.each_with_object({}) do |ancestor, inherited_definitions|
inherited_definitions.merge! @attachments[ancestor] inherited_definitions.deep_merge! @attachments[ancestor]
end end
end end
end end
......
...@@ -2,7 +2,7 @@ module Paperclip ...@@ -2,7 +2,7 @@ module Paperclip
class ContentTypeDetector class ContentTypeDetector
# The content-type detection strategy is as follows: # The content-type detection strategy is as follows:
# #
# 1. Blank/Empty files: If there's no filename or the file is empty, # 1. Blank/Empty files: If there's no filepath or the file is empty,
# provide a sensible default (application/octet-stream or inode/x-empty) # provide a sensible default (application/octet-stream or inode/x-empty)
# #
# 2. Calculated match: Return the first result that is found by both the # 2. Calculated match: Return the first result that is found by both the
...@@ -20,8 +20,8 @@ module Paperclip ...@@ -20,8 +20,8 @@ module Paperclip
EMPTY_TYPE = "inode/x-empty" EMPTY_TYPE = "inode/x-empty"
SENSIBLE_DEFAULT = "application/octet-stream" SENSIBLE_DEFAULT = "application/octet-stream"
def initialize(filename) def initialize(filepath)
@filename = filename @filepath = filepath
end end
# Returns a String describing the file's content type # Returns a String describing the file's content type
...@@ -33,32 +33,47 @@ module Paperclip ...@@ -33,32 +33,47 @@ module Paperclip
elsif calculated_type_matches.any? elsif calculated_type_matches.any?
calculated_type_matches.first calculated_type_matches.first
else else
type_from_file_command || SENSIBLE_DEFAULT type_from_file_contents || SENSIBLE_DEFAULT
end.to_s end.to_s
end end
private private
def blank_name?
@filepath.nil? || @filepath.empty?
end
def empty_file? def empty_file?
File.exist?(@filename) && File.size(@filename) == 0 File.exist?(@filepath) && File.size(@filepath) == 0
end end
alias :empty? :empty_file? alias :empty? :empty_file?
def blank_name? def calculated_type_matches
@filename.nil? || @filename.empty? possible_types.select do |content_type|
content_type == type_from_file_contents
end
end end
def possible_types def possible_types
MIME::Types.type_for(@filename).collect(&:content_type) MIME::Types.type_for(@filepath).collect(&:content_type)
end end
def calculated_type_matches def type_from_file_contents
possible_types.select{|content_type| content_type == type_from_file_command } type_from_mime_magic || type_from_file_command
rescue Errno::ENOENT => e
Paperclip.log("Error while determining content type: #{e}")
SENSIBLE_DEFAULT
end
def type_from_mime_magic
@type_from_mime_magic ||=
MimeMagic.by_magic(File.open(@filepath)).try(:type)
end end
def type_from_file_command def type_from_file_command
@type_from_file_command ||= FileCommandContentTypeDetector.new(@filename).detect @type_from_file_command ||=
FileCommandContentTypeDetector.new(@filepath).detect
end end
end end
end end
...@@ -13,9 +13,9 @@ module Paperclip ...@@ -13,9 +13,9 @@ module Paperclip
private private
def type_from_file_command def type_from_file_command
type = begin
# On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist. # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
Paperclip.run("file", "-b --mime :file", :file => @filename) type = begin
Paperclip.run("file", "-b --mime :file", file: @filename)
rescue Cocaine::CommandLineError => e rescue Cocaine::CommandLineError => e
Paperclip.log("Error while determining content type: #{e}") Paperclip.log("Error while determining content type: #{e}")
SENSIBLE_DEFAULT SENSIBLE_DEFAULT
...@@ -26,7 +26,5 @@ module Paperclip ...@@ -26,7 +26,5 @@ module Paperclip
end end
type.split(/[:;\s]+/)[0] type.split(/[:;\s]+/)[0]
end end
end end
end end
...@@ -8,7 +8,7 @@ module Paperclip ...@@ -8,7 +8,7 @@ module Paperclip
base.extend ClassMethods base.extend ClassMethods
base.send :include, Callbacks base.send :include, Callbacks
base.send :include, Validators base.send :include, Validators
base.send :include, Schema if defined? ActiveRecord base.send :include, Schema
locale_path = Dir.glob(File.dirname(__FILE__) + "/locales/*.{rb,yml}") locale_path = Dir.glob(File.dirname(__FILE__) + "/locales/*.{rb,yml}")
I18n.load_path += locale_path unless I18n.load_path.include?(locale_path) I18n.load_path += locale_path unless I18n.load_path.include?(locale_path)
......
...@@ -79,7 +79,8 @@ module Paperclip ...@@ -79,7 +79,8 @@ module Paperclip
end end
def add_required_validations def add_required_validations
if @options[:validate_media_type] != false options = Paperclip::Attachment.default_options.deep_merge(@options)
if options[:validate_media_type] != false
name = @name name = @name
@klass.validates_media_type_spoof_detection name, @klass.validates_media_type_spoof_detection name,
:if => ->(instance){ instance.send(name).dirty? } :if => ->(instance){ instance.send(name).dirty? }
......
...@@ -172,7 +172,7 @@ module Paperclip ...@@ -172,7 +172,7 @@ module Paperclip
when Integer when Integer
("%09d" % id).scan(/\d{3}/).join("/") ("%09d" % id).scan(/\d{3}/).join("/")
when String when String
('%9.9s' % id).tr(" ", "0").scan(/.{3}/).join("/") id.scan(/.{3}/).first(3).join("/")
else else
nil nil
end end
......
...@@ -6,6 +6,7 @@ module Paperclip ...@@ -6,6 +6,7 @@ module Paperclip
attr_reader :content_type, :original_filename, :size attr_reader :content_type, :original_filename, :size
delegate :binmode, :binmode?, :close, :close!, :closed?, :eof?, :path, :rewind, :unlink, :to => :@tempfile delegate :binmode, :binmode?, :close, :close!, :closed?, :eof?, :path, :rewind, :unlink, :to => :@tempfile
alias :length :size
def fingerprint def fingerprint
@fingerprint ||= Digest::MD5.file(path).to_s @fingerprint ||= Digest::MD5.file(path).to_s
......
...@@ -42,7 +42,7 @@ module Paperclip ...@@ -42,7 +42,7 @@ module Paperclip
end end
def mapping_override_mismatch? def mapping_override_mismatch?
mapped_content_type != calculated_content_type !Array(mapped_content_type).include?(calculated_content_type)
end end
......
module Paperclip
class RailsEnvironment
def self.get
new.get
end
def get
if rails_exists? && rails_environment_exists?
Rails.env
else
nil
end
end
private
def rails_exists?
Object.const_defined?("Rails")
end
def rails_environment_exists?
Rails.respond_to?(:env)
end
end
end
...@@ -141,8 +141,9 @@ module Paperclip ...@@ -141,8 +141,9 @@ module Paperclip
def expiring_url(time = (Time.now + 3600), style_name = default_style) def expiring_url(time = (Time.now + 3600), style_name = default_style)
time = convert_time(time) time = convert_time(time)
if path(style_name) && directory.files.respond_to?(:get_http_url) http_url_method = "get_#{scheme}_url"
expiring_url = directory.files.get_http_url(path(style_name), time) if path(style_name) && directory.files.respond_to?(http_url_method)
expiring_url = directory.files.public_send(http_url_method, path(style_name), time)
if @options[:fog_host] if @options[:fog_host]
expiring_url.gsub!(/#{host_name_for_directory}/, dynamic_fog_host_for_style(style_name)) expiring_url.gsub!(/#{host_name_for_directory}/, dynamic_fog_host_for_style(style_name))
...@@ -156,8 +157,7 @@ module Paperclip ...@@ -156,8 +157,7 @@ module Paperclip
def parse_credentials(creds) def parse_credentials(creds)
creds = find_credentials(creds).stringify_keys creds = find_credentials(creds).stringify_keys
env = Object.const_defined?(:Rails) ? Rails.env : nil (creds[RailsEnvironment.get] || creds).symbolize_keys
(creds[env] || creds).symbolize_keys
end end
def copy_to_local_file(style, local_dest_path) def copy_to_local_file(style, local_dest_path)
......
...@@ -4,7 +4,7 @@ module Paperclip ...@@ -4,7 +4,7 @@ module Paperclip
# distribution. You can find out more about it at http://aws.amazon.com/s3 # distribution. You can find out more about it at http://aws.amazon.com/s3
# #
# To use Paperclip with S3, include the +aws-sdk+ gem in your Gemfile: # To use Paperclip with S3, include the +aws-sdk+ gem in your Gemfile:
# gem 'aws-sdk' # gem 'aws-sdk', '~> 1.6'
# There are a few S3-specific options for has_attached_file: # There are a few S3-specific options for has_attached_file:
# * +s3_credentials+: Takes a path, a File, a Hash or a Proc. The path (or File) must point # * +s3_credentials+: Takes a path, a File, a Hash or a Proc. The path (or File) must point
# to a YAML file containing the +access_key_id+ and +secret_access_key+ that Amazon # to a YAML file containing the +access_key_id+ and +secret_access_key+ that Amazon
...@@ -288,8 +288,7 @@ module Paperclip ...@@ -288,8 +288,7 @@ module Paperclip
def parse_credentials creds def parse_credentials creds
creds = creds.respond_to?('call') ? creds.call(self) : creds creds = creds.respond_to?('call') ? creds.call(self) : creds
creds = find_credentials(creds).stringify_keys creds = find_credentials(creds).stringify_keys
env = Object.const_defined?(:Rails) ? Rails.env : nil (creds[RailsEnvironment.get] || creds).symbolize_keys
(creds[env] || creds).symbolize_keys
end end
def exists?(style = default_style) def exists?(style = default_style)
......
...@@ -29,7 +29,6 @@ module Paperclip ...@@ -29,7 +29,6 @@ module Paperclip
super super
geometry = options[:geometry].to_s geometry = options[:geometry].to_s
@file = file
@crop = geometry[-1,1] == '#' @crop = geometry[-1,1] == '#'
@target_geometry = options.fetch(:string_geometry_parser, Geometry).parse(geometry) @target_geometry = options.fetch(:string_geometry_parser, Geometry).parse(geometry)
@current_geometry = options.fetch(:file_geometry_parser, Geometry).from_file(@file) @current_geometry = options.fetch(:file_geometry_parser, Geometry).from_file(@file)
...@@ -64,8 +63,8 @@ module Paperclip ...@@ -64,8 +63,8 @@ module Paperclip
# that contains the new image. # that contains the new image.
def make def make
src = @file src = @file
dst = Tempfile.new([@basename, @format ? ".#{@format}" : '']) filename = [@basename, @format ? ".#{@format}" : ""].join
dst.binmode dst = TempfileFactory.new.generate(filename)
begin begin
parameters = [] parameters = []
......
...@@ -108,4 +108,20 @@ namespace :paperclip do ...@@ -108,4 +108,20 @@ namespace :paperclip do
end end
end end
end end
desc "find missing attachments. Useful to know which attachments are broken"
task :find_broken_attachments => :environment do
klass = Paperclip::Task.obtain_class
names = Paperclip::Task.obtain_attachments(klass)
names.each do |name|
Paperclip.each_instance_with_attachment(klass, name) do |instance|
attachment = instance.send(name)
if attachment.exists?
print "."
else
Paperclip::Task.log_error("#{instance.class}##{attachment.name}, #{instance.id}, #{attachment.url}")
end
end
end
end
end end
...@@ -12,8 +12,6 @@ Gem::Specification.new do |s| ...@@ -12,8 +12,6 @@ Gem::Specification.new do |s|
s.description = "Easy upload management for ActiveRecord" s.description = "Easy upload management for ActiveRecord"
s.license = "MIT" s.license = "MIT"
s.rubyforge_project = "paperclip"
s.files = `git ls-files`.split("\n") s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {spec,features}/*`.split("\n") s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
...@@ -24,21 +22,22 @@ Gem::Specification.new do |s| ...@@ -24,21 +22,22 @@ Gem::Specification.new do |s|
s.add_dependency('activemodel', '>= 3.0.0') s.add_dependency('activemodel', '>= 3.0.0')
s.add_dependency('activesupport', '>= 3.0.0') s.add_dependency('activesupport', '>= 3.0.0')
s.add_dependency('cocaine', '~> 0.5.3') s.add_dependency('cocaine', '~> 0.5.5')
s.add_dependency('mime-types') s.add_dependency('mime-types')
s.add_dependency('mimemagic', '0.3.0')
s.add_development_dependency('activerecord', '>= 3.0.0') s.add_development_dependency('activerecord', '>= 3.0.0')
s.add_development_dependency('shoulda') s.add_development_dependency('shoulda')
s.add_development_dependency('rspec') s.add_development_dependency('rspec')
s.add_development_dependency('appraisal') s.add_development_dependency('appraisal')
s.add_development_dependency('mocha') s.add_development_dependency('mocha')
s.add_development_dependency('aws-sdk', '>= 1.5.7') s.add_development_dependency('aws-sdk', '~> 1.6')
s.add_development_dependency('bourne') s.add_development_dependency('bourne')
s.add_development_dependency('cucumber', '~> 1.3.11') s.add_development_dependency('cucumber', '~> 1.3.18')
s.add_development_dependency('aruba') s.add_development_dependency('aruba')
s.add_development_dependency('nokogiri') s.add_development_dependency('nokogiri')
# Ruby version < 1.9.3 can't install capybara > 2.0.3. # Ruby version < 1.9.3 can't install capybara > 2.0.3.
s.add_development_dependency('capybara', '= 2.0.3') s.add_development_dependency('capybara')
s.add_development_dependency('bundler') s.add_development_dependency('bundler')
s.add_development_dependency('fog', '~> 1.0') s.add_development_dependency('fog', '~> 1.0')
s.add_development_dependency('launchy') s.add_development_dependency('launchy')
......
...@@ -8,6 +8,6 @@ describe "Attachment Definitions" do ...@@ -8,6 +8,6 @@ describe "Attachment Definitions" do
Dummy.do_not_validate_attachment_file_type :avatar Dummy.do_not_validate_attachment_file_type :avatar
expected = {avatar: {path: "abc"}, other_attachment: {url: "123"}} expected = {avatar: {path: "abc"}, other_attachment: {url: "123"}}
assert_equal expected, Dummy.attachment_definitions expect(Dummy.attachment_definitions).to eq expected
end end
end end
...@@ -31,8 +31,8 @@ describe 'Attachment Registry' do ...@@ -31,8 +31,8 @@ describe 'Attachment Registry' do
it 'calls the block with the class, attachment name, and options' do it 'calls the block with the class, attachment name, and options' do
foo = Class.new foo = Class.new
expected_accumulations = [ expected_accumulations = [
[foo, :avatar, { yo: 'greeting' }], [foo, :avatar, { yo: "greeting" }],
[foo, :greeter, { ciao: 'greeting' }] [foo, :greeter, { ciao: "greeting" }]
] ]
expected_accumulations.each do |args| expected_accumulations.each do |args|
Paperclip::AttachmentRegistry.register(*args) Paperclip::AttachmentRegistry.register(*args)
...@@ -50,25 +50,64 @@ describe 'Attachment Registry' do ...@@ -50,25 +50,64 @@ describe 'Attachment Registry' do
context '.definitions_for' do context '.definitions_for' do
it 'produces the attachment name and options' do it 'produces the attachment name and options' do
expected_definitions = { expected_definitions = {
avatar: { yo: 'greeting' }, avatar: { yo: "greeting" },
greeter: { ciao: 'greeting' } greeter: { ciao: "greeting" }
} }
foo = Class.new foo = Class.new
Paperclip::AttachmentRegistry.register(foo, :avatar, { yo: 'greeting' }) Paperclip::AttachmentRegistry.register(
Paperclip::AttachmentRegistry.register(foo, :greeter, { ciao: 'greeting' }) foo,
:avatar,
yo: "greeting"
)
Paperclip::AttachmentRegistry.register(
foo,
:greeter,
ciao: "greeting"
)
definitions = Paperclip::AttachmentRegistry.definitions_for(foo) definitions = Paperclip::AttachmentRegistry.definitions_for(foo)
assert_equal expected_definitions, definitions assert_equal expected_definitions, definitions
end end
it "produces defintions for subclasses" do it 'produces defintions for subclasses' do
expected_definitions = { avatar: { yo: 'greeting' } } expected_definitions = { avatar: { yo: "greeting" } }
Foo = Class.new foo = Class.new
Bar = Class.new(Foo) bar = Class.new(foo)
Paperclip::AttachmentRegistry.register(Foo, :avatar, expected_definitions[:avatar]) Paperclip::AttachmentRegistry.register(
foo,
:avatar,
expected_definitions[:avatar]
)
definitions = Paperclip::AttachmentRegistry.definitions_for(bar)
assert_equal expected_definitions, definitions
end
definitions = Paperclip::AttachmentRegistry.definitions_for(Bar) it 'produces defintions for subclasses but deep merging them' do
foo_definitions = { avatar: { yo: "greeting" } }
bar_definitions = { avatar: { ciao: "greeting" } }
expected_definitions = {
avatar: {
yo: "greeting",
ciao: "greeting"
}
}
foo = Class.new
bar = Class.new(foo)
Paperclip::AttachmentRegistry.register(
foo,
:avatar,
foo_definitions[:avatar]
)
Paperclip::AttachmentRegistry.register(
bar,
:avatar,
bar_definitions[:avatar]
)
definitions = Paperclip::AttachmentRegistry.definitions_for(bar)
assert_equal expected_definitions, definitions assert_equal expected_definitions, definitions
end end
...@@ -77,7 +116,11 @@ describe 'Attachment Registry' do ...@@ -77,7 +116,11 @@ describe 'Attachment Registry' do
context '.clear' do context '.clear' do
it 'removes all of the existing attachment definitions' do it 'removes all of the existing attachment definitions' do
foo = Class.new foo = Class.new
Paperclip::AttachmentRegistry.register(foo, :greeter, { ciao: 'greeting' }) Paperclip::AttachmentRegistry.register(
foo,
:greeter,
ciao: "greeting"
)
Paperclip::AttachmentRegistry.clear Paperclip::AttachmentRegistry.clear
......
...@@ -34,9 +34,9 @@ describe Paperclip::Attachment do ...@@ -34,9 +34,9 @@ describe Paperclip::Attachment do
it "does not delete styles that don't get reprocessed" do it "does not delete styles that don't get reprocessed" do
file = File.new(fixture_file("50x50.png"), 'rb') file = File.new(fixture_file("50x50.png"), 'rb')
rebuild_class styles: { rebuild_class styles: {
small: '100x>', small: "100x>",
large: '500x>', large: "500x>",
original: '42x42#' original: "42x42#"
} }
dummy = Dummy.new dummy = Dummy.new
...@@ -75,7 +75,11 @@ describe Paperclip::Attachment do ...@@ -75,7 +75,11 @@ describe Paperclip::Attachment do
it "handles a boolean second argument to #url" do it "handles a boolean second argument to #url" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, :instance, url_generator: mock_url_generator_builder) attachment = Paperclip::Attachment.new(
:name,
FakeModel.new,
url_generator: mock_url_generator_builder
)
attachment.url(:style_name, true) attachment.url(:style_name, true)
expect(mock_url_generator_builder.has_generated_url_with_options?(timestamp: true, escape: true)).to eq true expect(mock_url_generator_builder.has_generated_url_with_options?(timestamp: true, escape: true)).to eq true
...@@ -86,7 +90,11 @@ describe Paperclip::Attachment do ...@@ -86,7 +90,11 @@ describe Paperclip::Attachment do
it "passes the style and options through to the URL generator on #url" do it "passes the style and options through to the URL generator on #url" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, :instance, url_generator: mock_url_generator_builder) attachment = Paperclip::Attachment.new(
:name,
FakeModel.new,
url_generator: mock_url_generator_builder
)
attachment.url(:style_name, options: :values) attachment.url(:style_name, options: :values)
expect(mock_url_generator_builder.has_generated_url_with_options?(options: :values)).to eq true expect(mock_url_generator_builder.has_generated_url_with_options?(options: :values)).to eq true
...@@ -95,7 +103,7 @@ describe Paperclip::Attachment do ...@@ -95,7 +103,7 @@ describe Paperclip::Attachment do
it "passes default options through when #url is given one argument" do it "passes default options through when #url is given one argument" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, attachment = Paperclip::Attachment.new(:name,
:instance, FakeModel.new,
url_generator: mock_url_generator_builder, url_generator: mock_url_generator_builder,
use_timestamp: true) use_timestamp: true)
...@@ -106,7 +114,7 @@ describe Paperclip::Attachment do ...@@ -106,7 +114,7 @@ describe Paperclip::Attachment do
it "passes default style and options through when #url is given no arguments" do it "passes default style and options through when #url is given no arguments" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, attachment = Paperclip::Attachment.new(:name,
:instance, FakeModel.new,
default_style: 'default style', default_style: 'default style',
url_generator: mock_url_generator_builder, url_generator: mock_url_generator_builder,
use_timestamp: true) use_timestamp: true)
...@@ -119,7 +127,7 @@ describe Paperclip::Attachment do ...@@ -119,7 +127,7 @@ describe Paperclip::Attachment do
it "passes the option timestamp: true if :use_timestamp is true and :timestamp is not passed" do it "passes the option timestamp: true if :use_timestamp is true and :timestamp is not passed" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, attachment = Paperclip::Attachment.new(:name,
:instance, FakeModel.new,
url_generator: mock_url_generator_builder, url_generator: mock_url_generator_builder,
use_timestamp: true) use_timestamp: true)
...@@ -130,7 +138,7 @@ describe Paperclip::Attachment do ...@@ -130,7 +138,7 @@ describe Paperclip::Attachment do
it "passes the option timestamp: false if :use_timestamp is false and :timestamp is not passed" do it "passes the option timestamp: false if :use_timestamp is false and :timestamp is not passed" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, attachment = Paperclip::Attachment.new(:name,
:instance, FakeModel.new,
url_generator: mock_url_generator_builder, url_generator: mock_url_generator_builder,
use_timestamp: false) use_timestamp: false)
...@@ -141,7 +149,7 @@ describe Paperclip::Attachment do ...@@ -141,7 +149,7 @@ describe Paperclip::Attachment do
it "does not change the :timestamp if :timestamp is passed" do it "does not change the :timestamp if :timestamp is passed" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, attachment = Paperclip::Attachment.new(:name,
:instance, FakeModel.new,
url_generator: mock_url_generator_builder, url_generator: mock_url_generator_builder,
use_timestamp: false) use_timestamp: false)
...@@ -152,7 +160,7 @@ describe Paperclip::Attachment do ...@@ -152,7 +160,7 @@ describe Paperclip::Attachment do
it "renders JSON as default style" do it "renders JSON as default style" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, attachment = Paperclip::Attachment.new(:name,
:instance, FakeModel.new,
default_style: 'default style', default_style: 'default style',
url_generator: mock_url_generator_builder) url_generator: mock_url_generator_builder)
...@@ -163,7 +171,7 @@ describe Paperclip::Attachment do ...@@ -163,7 +171,7 @@ describe Paperclip::Attachment do
it "passes the option escape: true if :escape_url is true and :escape is not passed" do it "passes the option escape: true if :escape_url is true and :escape is not passed" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, attachment = Paperclip::Attachment.new(:name,
:instance, FakeModel.new,
url_generator: mock_url_generator_builder, url_generator: mock_url_generator_builder,
escape_url: true) escape_url: true)
...@@ -174,7 +182,7 @@ describe Paperclip::Attachment do ...@@ -174,7 +182,7 @@ describe Paperclip::Attachment do
it "passes the option escape: false if :escape_url is false and :escape is not passed" do it "passes the option escape: false if :escape_url is false and :escape is not passed" do
mock_url_generator_builder = MockUrlGeneratorBuilder.new mock_url_generator_builder = MockUrlGeneratorBuilder.new
attachment = Paperclip::Attachment.new(:name, attachment = Paperclip::Attachment.new(:name,
:instance, FakeModel.new,
url_generator: mock_url_generator_builder, url_generator: mock_url_generator_builder,
escape_url: false) escape_url: false)
...@@ -212,6 +220,7 @@ describe Paperclip::Attachment do ...@@ -212,6 +220,7 @@ describe Paperclip::Attachment do
dummy = Dummy.new dummy = Dummy.new
dummy.id = 1234 dummy.id = 1234
dummy.avatar_file_name = "fake.jpg" dummy.avatar_file_name = "fake.jpg"
dummy.stubs(:new_record?).returns(false)
expected_string = '{"avatar":"/system/dummies/avatars/000/001/234/original/fake.jpg"}' expected_string = '{"avatar":"/system/dummies/avatars/000/001/234/original/fake.jpg"}'
if ActiveRecord::Base.include_root_in_json # This is true by default in Rails 3, and false in 4 if ActiveRecord::Base.include_root_in_json # This is true by default in Rails 3, and false in 4
expected_string = %({"dummy":#{expected_string}}) expected_string = %({"dummy":#{expected_string}})
...@@ -251,6 +260,10 @@ describe Paperclip::Attachment do ...@@ -251,6 +260,10 @@ describe Paperclip::Attachment do
it "returns false when asked exists?" do it "returns false when asked exists?" do
assert !@dummy.avatar.exists? assert !@dummy.avatar.exists?
end end
it "#url returns nil" do
assert_nil @dummy.avatar.url
end
end end
context "on an Attachment" do context "on an Attachment" do
...@@ -635,15 +648,40 @@ describe Paperclip::Attachment do ...@@ -635,15 +648,40 @@ describe Paperclip::Attachment do
before do before do
rebuild_model processor: [:thumbnail], styles: { small: '' }, whiny_thumbnails: true rebuild_model processor: [:thumbnail], styles: { small: '' }, whiny_thumbnails: true
@dummy = Dummy.new @dummy = Dummy.new
Paperclip::Thumbnail.expects(:make).raises(Paperclip::Error, "cannot be processed.")
@file = StringIO.new("...") @file = StringIO.new("...")
@file.stubs(:to_tempfile).returns(@file) @file.stubs(:to_tempfile).returns(@file)
@dummy.avatar = @file end
context "when error is meaningful for the end user" do
before do
Paperclip::Thumbnail.expects(:make).raises(
Paperclip::Errors::NotIdentifiedByImageMagickError,
"cannot be processed."
)
end end
it "correctly forwards processing error message to the instance" do it "correctly forwards processing error message to the instance" do
@dummy.avatar = @file
@dummy.valid? @dummy.valid?
assert_contains @dummy.errors.full_messages, "Avatar cannot be processed." assert_contains(
@dummy.errors.full_messages,
"Avatar cannot be processed."
)
end
end
context "when error is intended for the developer" do
before do
Paperclip::Thumbnail.expects(:make).raises(
Paperclip::Errors::CommandNotFoundError
)
end
it "propagates the error" do
assert_raises(Paperclip::Errors::CommandNotFoundError) do
@dummy.avatar = @file
end
end
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe Paperclip::ContentTypeDetector do describe Paperclip::ContentTypeDetector do
it 'returns a meaningful content type for open xml spreadsheets' do
file = File.new(fixture_file("empty.xlsx"))
assert_equal "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
Paperclip::ContentTypeDetector.new(file.path).detect
end
it 'gives a sensible default when the name is empty' do it 'gives a sensible default when the name is empty' do
assert_equal "application/octet-stream", Paperclip::ContentTypeDetector.new("").detect assert_equal "application/octet-stream", Paperclip::ContentTypeDetector.new("").detect
end end
...@@ -13,7 +19,8 @@ describe Paperclip::ContentTypeDetector do ...@@ -13,7 +19,8 @@ describe Paperclip::ContentTypeDetector do
it 'returns content type of file if it is an acceptable type' do it 'returns content type of file if it is an acceptable type' do
MIME::Types.stubs(:type_for).returns([MIME::Type.new('application/mp4'), MIME::Type.new('video/mp4'), MIME::Type.new('audio/mp4')]) MIME::Types.stubs(:type_for).returns([MIME::Type.new('application/mp4'), MIME::Type.new('video/mp4'), MIME::Type.new('audio/mp4')])
Paperclip.stubs(:run).returns("video/mp4") Paperclip::ContentTypeDetector.any_instance
.stubs(:type_from_file_contents).returns("video/mp4")
@filename = "my_file.mp4" @filename = "my_file.mp4"
assert_equal "video/mp4", Paperclip::ContentTypeDetector.new(@filename).detect assert_equal "video/mp4", Paperclip::ContentTypeDetector.new(@filename).detect
end end
......
...@@ -24,4 +24,3 @@ describe Paperclip::FileCommandContentTypeDetector do ...@@ -24,4 +24,3 @@ describe Paperclip::FileCommandContentTypeDetector do
Paperclip::FileCommandContentTypeDetector.new("windows").detect Paperclip::FileCommandContentTypeDetector.new("windows").detect
end end
end end
...@@ -138,14 +138,7 @@ describe Paperclip::Interpolations do ...@@ -138,14 +138,7 @@ describe Paperclip::Interpolations do
assert_equal "000/000/023", Paperclip::Interpolations.id_partition(attachment, :style) assert_equal "000/000/023", Paperclip::Interpolations.id_partition(attachment, :style)
end end
it "returns the partitioned id of the attachment when the id is a short string" do it "returns the partitioned id of the attachment when the id is a string" do
attachment = mock
attachment.expects(:id).returns("fnj23")
attachment.expects(:instance).returns(attachment)
assert_equal "000/0fn/j23", Paperclip::Interpolations.id_partition(attachment, :style)
end
it "returns the partitioned id of the attachment when the id is a long string" do
attachment = mock attachment = mock
attachment.expects(:id).returns("32fnj23oio2f") attachment.expects(:id).returns("32fnj23oio2f")
attachment.expects(:instance).returns(attachment) attachment.expects(:instance).returns(attachment)
......
...@@ -9,11 +9,12 @@ describe Paperclip::AbstractAdapter do ...@@ -9,11 +9,12 @@ describe Paperclip::AbstractAdapter do
end end
end end
context "content type from file command" do context "content type from file contents" do
before do before do
@adapter = TestAdapter.new @adapter = TestAdapter.new
@adapter.stubs(:path).returns("image.png") @adapter.stubs(:path).returns("image.png")
Paperclip.stubs(:run).returns("image/png\n") Paperclip.stubs(:run).returns("image/png\n")
Paperclip::ContentTypeDetector.any_instance.stubs(:type_from_mime_magic).returns("image/png")
end end
it "returns the content type without newline" do it "returns the content type without newline" do
......
...@@ -73,10 +73,13 @@ describe Paperclip::FileAdapter do ...@@ -73,10 +73,13 @@ describe Paperclip::FileAdapter do
end end
end end
context "file with content type derived from file command on *nix" do context "file with content type derived from file contents on *nix" do
before do before do
MIME::Types.stubs(:type_for).returns([]) MIME::Types.stubs(:type_for).returns([])
Paperclip.stubs(:run).returns("application/vnd.ms-office\n") Paperclip.stubs(:run).returns("application/vnd.ms-office\n")
Paperclip::ContentTypeDetector.any_instance
.stubs(:type_from_mime_magic).returns("application/vnd.ms-office")
@subject = Paperclip.io_adapters.for(@file) @subject = Paperclip.io_adapters.for(@file)
end end
......
...@@ -20,6 +20,10 @@ describe Paperclip::StringioAdapter do ...@@ -20,6 +20,10 @@ describe Paperclip::StringioAdapter do
assert_equal 6, @subject.size assert_equal 6, @subject.size
end end
it "returns the length of the data" do
assert_equal 6, @subject.length
end
it "generates an MD5 hash of the contents" do it "generates an MD5 hash of the contents" do
assert_equal Digest::MD5.hexdigest(@contents), @subject.fingerprint assert_equal Digest::MD5.hexdigest(@contents), @subject.fingerprint
end end
......
...@@ -53,4 +53,18 @@ describe Paperclip::MediaTypeSpoofDetector do ...@@ -53,4 +53,18 @@ describe Paperclip::MediaTypeSpoofDetector do
file = File.open(fixture_file("empty.html")) file = File.open(fixture_file("empty.html"))
assert ! Paperclip::MediaTypeSpoofDetector.using(file, "empty.html", "").spoofed? assert ! Paperclip::MediaTypeSpoofDetector.using(file, "empty.html", "").spoofed?
end end
it 'does allow array as :content_type_mappings' do
begin
Paperclip.options[:content_type_mappings] = {
html: ['binary', 'text/html']
}
file = File.open(fixture_file('empty.html'))
spoofed = Paperclip::MediaTypeSpoofDetector
.using(file, 'empty.html').spoofed?
assert !spoofed
ensure
Paperclip.options[:content_type_mappings] = {}
end
end
end end
...@@ -20,7 +20,7 @@ describe Paperclip do ...@@ -20,7 +20,7 @@ describe Paperclip do
it "saves Cocaine::CommandLine.path that set before" do it "saves Cocaine::CommandLine.path that set before" do
Cocaine::CommandLine.path = "/opt/my_app/bin" Cocaine::CommandLine.path = "/opt/my_app/bin"
Paperclip.run("convert", "stuff") Paperclip.run("convert", "stuff")
assert_equal [Cocaine::CommandLine.path].flatten.include?("/opt/my_app/bin"), true assert_equal Cocaine::CommandLine.path.include?("/opt/my_app/bin"), true
end end
it "does not duplicate Cocaine::CommandLine.path on multiple runs" do it "does not duplicate Cocaine::CommandLine.path on multiple runs" do
......
require 'spec_helper'
describe Paperclip::RailsEnvironment do
it "returns nil when Rails isn't defined" do
resetting_rails_to(nil) do
expect(Paperclip::RailsEnvironment.get).to be_nil
end
end
it "returns nil when Rails.env isn't defined" do
resetting_rails_to({}) do
expect(Paperclip::RailsEnvironment.get).to be_nil
end
end
it "returns the value of Rails.env if it is set" do
resetting_rails_to(OpenStruct.new(env: "foo")) do
expect(Paperclip::RailsEnvironment.get).to eq "foo"
end
end
def resetting_rails_to(new_value)
begin
previous_rails = Object.send(:remove_const, "Rails")
Object.const_set("Rails", new_value) unless new_value.nil?
yield
ensure
Object.send(:remove_const, "Rails") if Object.const_defined?("Rails")
Object.const_set("Rails", previous_rails)
end
end
end
...@@ -320,6 +320,9 @@ describe Paperclip::Storage::Fog do ...@@ -320,6 +320,9 @@ describe Paperclip::Storage::Fog do
it "honors the scheme in public url" do it "honors the scheme in public url" do
assert_match(/^http:\/\//, @dummy.avatar.url) assert_match(/^http:\/\//, @dummy.avatar.url)
end end
it "honors the scheme in expiring url" do
assert_match(/^http:\/\//, @dummy.avatar.expiring_url)
end
end end
context "with scheme not set" do context "with scheme not set" do
...@@ -334,15 +337,20 @@ describe Paperclip::Storage::Fog do ...@@ -334,15 +337,20 @@ describe Paperclip::Storage::Fog do
it "provides HTTPS public url" do it "provides HTTPS public url" do
assert_match(/^https:\/\//, @dummy.avatar.url) assert_match(/^https:\/\//, @dummy.avatar.url)
end end
it "provides HTTPS expiring url" do
assert_match(/^https:\/\//, @dummy.avatar.expiring_url)
end
end end
context "with a valid bucket name for a subdomain" do context "with a valid bucket name for a subdomain" do
before { @dummy.stubs(:new_record?).returns(false) }
it "provides an url in subdomain style" do it "provides an url in subdomain style" do
assert_match(/^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png/, @dummy.avatar.url) assert_match(/^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png/, @dummy.avatar.url)
end end
it "provides an url that expires in subdomain style" do it "provides an url that expires in subdomain style" do
assert_match(/^http:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url) assert_match(/^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url)
end end
end end
...@@ -390,7 +398,7 @@ describe Paperclip::Storage::Fog do ...@@ -390,7 +398,7 @@ describe Paperclip::Storage::Fog do
end end
it "provides a url that expires in folder style" do it "provides a url that expires in folder style" do
assert_match(/^http:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url) assert_match(/^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png.+Expires=.+$/, @dummy.avatar.expiring_url)
end end
end end
...@@ -492,6 +500,7 @@ describe Paperclip::Storage::Fog do ...@@ -492,6 +500,7 @@ describe Paperclip::Storage::Fog do
@file = File.new(fixture_file('5k.png'), 'rb') @file = File.new(fixture_file('5k.png'), 'rb')
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = @file @dummy.avatar = @file
@dummy.stubs(:new_record?).returns(false)
end end
after do after do
......
...@@ -105,6 +105,7 @@ describe Paperclip::Storage::S3 do ...@@ -105,6 +105,7 @@ describe Paperclip::Storage::S3 do
url: ":s3_path_url" url: ":s3_path_url"
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a url based on an S3 path" do it "returns a url based on an S3 path" do
...@@ -145,6 +146,7 @@ describe Paperclip::Storage::S3 do ...@@ -145,6 +146,7 @@ describe Paperclip::Storage::S3 do
path: ":attachment/:basename:dotextension" path: ":attachment/:basename:dotextension"
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a url based on an S3 path" do it "returns a url based on an S3 path" do
...@@ -161,6 +163,7 @@ describe Paperclip::Storage::S3 do ...@@ -161,6 +163,7 @@ describe Paperclip::Storage::S3 do
path: ":attachment/:basename:dotextension" path: ":attachment/:basename:dotextension"
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a protocol-relative URL" do it "returns a protocol-relative URL" do
...@@ -177,6 +180,7 @@ describe Paperclip::Storage::S3 do ...@@ -177,6 +180,7 @@ describe Paperclip::Storage::S3 do
path: ":attachment/:basename:dotextension" path: ":attachment/:basename:dotextension"
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a url based on an S3 path" do it "returns a url based on an S3 path" do
...@@ -193,6 +197,7 @@ describe Paperclip::Storage::S3 do ...@@ -193,6 +197,7 @@ describe Paperclip::Storage::S3 do
path: ":attachment/:basename:dotextension" path: ":attachment/:basename:dotextension"
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a url based on an S3 path" do it "returns a url based on an S3 path" do
...@@ -236,6 +241,7 @@ describe Paperclip::Storage::S3 do ...@@ -236,6 +241,7 @@ describe Paperclip::Storage::S3 do
s3_host_name: "s3-ap-northeast-1.amazonaws.com" s3_host_name: "s3-ap-northeast-1.amazonaws.com"
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a url based on an :s3_host_name path" do it "returns a url based on an :s3_host_name path" do
...@@ -259,6 +265,7 @@ describe Paperclip::Storage::S3 do ...@@ -259,6 +265,7 @@ describe Paperclip::Storage::S3 do
attr_accessor :value attr_accessor :value
end end
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "uses s3_host_name as a proc if available" do it "uses s3_host_name as a proc if available" do
...@@ -281,6 +288,7 @@ describe Paperclip::Storage::S3 do ...@@ -281,6 +288,7 @@ describe Paperclip::Storage::S3 do
File.open(fixture_file('5k.png'), 'rb') do |file| File.open(fixture_file('5k.png'), 'rb') do |file|
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = file @dummy.avatar = file
@dummy.stubs(:new_record?).returns(false)
end end
end end
...@@ -342,17 +350,18 @@ describe Paperclip::Storage::S3 do ...@@ -342,17 +350,18 @@ describe Paperclip::Storage::S3 do
context "An attachment that uses S3 for storage and has spaces in file name" do context "An attachment that uses S3 for storage and has spaces in file name" do
before do before do
rebuild_model styles: { large: ['500x500#', :jpg] }, rebuild_model(
styles: { large: ["500x500#", :jpg] },
storage: :s3, storage: :s3,
bucket: "bucket", bucket: "bucket",
s3_credentials: { s3_credentials: { "access_key_id" => "12345",
'access_key_id' => "12345", "secret_access_key" => "54321" }
'secret_access_key' => "54321" )
}
File.open(fixture_file('spaced file.png'), 'rb') do |file| File.open(fixture_file("spaced file.png"), "rb") do |file|
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = file @dummy.avatar = file
@dummy.stubs(:new_record?).returns(false)
end end
end end
...@@ -385,6 +394,7 @@ describe Paperclip::Storage::S3 do ...@@ -385,6 +394,7 @@ describe Paperclip::Storage::S3 do
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = file @dummy.avatar = file
@dummy.save @dummy.save
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a replaced version for path" do it "returns a replaced version for path" do
...@@ -405,6 +415,7 @@ describe Paperclip::Storage::S3 do ...@@ -405,6 +415,7 @@ describe Paperclip::Storage::S3 do
url: ":s3_domain_url" url: ":s3_domain_url"
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a url based on an S3 subdomain" do it "returns a url based on an S3 subdomain" do
...@@ -414,16 +425,20 @@ describe Paperclip::Storage::S3 do ...@@ -414,16 +425,20 @@ describe Paperclip::Storage::S3 do
context "" do context "" do
before do before do
rebuild_model storage: :s3, rebuild_model(
storage: :s3,
s3_credentials: { s3_credentials: {
production: { bucket: "prod_bucket" }, production: { bucket: "prod_bucket" },
development: { bucket: "dev_bucket" } development: { bucket: "dev_bucket" }
}, },
bucket: "bucket",
s3_host_alias: "something.something.com", s3_host_alias: "something.something.com",
path: ":attachment/:basename:dotextension", path: ":attachment/:basename:dotextension",
url: ":s3_alias_url" url: ":s3_alias_url"
)
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a url based on the host_alias" do it "returns a url based on the host_alias" do
...@@ -447,6 +462,7 @@ describe Paperclip::Storage::S3 do ...@@ -447,6 +462,7 @@ describe Paperclip::Storage::S3 do
end end
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a url based on the host_alias" do it "returns a url based on the host_alias" do
...@@ -469,6 +485,7 @@ describe Paperclip::Storage::S3 do ...@@ -469,6 +485,7 @@ describe Paperclip::Storage::S3 do
url: ":asset_host" url: ":asset_host"
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = stringy_file @dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end end
it "returns a relative URL for Rails to calculate assets host" do it "returns a relative URL for Rails to calculate assets host" do
...@@ -684,6 +701,7 @@ describe Paperclip::Storage::S3 do ...@@ -684,6 +701,7 @@ describe Paperclip::Storage::S3 do
@file = File.new(fixture_file('5k.png'), 'rb') @file = File.new(fixture_file('5k.png'), 'rb')
@dummy = Dummy.new @dummy = Dummy.new
@dummy.avatar = @file @dummy.avatar = @file
@dummy.stubs(:new_record?).returns(false)
end end
after { @file.close } after { @file.close }
......
...@@ -26,4 +26,8 @@ describe Paperclip::TempfileFactory do ...@@ -26,4 +26,8 @@ describe Paperclip::TempfileFactory do
file = subject.generate file = subject.generate
assert File.exist?(file.path) assert File.exist?(file.path)
end end
it "does not throw Errno::ENAMETOOLONG when it has a really long name" do
expect { subject.generate("o" * 255) }.to_not raise_error
end
end end
...@@ -481,4 +481,20 @@ describe Paperclip::Thumbnail do ...@@ -481,4 +481,20 @@ describe Paperclip::Thumbnail do
end end
end end
end end
context "with a really long file name" do
before do
tempfile = Tempfile.new("f")
tempfile_additional_chars = tempfile.path.split("/")[-1].length + 15
image_file = File.new(fixture_file("5k.png"), "rb")
@file = Tempfile.new("f" * (255 - tempfile_additional_chars))
@file.write(image_file.read)
@file.rewind
end
it "does not throw Errno::ENAMETOOLONG" do
thumb = Paperclip::Thumbnail.new(@file, geometry: "50x50", format: :gif)
expect { thumb.make }.to_not raise_error
end
end
end end
...@@ -43,7 +43,7 @@ describe Paperclip::UrlGenerator do ...@@ -43,7 +43,7 @@ describe Paperclip::UrlGenerator do
end end
it "executes the method named by the symbol as the default URL when no file is assigned" do it "executes the method named by the symbol as the default URL when no file is assigned" do
mock_model = MockModel.new mock_model = FakeModel.new
mock_attachment = MockAttachment.new(model: mock_model) mock_attachment = MockAttachment.new(model: mock_model)
mock_interpolator = MockInterpolator.new mock_interpolator = MockInterpolator.new
default_url = :to_s default_url = :to_s
......
...@@ -18,4 +18,8 @@ class FakeModel ...@@ -18,4 +18,8 @@ class FakeModel
def valid? def valid?
errors.empty? errors.empty?
end end
def new_record?
false
end
end end
...@@ -8,7 +8,16 @@ RSpec::Matchers.define :have_column do |column_name| ...@@ -8,7 +8,16 @@ RSpec::Matchers.define :have_column do |column_name|
column && column.default.to_s == @default.to_s column && column.default.to_s == @default.to_s
end end
failure_message_for_should do |columns| failure_message_method =
"expected to find '#{column_name}', default '#{@default}' in #{columns.map{|column| [column.name, column.default] }}" if RSpec::Version::STRING.to_i >= 3
:failure_message
else
:failure_message_for_should
end
send(failure_message_method) do |columns|
"expected to find '#{column_name}', " +
"default '#{@default}' " +
"in #{columns.map { |column| [column.name, column.default] }}"
end end
end end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment