Skip to content

Commit

Permalink
fix: no-dupe-keys with legal duplicated keys (#148)
Browse files Browse the repository at this point in the history
  • Loading branch information
object88 authored and gajus committed Mar 21, 2017
1 parent 66d04e8 commit 636cead
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 4 deletions.
57 changes: 55 additions & 2 deletions src/rules/noDupeKeys.js
Expand Up @@ -12,13 +12,66 @@ export default (context) => {
});
};

const analizeElement = (element) => {
const {type} = element;
let value;

switch (type) {
case 'GenericTypeAnnotation':
value = element.id.name;
break;
case 'ObjectTypeAnnotation':
// eslint-disable-next-line no-use-before-define
value = builObjectStructure(element.properties);
break;
case 'TupleTypeAnnotation':
// eslint-disable-next-line no-use-before-define
value = buildArrayStructure(element.types);
break;
default:
value = element.value;
break;
}

return {
type,
value
};
};

const buildArrayStructure = (elements) => {
return _.map(elements, (element) => {
return analizeElement(element);
});
};

const builObjectStructure = (properties) => {
return _.map(properties, (property) => {
const element = analizeElement(property.value);

return Object.assign(element, {
name: getParameterName(property, context)
});
});
};

const checkForDuplicates = (node) => {
const haystack = [];

_.forEach(node.properties, (identifierNode) => {
const needle = getParameterName(identifierNode, context);
const needle = {name: getParameterName(identifierNode, context)};

if (identifierNode.value.type === 'FunctionTypeAnnotation') {
needle.args = _.map(identifierNode.value.params, (param) => {
return analizeElement(param.typeAnnotation);
});
}

const match = _.some(haystack, (existingNeedle) => {
return _.isEqual(existingNeedle, needle);
});

if (_.includes(haystack, needle)) {
if (match) {
report(identifierNode);
} else {
haystack.push(needle);
Expand Down
91 changes: 89 additions & 2 deletions tests/rules/assertions/noDupeKeys.js
@@ -1,11 +1,59 @@
export default {
invalid: [
{
code: 'type FooType = { a: number, b: string, a: number }',
code: 'type f = { a: number, b: string, a: number }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'type f = { a: number, b: string, a: string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'type f = { get(key: "a"): string, get(key: "a"): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'type f = { get(key: 1): string, get(key: 1): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'type f = { get(key: 1.1): string, get(key: 1.1): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'type f = { get(key: true): string, get(key: true): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'type FooType = { a: number, b: string, a: string }',
code: 'type f = { get(key: {a: 1}): string, get(key: {a: 1}):string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'var a = "a"; type f = { get(key: a): string, get(key: a): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'var b = 1; type f = { get(key: b): string, get(key: b): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'var c = true; type f = { get(key: c): string, get(key: c): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'var d = {}; type f = { get(key: d): string, get(key: d): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'var e = []; type f = { get(key: e): string, get(key: e): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'var e = [1, "a"]; type f = { get(key: e): string, get(key: e): string }',
errors: [{message: 'Duplicate property.'}]
},
{
code: 'function fn() {}; type f = { get(key: fn): string, get(key: fn): string }',
errors: [{message: 'Duplicate property.'}]
}
],
Expand All @@ -20,6 +68,45 @@ export default {
onlyFilesWithFlowAnnotation: true
}
}
},
{
code: 'type f = { get(key: "a"): string, get(key: "b"): string }'
},
{
code: 'type f = { get(key: 1): string, get(key: 2): string }'
},
{
code: 'type f = { get(key: 1.1): string, get(key: 1.2): string }'
},
{
code: 'type f = { get(key: true): string, get(key: false): string }'
},
{
code: 'type f = { get(key: ["a", 1]): string, get(key: ["a", 2]): string }'
},
{
code: 'type f = { get(key: ["a", ["b", 1]]): string, get(key: ["a", ["b", 2]]): string }'
},
{
code: 'type f = { a: number, b: string, c: number }'
},
{
code: 'type f = { get(key: "a"): string, get(key: "b"): string }'
},
{
code: 'type f = { get(key: "a"): string, get(key: "a", key2: "b"): string }'
},
{
code: 'type f = { get(key: "a"): string, get(key: 1): string }'
},
{
code: 'type f = { get(key: { a: 1 }): string, get(key: { a: 2 }): string}'
},
{
code: 'var a = {}; var b = {}; type f = { get(key: a): string, get(key: b): string }'
},
{
code: 'var a = 1; var b = 1; type f = { get(key: a): string, get(key: b): string }'
}
]
};

0 comments on commit 636cead

Please sign in to comment.