diff --git a/data/Table With Data.csv b/data/Table With Data.csv
new file mode 100644
index 00000000..6d09540e
--- /dev/null
+++ b/data/Table With Data.csv
@@ -0,0 +1,3 @@
+id,name
+1,english
+2,中国人
diff --git a/frictionless/helpers.py b/frictionless/helpers.py
index 97445639..67885215 100644
--- a/frictionless/helpers.py
+++ b/frictionless/helpers.py
@@ -9,6 +9,7 @@ import chardet
 import tempfile
 import datetime
 import stringcase
+from slugify import slugify
 from inspect import signature
 from importlib import import_module
 from urllib.parse import urlparse, parse_qs
@@ -136,13 +137,14 @@ def compile_regex(items):
         return result
 
 
-# TODO: use slugify
 def detect_name(source):
+    name = "memory"
     if isinstance(source, str) and "\n" not in source:
-        return os.path.splitext(os.path.basename(source))[0]
-    if isinstance(source, list) and source and isinstance(source[0], str):
-        return os.path.splitext(os.path.basename(source[0]))[0]
-    return "memory"
+        name = os.path.splitext(os.path.basename(source))[0]
+    elif isinstance(source, list) and source and isinstance(source[0], str):
+        name = os.path.splitext(os.path.basename(source[0]))[0]
+    name = slugify(name).lower()
+    return name
 
 
 def detect_basepath(descriptor):

diff --git a/tests/test_resource.py b/tests/test_resource.py
index d85951fa..6cbed497 100644
--- a/tests/test_resource.py
+++ b/tests/test_resource.py
@@ -606,6 +606,13 @@ def test_resource_infer_from_path():
     assert resource.path == "data/table.csv"
 
 
+def test_resource_infer_not_slugified_name_issue_531():
+    resource = Resource()
+    resource.infer("data/Table With Data.csv")
+    assert resource.metadata_valid
+    assert resource.name == "table-with-data"
+
+
 # Import/Export
 
 

Resource names coming from 'infer' should not retain uppercase characters
# Overview

In working on a dataset where some of the filenames contain uppercase characters, I see that those characters are retained in the resource names when one processes them with `infer`. 

For example, `RAW_input_stream_1.csv` will be given a resource name of `RAW_input_stream_1`. This violates the JSONschema, which allows only lowercase letters: `^([-a-z0-9._/])+$`

---

Please preserve this line to notify @roll (lead of this repository)

tests/test_resource.py::test_resource_infer_not_slugified_name_issue_531
tests/test_resource.py::test_resource tests/test_resource.py::test_resource_from_dict tests/test_resource.py::test_resource_from_path tests/test_resource.py::test_resource_from_path_error_bad_path tests/test_resource.py::test_resource_from_zip tests/test_resource.py::test_resource_source_non_tabular tests/test_resource.py::test_resource_source_non_tabular_error_bad_path tests/test_resource.py::test_resource_source_path tests/test_resource.py::test_resource_source_path_and_basepath tests/test_resource.py::test_resource_source_path_error_bad_path tests/test_resource.py::test_resource_source_path_error_bad_path_not_safe_absolute tests/test_resource.py::test_resource_source_path_error_bad_path_not_safe_traversing tests/test_resource.py::test_resource_source_data tests/test_resource.py::test_resource_source_path_and_data tests/test_resource.py::test_resource_source_no_path_and_no_data tests/test_resource.py::test_resource_dialect tests/test_resource.py::test_resource_dialect_header_false tests/test_resource.py::test_resource_dialect_from_path tests/test_resource.py::test_resource_dialect_from_path_error_path_not_safe tests/test_resource.py::test_resource_respect_query_set_after_creation_issue_503 tests/test_resource.py::test_resource_schema tests/test_resource.py::test_resource_schema_source_data tests/test_resource.py::test_resource_schema_from_path tests/test_resource.py::test_resource_schema_from_path_with_basepath tests/test_resource.py::test_resource_schema_from_path_error_bad_path tests/test_resource.py::test_resource_schema_from_path_error_path_not_safe tests/test_resource.py::test_resource_expand tests/test_resource.py::test_resource_expand_with_dialect tests/test_resource.py::test_resource_expand_with_schema tests/test_resource.py::test_resource_write tests/test_resource.py::test_resource_infer tests/test_resource.py::test_resource_infer_source_non_tabular tests/test_resource.py::test_resource_infer_from_path tests/test_resource.py::test_resource_to_copy tests/test_resource.py::test_resource_to_json tests/test_resource.py::test_resource_to_yaml tests/test_resource.py::test_resource_to_zip tests/test_resource.py::test_resource_to_zip_source_inline tests/test_resource.py::test_resource_to_table tests/test_resource.py::test_resource_to_table_source_data tests/test_resource.py::test_resource_to_table_source_non_tabular tests/test_resource.py::test_resource_to_table_respect_query_issue_503 tests/test_resource.py::test_resource_source_multipart tests/test_resource.py::test_resource_source_multipart_error_bad_path tests/test_resource.py::test_resource_source_multipart_error_bad_path_not_safe_absolute tests/test_resource.py::test_resource_source_multipart_error_bad_path_not_safe_traversing tests/test_resource.py::test_resource_source_multipart_infer tests/test_resource.py::test_resource_integrity_onerror tests/test_resource.py::test_resource_integrity_onerror_header_warn tests/test_resource.py::test_resource_integrity_onerror_header_raise tests/test_resource.py::test_resource_integrity_onerror_row_warn tests/test_resource.py::test_resource_integrity_onerror_row_raise tests/test_resource.py::test_resource_integrity_foreign_keys tests/test_resource.py::test_resource_integrity_foreign_keys_invalid tests/test_resource.py::test_resource_integrity_read_lookup tests/test_resource.py::test_resource_relative_parent_path_with_trusted_option_issue_171 tests/test_resource.py::test_resource_preserve_format_from_descriptor_on_infer_issue_188